読者です 読者をやめる 読者になる 読者になる

cockscomblog?

cockscomb on hatena blog

年末年始に飲み過ぎないために

Swift Development

諸君は酒が好きだろうか。筆者の場合は少しくらい、好きである。酒を飲んでもいいことなどない。僅かに楽しいような気分になるばかりで、だんだんと頭がボーッとしてきて身体もダルくなり、ひどいときには周囲の人間にまで迷惑をかける。しかし、よく冷えたビールの一口目の、あのなんとも言い難い美味さよ。あのたった一口分の美味さが脳神経に刻みつけられ、繰り返しくりかえし酒を飲んでしまう。なんと愚かなことだろう。

さて本稿では、種々の問題をはらむ飲酒について、特に二つの問題を取り上げ実践的なアドバイスを諸君らに授けたい。筆者のアドバイスは主に Swift によって記述される。

ビール1パイント問題

アイリッシュパブなどに行ってビールを頼むと、「中ジョッキ」のような曖昧な単位でなく、「パイント」という単位で量を指定しなければならない。諸君らも安易に1パイントで頼んでしまって思ったより多くて苦労する、といった経験をしたことがあるかもしれない。

パイントはヤード・ポンド法における体積の単位であり、イギリスでは1パイントがおよそ0.568リットルに相当する。アメリカでは0.473リットルであるが、ビールにおいてはイギリス式のパイントが用いられる。

Swift と Foundation.framework でこれを示すと、以下のようになる。

let onePint = Measurement(value: 1, unit: UnitVolume.imperialPints) // 1.0 pt
onePint.converted(to: .liters) // 0.568261 L

Measurement は Foundation に iOS 10 の世代から追加された、Double 型の値と Unit 型の単位を持った、単位付きの値を表す struct である。体積の単位を表す UnitVolume は抽象クラスである Dimension のサブクラスで、また DimensionUnit のサブクラスである。Unit は単に単位を表し、Dimension はそれに加えて単位変換を行うために baseUnit()UnitConverter が関連づけられている。

これらの仕組みにより、converted(to:) メソッドで単位変換を行うことができる。英国法定標準のパイントである UnitVolume.imperialPints から SI 併用単位の UnitVolume.liters へ変換できる。(ところで litre じゃなく liter なのはアメリカっぽいと思います。)

let halfPint = Measurement(value: 0.5, unit: UnitVolume.imperialPints) // 0.5 pt
halfPint.converted(to: .liters) // 0.2841305 L

(halfPint * 3).converted(to: .liters) // 0.8523915 L

Swift の Foundation インターフェースでは演算子が定義されているので、ハーフパイントのビールを3杯くらい飲めばおおよそいい感じになる、ということがわかる。

結論:ハーフパイントくらいでいい

さらに Measurement では、MeasurementFormatter を使って読みやすい文字列を得られる。

let onePint = Measurement(value: 1, unit: UnitVolume.imperialPints) // 1.0 pt

let formatter = MeasurementFormatter()
formatter.locale = Locale(identifier: "ja-JP")
formatter.unitStyle = .long

formatter.string(from: onePint) // "0.568リットル"

日本酒1合問題

日本酒のラインナップが充実した居酒屋でお気に入りの銘柄を1合注文したとき、後に続くおちょこ追加、おちょこ人数分によって、僅かに舐めるばかりの量しか残らない。諸君らも、このような事例で涙したことは一度や二度では済まないだろう。

1合がいかほどの量か、ビールのように調べてみたいが、生憎 Foundation の UnitVolume には「合」という単位は存在していない。しかし幸いなことに、自分で単位を追加することができる。

extension UnitVolume {
    static var: UnitVolume {
        return UnitVolume(symbol: "合", converter: UnitConverterLinear(coefficient: 0.18039))
    }
}

このように UnitConverterLinear を利用して新しい UnitVolume を作ることができる。UnitConverterLinearUnitConverter 抽象クラスのサブクラスであり、coefficient と constant によって単純な線形の変換を行うことができる。UnitVolumebaseUnit().liters であるから、尺貫法における1合が約0.18039リットルであることにより、このように書けるのである。

let oneGo = Measurement(value: 1, unit: UnitVolume.合) // 1.0 合
oneGo.converted(to: .liters) // 0.18039 L

これによって Measurement において合という単位が利用できるようになり、人数に応じて適切な量について考えられるようになった。

UnitConverter は他にも実装することができ、例えば逆数への変換などが存在し得るだろう。

結論:みんなで飲むなら多めにたのむ

総括

本論により、Foundation の Measurement 関連 API の利用方法を示した。その中で我々は、以下の結論を得た。

  • ハーフパイントくらいでいい
  • みんなで飲むなら多めにたのむ
  • 飲み過ぎないように気をつける

それでは皆さんよいお年を。


本稿の内容は関西モバイルアプリ研究会 #21において行われた筆者の研究発表から、その内容を再録したものである。

これは飲酒を勧めるものではなく、京都市清酒の普及の促進に関する条例とも関係しない。筆者の居住地である日本国では、未成年者飲酒禁止法により満20歳未満の者の飲酒は禁止されている。また酒気帯び及び酒酔い運転は犯罪である。飲酒は健康な成年に限って、自己の自由意志によってのみ行われるべきであり、何人も飲み過ぎてはいけない。