ポクポク

ポクッとしてツナッ

GW9日目

弾づまりした電動ガンのマガジンを直そうとバラしたらスプリングを押さえておく板がスプリングの勢いで吹っ飛んでいって修理不能になった。パーツを見つけるため部屋を片付け掃除機をかけたけど見つからない。掃除機をかけて偉い。

鶏肉が食べたかったので鶏肉を買ってきて皮をバリッとさせて食べた。

Untitled

すぐさま皿洗いを行うものの、排水口への水の流れが悪い。皿を洗ってるとどんどんシンクに水が溜まってプールみたいになる。なぜなら草が生えるぐらいゴミ受けが埋まっているからです。

観念してゴミ受けを空にする。数ヶ月ためたゴミ受けは汚濁にまみれた地獄であり名状しがたい悪臭を発するかと思いきや、湿った土の匂いがするだけだった。雨の森を歩いてるようなさわやかさ。土ってこうやってできるんだ!! って感動した。見た目は完全にゴミゲロドブ汚物だけど、匂いは生まれたての土だった。根が張っていたせいか網とゴミ受けを剥がすのに難儀した。

明日から仕事なので4時ぐらいまでゲームして寝ました。

GW5~8日目

5~6日目(5/2-3)

平日なので仕事をしていました。

昼は外にパンを買いに行ったところ、ほとんど売り切れていて棚の 1/3 もパンが無かったのでラーメン屋にフォールバックした。夜は何してたんだっけ、もう記憶がない。晩御飯を食べた後に会社でぐだぐだとしていたら日が変わっていた。

Untitled

最近毎日のように唐辛子を揚げたおかしを食べてる。朝食の代わりになったりする。

組織体制、ソフトウェアエンジニアリングについての活発な意見交換を行っていると朝になっていた。諦めてパン屋が開くまで粘ろう(だいたい7時です)としていたけど、もう帰りましょうもう帰りましょう、って言われるので会社を出た。パン屋の前で10分ほど開くのを待ってパンを買って帰る。朝7時のさわやかさと共に家まで戻ると猫が居たので交流した。

Untitled

こういう日を棒に振るかどうかは気絶せず風呂に入れるかどうかに懸かっているので風呂に入ってコーヒーを入れて寝た。棒には振った。

7日目(5/4)

1日かけてプライムビデオで無料になっていたので Band of Brothers を見ていた。寝て見て曖昧になって見て寝て見るという具合で1日が進行した。

バンド・オブ・ブラザース (字幕版) | 動画 | Amazonビデオ

昼食を作ろうにも台所が最悪の状態だったので掃除をした。3週間ぐらい洗い物を放置していて汚水で満ちており排水口から草が生えている状態を綺麗にした。GW で一番めざましい成果です。これが新しい家族の草。来週捨てたい。

Untitled

余っていた冷凍餃子と、しーほんしーちゃおじーだんを作って食べた。日本人がみんな好きな割に目立たない簡単に作れる中華料理!! という位置づけらしいけど、まあふつうかな...と思った。もっと中華らしい中華を食べたい。単に作りが悪い可能性もある。米はない。ぽん酢も無かった!! ぽん酢を買うのを忘れ続けており、かれこれ半年ぐらいぽん酢なしで餃子を食べ続けている(4かいぐらいです)。酢とこしょうで食べたり、バルサミコ酢といったバリエーションでごまかしてる。この日はふつうに醤油と酢とラー油で食べました。

Untitled

片付けないとまた3週間汚水と暮らす羽目になるのでその場で洗った。偉い。おやつは土佐文旦を剥いて食べた。実が頑丈なのとチマチマ剥く作業のダブルの楽しさがある。姉がいたら剥いてあげる予定です。

8日目(5/5)

来週何もできない懸念が拭えないので仕事をしました。

一人だと真の裁量があって 14:00 (昼休みの終わる時刻)まで働いてから飯を食いに行っても何の問題もない。しかしランチのラストオーダーが終わってしまうという問題がある。店が空いていないので下駄のままフラフラ外を歩いたせいで下駄がだいぶ削れた。自席の下が木屑だらけになってしまった。

僕は下駄を愛好していて会社でも家でもスリッパ代わりに下駄をはいて暮らしてる。会社では高級下駄を使っていて年2回職人が京都に売りにくる。今年ももうすぐやってくる。

第14回 黒澤桐材店×おはりばこ《下駄ばこ》 | 京都 おはりばこ

今年も職人の兄ちゃんに下駄を見せて、できれば鼻緒を交換したいけど、女性向け高級おしゃれ和雑貨ショップの離れが会場なので、身なりの整っていない独身男性が行くにはかなりキツい。今から憂鬱である。最初に行った時どなたの紹介ですか? と女性店員に言われて窮した記憶が蘇る。

21時頃これを書いていて、夕食何にしようか考えてる。社会には、ちょっとだけ何か食べたいみたいな時に行くいい感じの場所がない。夜もパン屋に行きたい。このままだとココイチマクドに行くと思う。酒飲まなくてよくて1人で入りやすい焼き鳥屋とかが欲しい。酒飲まないのは、夜にゲームやる時に判断力や反射神経が落ちるからで、飲みたい時は飲みます。

GW4日目

平日なので仕事をしていました。

昼休みは factory_girl が factory_bot になった issue を読んでいた。

一方 Python では factory_boy が活躍している。

夕食はマックデリバリーを食べました(図1)。マックデリバリーで注文できるアスペクト比の変なポテト(図2)が消えていて、グランドフライというのに変わっていた。グランドフライはMサイズの1.7倍らしいけど、Lより大きいのか小さいのかはっきりして欲しい。価格的には大きいだろう、シェアポテトよりは小さいだろう、Mサイズの1.7倍未満の価格だろう、といった曖昧な状態で注文している。

図1. マックデリバリーを食べる人間達

図2. アスペクト比の変なポテト

http://www.mcdonalds.co.jp/quality/basic_information/flashimages/megapotato_l.png

GW3日目

なぜか出社して働いていた。

昼休みは最近会社の近くに出来たカレー屋に行った。 カレーライスはもはや日本料理という向きもあるけど僕は納得していない。なぜかというと、カレーライスを先鋭化させるにつれすぐスパイスを強調した方向性になり、先祖帰りしてインド亜大陸の形質を取り戻していくからだ。スパイスカレーは好きだけど日本食の文脈で語るのは難しい、本家を無視して構造を語りづらすぎる。一方ラーメンは先鋭化していくと無化調や鮎の煮干、タオルを巻いて腕を組むといった方向になるので中華料理の文脈から離れていく。ラーメンは日本食で良いと思う。カレーライスは日本の食卓の風景であると思うけどもまだ日本食とは思えない。カレールーを使ったカレーや、オシャレ盛り付けといったレイアウト面では日本っぽい文脈だと思う、といったことを考えながら昼食を食べた。

夕方、GW に行き場のない独身男性が続々と出社してきた。GW らしく夜は焼肉に行った。メニューに載っている肉の品切れが多すぎて計画が立てられない。19:30 頃にツラミもハラミも売り切れていて、ここはいつもこういう状態である。これは部下が出社するかしないか分からないディレクターの気持ちを追体験させる仕組みといえる。コスパの良い店のはずだけど調子乗ってべらぼうに食べたので1人8000円に達した。

GW1~2日目

いかに無為なゴールデンウイークを過ごしているか記録していく

1日目

会社でダラダラと仕事したりゲームブログに Webfont 入れたりしてたら日が変わってGW突入してしまった。

飲み会から帰ってきた人間たちが賢者の止まり木(そう呼ぶ場所があります)で二次会を始めたのを眺めてから畳で気絶した。途中起きてきららファンタジアとシャニマスで遊んだ記憶はある。ちゃんと起きたのは9時ごろである。

もうちょっと作業して昼前に飯食べて帰ろうとするも、なんか集中してしまって16時頃になった。やっていたことは、ゲームブログのアイコンを作ろうと思って Tarkov のダメージ表示みたいな表現に僕のアイコンを加工していた。

こういうのを真似したくて

f:id:pokutuna:20180430102443p:plain:w250

アイコンはこうなった

f:id:pokutuna:20180428145939p:plain:w250

きわめてどうでもいいと思う。あと主線が太かった。ゲームブログはこちら

escapefromtarkov.hatenablog.com

朝から食事をとらずおやつ置き場に打ち捨てられていた宴会のつまみの残りを食べて暮らしていたので、肉が食べたくなる。インターネットによると近所に知らないステーキ屋があることが分かったので、ディナータイム開店の17:30まで時間を潰す。

会社でやっていたワークショップに参加していた同僚とそのワイフと合流してベトナム料理屋へ行った。お腹が空いたのでマクドナルドで倍チーズバーガーを食べる。チーズバーガー130円に100円追加して倍にしてみたけどもっとデカいバーガーを倍にしないとパフォーマンスが悪い。

2日目

洗濯機を回して運転免許の更新に行く。4/7 生まれなので 5/7 までに更新しないといけない。GW の連休を考慮するとかなりギリギリだった。wishlistはこちら

京都府警察/京都駅前運転免許更新センターによると

土曜日、祝・休日、年末年始の休日は業務を行っておりません。

とのことだけど 4/29 日昭和の日は業務を行っていた。振替られると祝日扱いではなくなるのか、単に日曜ならやっているという話なのか。

京都ヨドバシ北の新しいビルで免許を更新する。新しく綺麗なビルで短焦点プロジェクターを使ってやってるのは原始的な教室のそれで趣があった。立体円グラフが2階建てになっており、中心がずれていた。10時頃着いて11時には新しい免許を受け取れた。

特に行きたい店もないのでヨドバシに行く。何か見るもの無いかと思うものの、欲しいものは大抵既に買っているので驚くほど見たいものがない。若い頃はこうではなかった。欲しいけど買ってないものといえばレーザー距離計があった。レーザーで対象までの距離を計るグッズで、なぜ欲しいかと言うと目測でバチッと距離が分かればかっこいい、それの練習のために欲しい。見に行ったけど2万円以上のモデルばかりがガラスケースの中に置かれていたので遊べなかった。代わりに双眼鏡とかゲーミングマウスを眺めてヨドバシから出た。

2011年に購入した薄汚れて穴の空いたパーカーを着ているのことに気づいたので、ユニクロでパーカーを購入した。涼しそうだったけど薄くていかにも耐久性が低そうだった。2年保たないと思う。その場で装備する。ヨドバシ上の飯フロアでステーキとハンバーグのセットを食べる。コンボにせず全ステーキにすれば良かった。そのまま帰宅する。飯を済ませた観光客がバス停に押し寄せ混雑していたが、意外と自宅への路線はすかすかだった。13時頃家に着いてコーヒーを飲んで寝てゲームをする。

グアムで実弾射撃をしてきた話

IMGP0313 (1)

2017年9月末、消滅の危機に瀕した有給を救うため立ち上がった。 何年もFPSで遊び、銃の文化や歴史に親しんでおきながら実銃を撃ったことないのは悲しい、撃っておけば今後のゲーミングに深みが出る、そういう心持ちでグアムへ飛びました。

グアム旅行情報は下の方にあります。

GOSR

1軒目は GOSR に行きました。 まず一通り撃っておこうと、カスタマイズコースで口径ごとに1種類ずつ選んでいく方針。

gosrjapan.com

IMG_0660

IMG_0667

Glock 17

初めは 9mm が良かろうということで選んだ。 ポリマーフレームはグニョグニョした撃ち味と聞くものの比較対象がないので分かるはずもなく、反動は思ったほどではないものの CS:GO のようにパスパス連射して集弾する感じはしない。 トイガンでは省略されがちなチャンバーに弾が入っている時のエキストラクターの出っ張りを確認しようと思っていたけど忘れてた。

Kimber TLE2(M1911)

20170918_010321_000

想像だと 9mm の倍ぐらいのリコイルがあるイメージだったけど、そこまで .45ACP 反動あるわけではないなと思った、体感だと 9mm の 1.2~1.3倍ぐらいかなあ。 実銃はリコイルスプリングが強いからかスライドストップおろした時の動きがシャキシャキしている...気がする。 シングルカラムも1911も好きだけど、もし1つハンドガンを携帯していいなら 9mm を選ぶだろうなと思った。

SAA 5.5inch

IMG_0673

リボルバーも撃ちたかったのでクラシックな SAA にした。 排莢レバーは勢いをつけて動かさないと薬莢が出てこない。戦いながら一発一発入れるのむりだと思う。 撃ってると銃身から陽炎が立って盛り上がる。

HK94(民間MP5)

IMGP0033

アサイト覗くのがやや窮屈だった。 撃った時の音や感触がメカニカルでこれがローラーロッキングの作用なのかなと思った。 フルオートで撃ってみたいな SMG

SCAR 16S

IMG_0678

クーラーのガンガンに効いた部屋から出してきたのでホロサイトがめちゃくちゃ結露していた。 腕力が無さ過ぎてしばらく構えていると重さに負けてブレてしまう、反動はかなり軽く感じた。 ホロサイトの parallax free 感を確認しようと思ってたけど完全に忘れていた。

AK47

20170918_014513_000

Bumpfire が修理中だったので自力で連射した...反動はあるものの意外と撃ちやすかった。 排莢パワーが強くてやたら遠くへ薬莢が飛ぶ。

Remington M770

IMG_0687

50mほど先に置かれたクレーにバスバス当たるし、ボルトアクションは楽しい。 .30-06 は音も反動もでかくてやや肩が疲れてきていた。

Remington M870

20170918_014937_000

クレー射撃した、3/10 命中で全然当たらなかった... ポンプアクションもシェルを入れていくのはめっちゃ楽しい。 イジェクションポートからもリロードできて楽しめた。

  • よいところ
    • いろんな銃を撃てる
    • 遠くから近くに何らかの的がある
    • 銃の追加が柔軟にできる
    • クレー射撃で動く的を狙うことができる
  • よくなかったところ
    • 人が多かったからか、ベルトコンベア式で次々撃つ順番が来る感じでじっくり撃てなかった
    • シェアした結果銃のレンタル代が浮いたものの、弾が少なくて物足りなかったのでじゃんじゃん追加すべし
    • 何も言わないと店員が付きっきりでマガジン入れたりボルトハンドル引いたりまでやってくれる、こっちは当然自分でやりたいのでその旨を主張しないといけない

CQBGuam

2軒目はいろんな姿勢で撃ちたくて CQBGuam に行きました。

https://www.cqbguam.net/

IMG_0829

オフィスで受け取った弾を各自のアモケースに入れて運ぶ。

IMG_0834

残念ながら大雨で、行程の7割ぐらいはレンジ内から撃つ感じになってしまった。アトラクション感を期待していたので残念。

SIG P320 Compact

IMGP0242

持ちやすかったし撃ちやすくてとても気に入った。 銃自体より専用ホルスターも借りれて抜き差しがしやすかったのが寄与している気もしてきた... マニュアルセーフティがないので装填した状態でホルスターに入れるのはやや怖い。

H&K Mk23

USP を撃ちたかったけど Mk23 になってしまった。 重い & セーフティが遠くて薄い、大型ハンドガンを撃ってる感はすごい。 片手でダブルタップしたらかなり手首がぶれてしまう、5m程度先のマンターゲットに当たりはするけど当たってるだけという感じだった。

BCM Jack Carbin

IMGP0324

民間M4カスタム。またホロ&ブースターの組み合わせ。 Geissele ハンドガードは持ちやすいし SCAR よりだいぶ軽く感じた。 反動も小さいしダブルタップで撃ってて楽しい。 ブースターを使うと30mほど先のナンバープレートにバスバス当たるが、やや右下にゼロインがずれていたように思う。

Kar98k

IMGP0293 (1)

コースと別に追加した銃。 Red Orchestra から PUBG で散々撃ってきたのに実銃は全然当たらない! 30mほど先の缶に10発使っても当てられなくて最悪だった。 クリップでリロードできたし、なんと不発も体験できたのは良かった。

IMGP0241

  • よいところ
    • 4人だったけど、時間に余裕があった
    • スライド引いたりリロードしたり銃自体の操作を色々することができる
    • 弾に余裕があった
    • マガジン地面に捨ててリロードしたり、片腕撃たれた設定で足で銃挟んでリロードしたりもできる
  • よくなかったところ
    • 雨だったので期待していた動きながらの射撃はあまりできなかった
    • USP をオーダーしたのに Mk23 になってしまった、似てるからしょうがない

実弾射撃自体の感想

  • 反動は想像を超えてめっちゃすごいということはない
  • 音は想像よりだいぶうるさい
    • イヤーマフがずれていて .338 lapua の発射音をすぐ横で聞いてしまってしばらく耳の調子が悪かった
  • 銃は重い
    • 正確なエイムに必要なのはまず筋力
  • 的当てがしたいのではなくて、銃を操作したいんだなと思った
    • リロードしたりボルトハンドル引いたりしたい
    • 機構や弾薬の差異を感じて悦に入りたい
    • なんなら分解清掃もしたい
    • なんなら後遺症が残らない程度の箇所を撃たれてみたい
  • 弾をケチると後悔するのでじゃんじゃん追加しよう
    • 2軒で総額 $1000 ぐらい
    • .50AE や .357mag も撃ちたかったのでもっと使えばよかった
    • 12.7x99mm を1発撃で $50 とかするのは流石に高い
    • 一般販売価格と比べるとめっちゃ高く感じるのでツアー代という気分で払おう

グアム旅行情報のコーナー

パックツアーではなく、個人手配で飛行機と宿を予約した。

IMG_0922-EFFECTS (1)

飛行機

京都在住なので、特急はるかで関空からグアムへ。 t'way航空のサイトで予約した。韓国-関空-グアムの定期便がほぼ毎日飛んでる。 ローカライズが怪しくてハングルのページに度々飛ばされたけどなんとかなる。繁忙期でなければ1人3万円を切る価格で往復できる。 同行者の独身男性がパスポートを持っておらずたいへん困ったけど投機的に予約をしてあとでパスポート番号を入力することができた。パスポートができたのは出発6日前である。

飛行機が着く時間は 15 時前後に固まっていて immigration がめっちゃ混むので、速やかに飛行機を降りて少し前を確保するだけで数十分節約できそうである。ESTA はケチって申請しなかったけど、列の長さはあまり変わらなさそうだった。ちなみに2017年現在グアムは ESTA 免除できる。(グアムへの入国|グアム政府観光局)

vs台風

f:id:pokutuna:20180105004916p:plain

当日は台風で離陸できるか危うい状態でヤキモキしていたので同じ境遇の人へ便利情報です。

  • 気象庁 | 台風情報
    • 台風接近時にここの泉州を見ると時間帯ごとに防風域に入っている確率がわかる、6時間おきに更新されるので前日からヤキモキできる f:id:pokutuna:20180105005303p:plain
  • 関空フライト情報
    • 関空がダメと言っていたら望みはない
  • flightrader24
    • このサイトでリアルタイムの飛行機の位置が分かる、ちゃんと韓国を離陸して向かってきとるかな〜という感じに使う

宿

www.fiestaguam.jp

Tガレリア周囲の中心街から離れたフィエスタリゾートに宿を取って正解だった。 中心街はセレブマダム向けの雰囲気。買い物や家族連れには良さそうだけど、独身男性が射撃しに来た状態なので適さない。

フィエスタは

  • ホテル前にバス停があって長距離移動ができる
  • コンビニエンスストア大阪で自転車を借りて移動もできる
  • K マート(ショッピングセンター)へ歩いて行ける
  • Fountain Plaza のサークル K やコーヒーショップで軽い食事の選択肢がある
  • Meskla DOS, Jamaican Gril, Terry's Local Comfort といった良さそうなレストランも近い
  • 部屋がカビ臭い

といったメリットがある!!!

IMGP0505

フィエスタは評判の良いイパオビーチの東端なので、西よりにいくといい感じ。タオルとライフジャケットは無料で借りられる。 Kマートで買った$10ぐらいのシュノーケルを装備して頭を水に付けながら延々と海の中を漂ってると日焼けで死亡する。 マリンシューズがないとサンゴとかで足がズタズタになりそうなので必須である。防水のカメラを持っていくと楽しい。 水深 1.0~1.5m 程度の遠浅の海が続いているので、あまり泳げなくてもなんとかなる。 縄張り意識の強いイカれた魚が足に噛み付いてきたりするので、パンチして追い払うといった戦闘も可能である。

ドライバッグ荷物を入れて海に浮かせ、ナイロン紐とカラビナで作った繋留ロープで体につないでおくと、置き引きの心配もないし、遠目に居場所が伝わるので便利。

IMGP0441

天気

このあたりの天気予報を見てた。

雨季は天気予報がだいたい雨の表示になるけど、どこかしらにスコールが降っている程度のようだった。 滞在6日中4日が雨の予報だったけど、雨が問題になったのは CQBGuam での2時間ほどだった。 湿度は常に90%前後で普通に日本よりクソ暑い。

写真集

でかい服のコーナー。
IMG_0728

ナンバープレートに .223 と .45 を撃った穴の比較。
Untitled

魚でできた棒。
IMGP0555

釣り人の魚を狙う猫。
IMGP0177

ホロサイト & ブースター
IMGP0321

Kar98k のタンジェントサイト
IMGP0290

魚。
IMGP0554

足に噛み付いてくる凶暴フィッシュ。 IMGP0445

一部だけスコールが降ってる様子。 IMGP0127

品質の低いガチャポン、これで $1 もする。 IMG_0964

飯のコーナー

Meskla DOSハンバーガー、すぐ崩れる以外は良い。
IMG_0740

ABC Store で買った朝食めいたもの。
IMG_0763

Jamaican Grill のわかりやすい夕食。
IMG_0757

陰陽茶。
IMG_0747

Coffee Beenery のトルティーヤ、見た目通りの味。
IMG_0645

Terry's Local Comfort の細切れと塊でできた飯。 IMG_0772

Infusion Coffee の完全無欠コーヒー、小にしなかったことを悔やんだ。
IMG_0787

IHOP のパンケーキ、甘くてコーヒー無限でなければ諦めるところだった。
IMG_0898

Chamorro Island BBQ の揚げた魚。単純でうまい。
IMG_0849

南国には当然ココナッツが落ちているので、破壊して食べるためマルチツールを持っていったけどロクなココナッツが落ちてなかった。カブトムシにやられてヤシの木壊滅中らしい。
IMG_0871

狩猟採集を諦めて購入したココナッツ。ほぼイカ味。
IMG_0895

Chili's Restaurant のメキシコっぽい巻物。めっちゃ味が濃い。
IMG_0935

Dr.Kebob のケバブ、野菜の割合が多くて助かる...
IMG_0819

サンキョー・ガーデンの果物、グアムでいちばんさっぱりした食べ物。僕1人のために車で送迎してくれて申し訳なかった。
IMGP0419

Kマートのホットドッグ組み立てコーナー、ハラペーニョ入れ放題で最高。パンは引き出しの中にあります。
IMG_0946

Tips

当時集めたおもしろ情報です


こちらからは以上です。
薬莢は普通に持って帰れました。

Perl でテンプレートの変数に型を書く in 2017

この記事ははてなエンジニアAdvent Calendar 2017の22日目の記事です。前日は id:takuya-a さんの『Bing検索の裏側―BitFunnelのアルゴリズム』でした。たいへん興味深いですね。


はてなPerl アプリケーションが多い会社ですが、今年のアドベントカレンダーは全く Perl の話が出てきてない......。でも僕は Perl 大好き少年なので、このまえ作った CPAN モジュール Text::Xslate::Bridge::TypeDeclaration の話をします。

一般的な Web アプリケーションではテンプレートエンジンに変数を渡して html を組み立てますよね。 はてなでは Text::XslateTTerse Syntax を利用しているプロジェクトが多いです。 例えばユーザ情報を表示するサイドバーの部分テンプレートはこんな雰囲気になるでしょう。

<!-- _sidebar.html -->

<div id="sidebar">
  <div id="profile">
    <img src="[% user_account.icon_url %]" />
    <a href="[% user_account.profile_page_path %]">[% user_account.name %]</a>
    <p>[% user_account.profile_description %]</p>
  </div>

  [% IF show_recent_entries %]
    <ul id="recent-entries">
      [% FOR entry IN entries %]
        <li><a href="[% entry.permalink_path %]">[% entry.title %]</a></li>
      [% END %]
    </ul>
  [% END %]
</div>

このぐらいのテンプレートなら簡単に把握できるけど、実際はこの30倍ぐらい複雑だぞ!!

  • どういう変数があるのかぱっと見よくわからない
  • それぞれの変数はどのようなオブジェクトなのかよくわからない
  • 分割されたテンプレートは再利用可能で良いけどエンドポイントによって変数の渡し忘れが起きがち
    • 一見ちゃんと動いているように見えたりする

などなど気になりますね。

テンプレート中の変数のコメントの歴史

過去のプロジェクトのテンプレートを見てみると、テンプレート中の変数に立ち向かう人類の努力の跡をみることができます。

暗黒時代

<div id="sidebar">
  ...
</div>
  • ただテンプレートがあるだけ
  • 表示のためにどういう変数が必要かは毎回頑張って読み解く、体力が必要
  • よく壊れるし壊れても気づきにくい

冒頭にコメントを書く時代

[% # user_account:  閲覧対象のユーザオブジェクト
   # show_recent_entries: 最近のエントリを表示するオプション
   # recent_entries: 最近のエントリの配列
%]

<div id="sidebar">
  ...
</div>
  • どういう変数を期待しているかは分かる
  • どういうオブジェクトかは変数名やコメントから読み解く
  • 修正時に同時にコメントを修正するのを見落としがち、レビューで気をつける

コメントに型を書く時代

Smart::Args が流行ってコメントに型を書くようになった頃です。

[% # user_account: 閲覧対象のユーザオブジェクト(Model::UserAccount)
   # show_recent_entries: 最近のエントリを表示するオプション(Bool)
   # recent_entries: 最近のエントリの配列(Maybe[ArraRef[Model::Entry]])
%]

<div id="sidebar">
  ...
</div>
  • 型の表記方法に合意が取れた状態
  • 変数のオブジェクトが何か分かるのでどうアクセスすれば良いか分かる
  • レビューで気をつける世界観はそのまま

型をコメントしつつ動くコードにする時代

型を書く期の少し後はこういうのがありました。

[% SET user_acocunt        = visiting_user_account    # 閲覧対象のユーザオブジェクト(Model::UserAccount) %]
[% SET show_recent_entries = show_recent_entries || 0 # 最近のエントリを表示するオプション(Bool) %]
[% SET recent_entries      = recenet_entries || []    # 最近のエントリの配列(Maybe[ArraRef[Model::Entry]] %]

<div id="sidebar">
  ...
</div>
  • 単なるコメントではなく動くコードではある
  • 変数のデフォルト値を設定したりもやる
  • そこまで何かが良くなっている感はない

などなどいろんな工夫で変数に立ち向かってきたものの、これだ! という方法はありませんでした。

こうしたかった

  • テンプレートに型注釈を書きたい
  • コメントではなく動くコードになってほしい
  • おかしければエラーを出したいし、テストでもチェックしたい

という要求を叶えるために、Text::Xslate::Bridge::TypeDeclaration というモジュールを作りました。

こういう感じにつかえるぞ

[% declare(
    user_account        => 'Model::UserAccount',
    show_recent_entries => 'Bool',
    recent_entries      => 'Maybe[ArraRef[Model::Entry]]',
) %]

<div id="sidebar">
  ...
</div>

変数と宣言している型が合わなければ以下のような感じでエラーがテンプレートに挿入されます。

f:id:pokutuna:20171222015047p:plain

テストでは型エラーの要素があればテストが落ちるようにしています。本番環境ではエラーメッセージから情報が漏れないよう、レンダリングのパフォーマンスを落とさないように型チェックを無効にもできます。 これで複雑なテンプレートを書き換えることになってもヘトヘトにならずに済むぜ!!!

どういう感じか

Type::Tiny を利用して型チェックを行っています。
型ライブラリを利用していないプロジェクトでも導入できるようにデフォルトでは Types::Standard の型を利用可能にし、未定義の型名は isa として扱います。(Smart::Args のような敷居の低さを目指した)

Type::Tiny は特に Tiny な感じはしないけど、{MouseX, MooseX}::Types::Base の型を lookup できるのでプロジェクトの型ライブラリを制限しにくくて良さそうなので採用しました。グローバルな型レジストリが無い点は戸惑ったけどアプリケーションとテンプレートで共通の Type::Registry を使うというのは状態が隠れていなくて良い気もします。

単機能なプラグインを Text::Xslate::Bridge:: 以下に作るのは迷いましたが、Xslate->current_var にアクセスしたかったり、エラーをテンプレートに注入したかったので Bridge として作りました。 Text::Xslate::HashWithDefault と組み合わせて未定義変数への参照も行えばより堅牢なテンプレートを作ることができるでしょう。

ぜひご利用ください!!!

そして明日は id:wtatsuru さんです。たのしみですね。