2020年に飲んだ日本酒
2020年は引っ越しをしたために周辺環境が変わった。
生活圏内に色々な酒を扱っている店舗(主にワインと日本酒)があったため、様々な種類の日本酒を飲むことが出来た。
2020年に出会った日本酒について、感想などを忘れぬよう雑記を残すことにする。
花浴陽 純米大吟醸無濾過原酒山 山田錦
2020年に飲んだ酒ではダントツに美味しい。
香り良し、口に含んだときの味がほぼジュース、喉越しで日本酒らしさが顔を出す。
何でも埼玉県で一番美味しい酒なんだとか…
通販サイトなどを見るとプレミアム価格がつくことがあるようだが、運良く定価で購入することが出来た。
おそらくもう一度飲む機会はないのではないだろうかと思う。
頻繁に手に入ってしまうとあまりにも美味しいので、酒浸りになりそうだし入手難度は高くて丁度良いのかもしれない。
大雪渓 純米吟醸
無性にわさびが食べたくなり、わさびのお供に購入した。
口に含んだときの味が安酒か?と警戒させるのだがそれは大きな間違いであることが分かる。
口に含んだ後口の中で転がしても、喉越しの時も特別な主張を一切しない不思議な味であり安酒のような不快感は一切ない。
この主張のなさからスイスイ飲むことが出来る面白い酒だった。
肝心のわさびとの相性は正直良くわからないが、また飲んでみたいと思える一品だ。
冬まで待てない冬の月
ラベルのうさぎとお酒の名前が面白く購入した一品。
白桃酵母を利用しているらしく、味に桃の皮特有の苦味があるように感じた。
家族にはこの苦味が苦手で敬遠されてしまったが、個人的には幼少時から桃を食べ慣れていた影響もあるのかこの苦味に好感を持つことが出来た。
冬の月
上記で書いた「冬まで待てない冬の月」が気に入ったため、予約購入した一品。
非常に美味しかった記憶があるものの購入時期、仕事が多忙だったこともありじっくり飲むことが出来なかった。
2021年も再度購入したい。
飛良泉 純米大吟醸 限定生酒
どうも限定という言葉に弱く、瓶に限定などと書いてあろうものならその商品を手にとってしまう。
この飛良泉という酒も購入はそのような動機だ。
香りがよく、飲み口はスッと入る。
口の中で転がすと日本酒らしさが顔を出し始め、喉を越すころにはしっかりとした日本酒らしさで通り過ぎる。
難しく書くと良さが伝わらないだろうから簡単に書くが、美味しい酒だった。
Sasanami 春
花見がしたく、ラベルのオシャレさも手伝い購入した一品。
味は忘れましたが「爽やかだなー」という感想をもった記憶がある。
素敵 Japan
購入難度が低く、それでいて圧倒的に美味しい!2020年で何度もリピート購入した。
ぶどうを思わせる香り、ワインのような飲み口、強すぎない日本酒さ、とにかく飲みやすく、飲みやすいだけでなく味もしっかり美味しいお酒。
開栓からしばらく時間をおくとフルーツのような味わい・香りは姿を消すが、今度は味が丸くなるというのだろうか?そう表現する他ないのだが、そのような味に姿を変え、これがまた飲みやすい。
トータルのバランスで考えるとこの酒は2020年に出会った酒の中でもNo1だろう。
SwiftPackageManagerを使うための覚書
以前SwiftPackageManagerを利用してライブラリを作成したことがあったが、使い方をすっかり忘れてしまったため覚書として使い方のメモを残しておくことにする。
プロジェクトディレクトリの作成
SwiftPackageMamagerにはプロジェクトディレクトリを作成してくれる機能は無いため自前でプロジェクトディレクトリを作成しておく必要がある。
ディレクトリを作成したら、そのディレクトリに移動してSwiftPackageManagerの初期化を行っていくことになる。
mkdir /path/to/Project cd /path/to/Project
初期化
swift package init --type [empty|library|executable|system-module]
というコマンドを実行することでプロジェクトのスケルトンを生成することができる。
--type
に指定したオプションによって生成されるスケルトンが異なってくる。
生成内容はそれぞれ下記の通り。
オプション | 生成物 |
---|---|
empty | 空のプロジェクトスケルトンが生成される、用途的に使うことはほぼ無いのではないか? |
library | 他のSwiftプロジェクトから利用可能なライブラリを生成するためのスケルトンが生成される。 |
executable | 実行可能なコマンドのためのスケルトンが生成される。 |
system-module | システムモジュールを生成するためのスケルトンが生成される。 |
SwiftPackageManagerでビルドを行うには特定のプロジェクト内構造を持つ必要がある。
この構造を自分で考えるコストが必要になるempty
オプションは基本的に利用するケースが無いように思われる。
Xcodeプロジェクトの生成
swift package init
でプロジェクトの初期化を行うと開発が行えるようになる。
通常、Swiftの開発にはXcodeを利用するため*1Xcodeのプロジェクトファイルを生成する必要がある。
Xcodeプロジェクトの生成は下記のコマンドを実行すれば良い。
swift package generate-xcodeproj
コマンドを実行すると、[ProjectDirName].xcodeproj
という設定が生成されるので、これをXcodeから開けばXcodeを利用して開発を行うことができる。
以前使ったときはテストコマンドやビルドコマンドもあったような記憶があるのだが、どうも無くなってしまっているようだ*2
ブログに書いたことで次に利用する時はすんなり使えるようになっているとよい。
オクトパストラベラー感想
ちょっと前に話題になっていたオクトパストラベラーというゲームをクリアした。
以下感想です。
シナリオ
- 各キャラクター4章構成だが、4章の間にキャラクターの心情が変化していく様を描くのには無理があるキャラクターがちらほら(特にテリオン)
- ゲーム上仕方がないのかもしれないがただの商人の娘であるトレサが強い謎
- サイラス編がキャラクターの天然ぶりと相反してシナリオが怖い(4章を夜に暗い部屋でやると特に怖い)
- ハンイット編はシナリオ的にはわりとよく出来ている、隠しボスへの布石みたいなものもあって気が付く人にとってはいいシナリオだと思う
戦闘
- ブースト、ステータスアップ・ダウンを駆使して戦うことを覚えるとボス戦が楽になる
- 上記を除くとごくごく普通のRPGな戦闘スタイル
フィールド
- グラフィックが綺麗なのだが画面の輝度や周囲の明るさによってフィールドが見にくくなることがあった
- ダンジョンの作りが単調なので、RPGとは入り組んだダンジョン!という人には物足りないかも(私は難しく考える必要がなかったので特に気にならなかった)
- 宝箱に入っているものが多くの場合重要ではないので後半は宝箱を見つけてもスルーするようになっていた
フィールドコマンド
- 盗むや買い取るはゲームが難しい人用の救済手段みたいなもののように感じた
- 巷で噂されるほど感心はしなかったものの、新しい街に移動したあと盗むコマンドでレア装備を見つけるのが一つの楽しみになったのは間違いない
- プリムロゼの誘惑で男性NPCキャラが「げへへ」という言葉を発するあたりに人間の業を感じずにはいられない
隠しボス
- 最後の最後で8人全員必要とか辞めて!
感想はこんなところ。
正統派RPGを名乗るには*1ダンジョンの構造が少し残念だったように思うが、それを除けばなかなか良い出来のRPGだと思う。
気がついたら総プレイ時間が70時間程度になっていたので私としては楽しめたゲームだった。
*1:ソースは?
読書感想 - 異文化理解力
異文化理解力という本を読んだ。
グローバルな人を相手にして働くビジネスパーソンが各国の文化的背景等から生まれるコミュニケーションの差異を明らかにし、どのように対処していくかという内容の本だ。
なお、「日本人の性質とプログラマー文化」と題しているがこのエントリはただの読書感想文であり、壮大な考察が述べられるものではない。
さて、ITエンジニアとして仕事をしていると他の職種と比べてITエンジニア特有の文化のようなものが形成されていおり、また、この文化が日本人の性質とされているものから外れている節があるように感じる。
例えば、無駄なミーティングを好まないだとか、情報をオープンにするだとか、ひどいコードを目の前にしたときに「なんだ、このクソコードは!」など堂々と暴言を吐く、などなど…
これらは仕事を効率よく進めることい対して非常に有用だが日本人の性質と照らし合わせると、ズレが生じておりITエンジニアの精神的な観点をすり減らしてしまうという問題はなかろうか?
特に、ITエンジニアはプログラムのソースコードを指して暴言を吐きがちだが、このオープンなフィードバックは明らかにITエンジニア諸氏の精神をすり減らしている場面をよくよく目にする。
これは一例に過ぎないが、私達はもう少し、ITエンジニアとしてではなく、日本人という文化に所属する人間を相手にして仕事をしているということに意識を向けたほうが良いのかもしれないと考えさせられた。
実はITエンジニアに留まらずIT企業というのが特殊な文化を構築しており、このあたりがまた従業員のモチベーションに関するミスマッチを起こしているというケースも目にすることがある。
エンジニアリングにせよ、IT企業にせよまだまだ若い産業であるので、これまでの文化とは異なる形態をとるのはおかしな話ではないが、その文化の所属する前に私達の考え方は自分の国の文化的背景がベースとして存在している。
これらを上手く迎合できるような振る舞いというのを考えていければと思った。
退職しました
これはITエンジニアの界隈で非常に流行している退職エントリというものだ。
ITエンジニアの界隈では人材の流動性が高いらしく*1、また、自身の情報を発信することが人材的価値の向上に繋がるケースモデルが一定数観測されることから、このような退職エントリが上がることは珍しいことではない。
私はITエンジニアとして業界に身をおいているのだが、この流行というものに倣って退職エントリというものを書いてみるに至った次第だ。*2
さて、先日8月末日をもって約3年と半年ほど所属した会社を退職した。
会社への不満、未来への成長の展望、これまでの感謝等、感情としては諸々が混じり合っているためどれがどうっだったという明確な理由を上げてもそれは違うことのように思われる。
故に、退職理由は簡単に書き記せるような明確なものではなく、様々な要素が重なった中である日「退職しよう」という判断が自分の中で下されたのだ。
いざ書いてみたが書きたいことが殆どないことに若干の寂しさを憶える。
なお、次に所属する会社はすでに決まっているためこのエントリに転職活動を示唆するものは含まれていない。
Swiftで利用できるLooseCodableというライブラリを作った
LooseCodableというライブラリを作った。
CarthageとSwiftPackageManagerからインストールして利用することができる。
このライブラリを作ろうと思った動機だが、サーバーサイドのAPIレスポンスが安定していないというのが理由だ。
主にIntegerとString、IntegerとBooleanの型が様々な形式で返ってくるのだが、SwiftのCodable
*1はこれらの型を曖昧に変換することを許さず例外を投げてくる。
例えば、Booleanで扱いたいケースで0
か1
で返ってくるケースとtrue
かfalse
で返ってくるケースが混在しているだとか、10
で返ってくるか"10"
で返ってくるかが混在しているかなど…
Codable
登場以前は自前で書いたマッパーがこのあたりの差異をいい感じに吸収してくれていたのだが、Codable
へ移行したと同時にこのような問題が顕在化してしまった。
Codable
を利用すること自体は間違いのない選択だと考えているが、この気まぐれなAPIとは相性が悪い。
そこで、この気まぐれAPIを快く受け入れるべくLooseCodableを作ったというわけだ。
さて、このライブラリだが期待する型をLooseCodable
という型で包んであげることでいい感じに差異を吸収してくれるものだ。
struct Hito: Codable { // このように定義しておくと let age: LooseCodable<Int> } // こんなデータが let json = """ { "age": "10" } """ // デコードできちゃいます! let hito = try! JSONDecoder().decode(Hito.self, from: json.data(using: .utf8)!) print(hito.age.value) // 10
上記のコードだとLooseCodable
という型が表面に出てしまい、結果の値を得るためにvalue
というプロパティを呼ぶのは、呼び出し側に多くの変更の負担が寄る可能性がありいただけない。
そもそもLooseCodable
はCodableオブジェクトの外に見えている必要は無い。
このため定義するとき、LooseCodable
を指定する型はプライベートにしておき、公開するプロパティをComputedにしたほうが良いだろう。
struct Hito { // LooseCodableなプロパティは非公開にし、 private let _age: LooseCodable<Int> // 利用される値をComputedな公開プロパティにする var age: Int { return self._age.value } // JSONとプロパティのキーマッピングを忘れずに enum CodingKeys: String, CodingKey { case _age = "age" } }
今回、初めてSwiftPackageManagerを利用してライブラリを公開してみたが、何もしなくてもCarthageでのインストールにも対応できていて中々に便利な代物だなと思えた。
ファイル構造を強制するなどとっつき憎い点もあったが、今後のSwiftにおけるライブラリ開発はSwiftPackageManagerで作成することを念頭に置いておきたいところだ。
公式Perlチュートリアル
先日のブログに書いたとおりPerl公式のチュートリアルを学んでいる。
最近WEBフロントエンドのライブラリのチュートリアルをこなすことが多いだが、 これらのチュートリアルは懇切丁寧に記されておりPerlのチュートリアルに対しても同じようなものを想定していた。
しかし、内容は最低限Perlの基礎とかコンピュータ・サイエンスの基礎などの知識が必要とされる内容だった。
先にPerlの基礎を学んでいたおかげで特に問題無く読み進めらることができたが、
このチュートリアルは私のチュートリアルに対する概念は大きく崩すことになる内容だ。
さて、このチュートリアルだがちょっとしたジョークを交えた文章で書かれており読んでいると以外に楽しめる内容になっている。 内容もPerlの細かな挙動について触れられており、こういったところに新たな発見・気付きを得られるのは学ぶ上での喜びだろう。
ここから下はチュートリアルで学んだことの覚書を記していく*1
変数の定義
変数の先頭にプレフィクスをつけることで、データのタイプを分類出来る
# スカラーは`$` $shin_gi = true; $number = 42; $string = "moji moji"; # 配列は`@` @array = ( 1, 2, 3, 4, 5 ); # ハッシュは`%` %hash = ( "ha" => "shun!!" ); %hash = ( "ali", "as" ); # こう書いてもいいが、分かり難いので多分書かない
尚、配列やハッシュに格納出来るのはスカラー値だけなのでネストするデータ構造などが扱えない。
これを解決するために参照というスカラー値を作って格納するらしい。
# 参照を作るには、配列やハッシュの先頭に`\`をつける $aref = \@array; $href = \%hash; # 無名配列・無名ハッシュへの参照を持てる # オリジンを壊されないという意味でこっちのほうが使いやすそうだが… # (メモリ使用量などが問題になるか?) $aref = [ 1, 2, 3, 4, 5 ]; $href = { "no" => "name" }; # 参照へアクセスしたいときは`{}`でくくることでアクセスできるようになる @{$aref} # => @array ${$aref}[0] # => $array[0] %{$href} # => %hash ${$href}{"no"} # => $hash{"no"} # 参照先の要素アクセスにはエイリアスが存在する(こちらを使ったほうが読みやすくて良い) $aref->[0] # ${$aref}[0] $href->{"no"} # ${$href}{"no"}
正規表現
Perlは文字列操作が凄いというだけあってかなりボリュームが高い内容となっていた。
なので基本的な部分にのみ目を通して読み飛ばした。
以下は基本的な部分の覚書である。
# `=~`演算子でマッチの真偽をチェックできる if ($value =~ /kihonn/) { print "matched!"; } # `!~`演算子でアンマッチの真偽をチェックできる if ($value !~ /unmatch/) { print "unmatched..."; } # 正規表現のデリミタは`m`オプションを指定することで変更ができる "Henkou dekiru!" =~ m{dekiru!}; # グループ化して取り出す if ("grouping!!" =~ /(ping).*(!!)$/) { print $1; # "ping" print $2; # "!!" } # マッチした値はリストで返るのでこういうふうに書ける ($ping, $bikkuri) = ("grouping!!" =~ /(ping).*(!!)$/);
スレッド
Perlではスレッドを利用することができるらしい。
Perlのスレッドはスレッドセーフらしいので、スレッドを生成した時点でデータがスレッド内にコピーされる。
(配列やハッシュの参照を渡してみたところ、参照すらも(参照先にある実態も)コピーされました)
※スレッドセーフなのは、スレッド生成時にすべてのデータをコピーするから。
データ以外(chdir
などでプロセスレベルで影響を与えるもの)はすべてのスレッドに影響を及ぼしてしまう。
use threads; # サブルーチンの参照を渡すと、その処理をスレッド内で行ってくれる。 my $thread = threads->create(sub { print "Hello world!!"; }) # `join`メソッドを呼び出すと、スレッドの完了を待機、戻り値がある場合は取得、スレッドの後始末を行ってくれる。 # スレッドの後始末をしないコードはエラーになる。 $thread->join(); # `detach`メソッドはスレッドの後始末を行うだけ。 # スレッドが実行中であっても処理結果が出力される前に`detach`を呼び出せばその結果を得ることは出来ない。 $thread->detach();
上記はスレッドの基本的な利用方法でデータのシェア、キューの存在やセマフォ等も存在しますが、
これらが必要になるケースは稀だろうということで軽く読み進めるだけに留めておいた。*2
オブジェクト
パールのクラスはパッケージ。
package Human;
use Human; # パッケージ名からメソッドを呼び出せる Human->Something;
オブジェクトのコンストラクタは、bless
を内部で呼び出すサブルーチン。
コンストラクタの名前は何でもよい。
※bless
は参照をオブジェクトとみなすために利用するらしい(よくわかっていない)
# 内部でblessを呼び出せばそれがコンストラクタ sub new { bless {} } # newでなくても良い sub init { bless {} }
オブジェクトの継承には@ISA
構文を利用する。
暗黙的にすべてのオブジェクトはUNIVERSAL
クラスを継承する。
オブジェクトからメソッドを呼び出すとき、オブジェクトにメソッドがなければ、@ISA
で定義したオブジェクトの左からメソッドを探していき、
どこにも無い場合にAUTOLOAD
メソッドを呼び出す。
{ package Animal; sub cry {} } { package Dog; # Animalを継承 @Dog::ISA = qw(Animal); } # Dogパッケージにはcryメソッドが無いが、Animalを継承しているので呼び出せる。 Dog->cry;
オブジェクトに関する内容がかなり濃密なので、詳細はまた別途学習することにする。