How to read code というライトニングトークを勤め先でした
画像やファイル圧縮、インターネット関係のプロトコルの一般的な実装例を知りたいとき、Go 言語のライブラリを読むのが便利だと思っている。 依存関係が少なく、簡易な文法で、新し目のコードを読めるのがその理由。
で、その話を勤め先でした。
トークはひたすら image/png/reader.go を読むという構成だったので全然時間が足りなかったから反省点は多い。
スライドになんでグリッチの話が出ているのかというと、なんで画像フォーマットを題材として選んだのか、というコンテキストがある。 実際は深い理由はない。
PNG フォーマット、まともに読んだのは初めてだけど、割りとこまめにチェックサムを見ているので、データを壊した時に不正な画像になりやすいのは納得感がある。 壊しながらチェックサムのところだけ修復していくのが戦略としてはよさそう。
運動を始めた (知見)
先日の健康診断で「食事に気を使え、ちゃんと運動しろ」と言われたので、最近は取り敢えず走ったり歩いたりしている。
ある程度のコストをかけてちゃんとしよう (ただ、トレーナーをつけたり、ジムに通ったりはしたくない) というポリシーでやっていて、いくらかの知見がたまったので共有する。
服装
ランニング用の装備なしで長距離走ったり歩いたりすると身体を壊しやすいとのアドバイスをもらったので、もろもろの装備を整えている。
靴
靴はアディダスの adizero Mana 7 にした。 いつもはコンバースとか履いているので、ランニングシューズを履くだけで足が軽くなっていくらでも走れる気持ちになれる。(気持ちだけ) 意外と普段履きにもできていて、たまに運動しない日にも履けて使い勝手が良い。
特に靴にこだわりはないのだが、アディダスの adizero にしたのは昔 Youtube で見た動画を覚えていたからだ。 ちゃんとした広告にはちゃんとした意味がある。
[アディダス] adidas adizero Mana 7 M20187 M20187 (ブラック/カーボンメット S14/ソーラーブルー S14/28.0)
- 出版社/メーカー: adidas(アディダス)
- メディア: ウェア&シューズ
- この商品を含むブログを見る
タイツ
近所にモンベルの直営店があるので、そこでランニング用のタイツを買った。 タイツは実際必要なのか疑問だったけど、つけているとたしかに身体が楽で良いし、一度つけずに走ったらふくらはぎがひどい筋肉痛になったので意義はありそう。 あと、METAL GEAR SOLID のスニーキングスーツっぽくて良い。
タイツだけ履いていると違法感があるので、その上にユニクロで買ったショートパンツを履いている。
モンベル(mont‐bell) サポーテックライト タイツ Men’s ブラック BK S
- 出版社/メーカー: モンベル
- メディア: その他
- この商品を含むブログを見る
ポーチ
運動中に身体に巻きつけるポーチもモンベルで手に入れた。 Amazon で評価がよさそうなのを実店舗で大きさとか見て購入した。
ポーチには電話と財布と鍵を入れている。 本当はタオルもしまいたいのだが、それには少し大きさが足りなくて、タオルはポーチの帯に下げる感じにしている。
[モンベル] mont-bell クロスランナーポーチ M 1123647 SV (SV)
- 出版社/メーカー: mont-bell(モンベル)
- メディア: ウェア&シューズ
- 購入: 1人 クリック: 1回
- この商品を含むブログを見る
ほか
ソックスは H&M のランニング用のショートソックスを履いている。 たまに間違えて普通のソックスで走るけど、特に今のところ不都合はない。
上半身はタンクトップの上にどっかのカンファレンスとかでもらったTシャツを着ている。 実際はちゃんとしたランニング用のシャツとかにした方が良い気もするのだが、ランニング用のシャツはどれも派手で少し趣味に合わない。 結果、Code Climate とか Puppet Labs とかのTシャツを着ることにしている。
ランニング用の装備をする利点は身体を守る以外にもう一つあって、ランニング用の格好をしていると、運動したあとにカフェなどに入りやすい。 ジーンズにTシャツとかの格好で汗だくでお店に入ると店員さんから不審な目で見られるが、ランニング用の格好をしていると「ああ、この人はワークアウトのあとなのだな」という認識を得られて普通の対応をしてくれる。 (本当の汗だくだと、さすがにどこにも入れないので、タオルで汗を拭いて体温が落ち着くのを待ってから動くようにはしている)
記録
運動の指標として体重と体脂肪率を置いていて、家にあるオムロンの体組織計で毎朝計測している。 Android アプリを使って NFC 経由で指標をサーバとシンクするやつで、NFC 使うってその設計どうなのという思いはなくはないけど使えている。
以前は Withings のやつを使っていたんだけど、1年くらい前に壊れて1.5万円で買い換えるのがつらかったので今のにした。 Withings は後述の UP のアプリと連携できるので、やっぱり買い換えようかと検討中。
オムロン 体重体組成計 カラダスキャン ブラック HBF-252F-BK【ウェルネスリンク対応】
- 出版社/メーカー: オムロン
- 発売日: 2012/09/03
- メディア: ホーム&キッチン
- 購入: 1人 クリック: 6回
- この商品を含むブログ (6件) を見る
走ったり歩いたりの記録には RunKeeper を使っている。 適当にやったら適当に記録してくれるので良い。
1km の走行時間とか距離とかリアルタイムで教えてくれるのだが、あんまり気にしすぎてもしょうがないので、運動しているときはあまり見ないようにしている。
あと、今週の土曜日に UP24 を手に入れたので身につけている。 フィットネス系のガジェットはもはや Android Wear とか Apple Watch で良いのではという向きもあるが、 腕時計は腕時計で別につけているので、腕時計じゃないものがほしいという気持ちがあった。
スマートフォンアプリと Bluetooth でシンクさせ、腕につけておくだけでよしなにしてくれるので楽。 あと、買うまで知らなかったけど、睡眠をモニターしてくれるし、起きるべきタイミングで腕が震えるので便利だった。
UP のアプリが相当数のサードパーティ製アプリとの連携をサポートしていて、RunKeeper のワークアウトの記録とかを良い感じに表示してくれる。
Jawbone UP24 by JAWBONE JP ライフログ リストバンド 活動量計 ( アプリ連動 / Bluetooth 同期 / オニキス / サイズ M ) JL01-52M-JP
- 出版社/メーカー: Jawbone
- 発売日: 2014/04/08
- メディア: エレクトロニクス
- この商品を含むブログ (2件) を見る
サプリメント
運動前にスーパーヴァームを、運動後にアミノバイタルを飲んでいる。 いずれも顆粒タイプ。
運動を始めたときから飲んでいるので、正直実際に効果があるのかはわからないけど、運動前後の儀式的なものだと思っている。
どちらもそこそこ美味しいので気に入っている。
スーパーヴァームパウダー パイナップル味 10.5g×12袋
- 出版社/メーカー: 明治
- 発売日: 2014/02/24
- メディア: ヘルスケア&ケア用品
- この商品を含むブログを見る
- 出版社/メーカー: 味の素
- 発売日: 2013/02/26
- メディア: ヘルスケア&ケア用品
- この商品を含むブログを見る
ワークフロー
平日と休日で分かれる。
平日
体調がよい、かつ、5時半までに起床した場合のみ1時間弱走ることにしている。
9時くらいには職場に行きたいので、走る準備30分、ワークアウト1時間、着替えとシャワー30分、休憩1時間、通勤30分、を逆算している。
それより後に起きて体調が良ければ自宅で軽くストレッチをやって小走りで通勤することにしている。
休日
体調がよい、かつ、日中特に予定がない、かつ、天気が良い (気温が正気の範囲内でかつ雨が降ってない) 場合、1時間から3時間くらい適当な時間を走ったり歩いたりしている。
9時くらいに家を出て、適当に決めた場所に向かって走ったり歩いたりする。
目的地を決めるポリシーはあまりないが、都心を徒歩で移動するのが好きなので東京駅とかにしている。
この前、間違えてみなとみらいまで行くことにしてしまったら、5時間で 25km 歩くことになり大変なことになった。
経過
運動して1ヶ月弱くらい経つけど、体重が 2kg くらい、体脂肪率が2ポイントくらい落ちた。
太ももからふくらはぎにかけて筋肉がついてきたように思える。 ほかは体感はあまりないけど、胸回りが締まってきたらしく、以前は着ると胸がきつかったシャツがふつうに入るようになった。
あと、歩くのが早くなった。 これはひとりのときには便利だけど、社会的にはあまり嬉しくない特性なので、人と歩くときは注意している。
glitch(1) - グリッチのためのコマンドラインツール
土日に開発合宿に行ったので、その際に glitch(1) というのを作った。
何これ
例によってグリッチのためのツールなのだが、 golang 製のコマンドラインツールとして作られている。
golang がインストールされている端末では、最短2個のコマンドを叩くだけでグリッチ画像が作成できる。
(とはいえ、sed s/a/b/g photo.jpg > output.jpg
とかすると1コマンドでグリッチできるので、実は別段優れているわけではない)
今のところ sed glitch と repeat glitch と自分が呼んでいる手法について実装してある。 JPEG 画像だとうまく壊れるが、他のフォーマットではまだあまりまじめに確認していない。
特に何も設定しなくてもそれなりの壊れ方をするようになっているけど、オプションをいくつか渡すことでその人好みの壊れ方をすることができる。
例えば、
$ glitch repeat -e 15 -b 200 -n 10 -o glitched.jpg /path/to/yourfile.jpg
は、データの前方 15% をヘッダとして無視した後、その次の200バイト分のバイト列を10回繰り返し書き込み、その後のデータを書き込んでから glitched.jpg というファイルに出力している。
今後も時間があればいろいろな手法を実装していきたい。
なぜ作ったのか
最近、 ghq とか peco のような golang 製のコマンドラインツールが流行っていて、自分でも必要が生じた際にサクッと作れるように作り方を把握しておきたかったのが一番の目的である。
あと、画像や動画を壊したりする仕事は、原則としてバイト列を操作することに終始するのだが、今のところそういうのがあまり得意じゃなさそうな Ruby とかで書いていて、もうちょっと向いていそうな言語を探しているというのもある。
開発について
あんまりスクラッチから golang を書いたことがなかったので、探り探りでやっていた。
ghq のコードとか読んだ時に見かけた cli.go というライブラリがコマンドラインパーサのデファクトスタンダードのようなのでこれを採用した。
tcnksm/cli-init という cli.go 用のコードを生成してくれるツールもあったので、これを使って雛形を作った上で、画像を壊すロジックをガシガシ書いていくだけだったので、かなり整っている印象だった。
バイト列操作には bytes パッケージに Repeat
とか Replace
のようなそのまんまな名前のメソッドがあって便利だった。
画像を壊すことに興味のある人々は golang でやるのがかなり効率的だと思った。
合宿について
- 今回の開発合宿は勝どきのホテルの会議室でやったので、地下鉄で通えて便利だった。
- 夜に mirakui さんが Podcast の収録をするということで、10人くらいでホテルの一室にこもって話を聴いていた。 ★
- 翌日の昼、昼食を取りに勝どき駅の辺りまで行ったけど、人通りはあるのに飲食店はまったく開いてなくてつらかった。この近隣の人々は休日は外食しないのだろうか。
- 月島の方のもんじゃ焼き屋さんが開いていたので事無きを得た。
(合宿っぽい写真を貼っときますね)
zsh で rbenv の Ruby のバージョンをプロンプトに表示させる
rbenv あるある: rbenv shell のつもりが rbenv local と打っていて、そのカレントディレクトリ以下での実行した Ruby のバージョンが意図しないバージョンになってしまってる。~/ でやりがち。
— セコン (@hotchpotch) January 5, 2014
たしかに、自分の使っている Ruby のバージョンがわからなくて辛い時が私もしばしばあるので、Ruby のバージョンをプロンプトに表示させてみることにしました。
単純に rbenv version
をコニョコニョしているだけです。
rbenv_version () { if [[ "`rbenv version | grep '.rbenv/version'`" = "" ]];then if [[ "`rbenv version | grep 'RBENV_VERSION'`" = "" ]];then local setting="L" else local setting="V" fi else local setting="G" fi RPROMPT="[☃ `rbenv version | cut -f1 -d' '`($setting)]" } add-zsh-hook precmd rbenv_version
rbenv global
で設定した Ruby だったら (G)
、rbenv local
で設定したものだったら (L)
、環境変数 RBENV_VERSION
で設定したもの (== rbenv shell
を呼んだ状態) だったら (V)
と表示されます。
設定してはみたものの、常時 Ruby のバージョンを意識する必要性はない気がするから、プロンプトの色がさりげなく変わるとかが良いのかもしれません。
activerecord-msgpack_serializer というのをつくった
ActiveRecord に serialize という機能があります。
特定フィールドにオブジェクトをシリアライズして保存する機能で、デフォルトでは YAML が使われますが、 load
と dump
のクラスメソッドを持つクラスを指定することで、任意のフォーマットでシリアライズすることができます。
activerecord-msgpack_serializer は MessagePack を使った ActiveRecord のシリアライズを行なう機能を提供するもので、以下の様に使います。
require "activerecord/message_pack_serializer" class Post < ActiveRecord::Base serialize :meta_data, ActiveRecord::Serializers::MessagePackSerializer # ... end
上記の例だと、 meta_data
というフィールドについて、Array や Hash などのデータを出し入れすることができ、内部的には MessagePack で保存されるようになります。
実装 *1は結構シンプルなのですが、そこそこ使いでがあると思います。
exception_notification_fluent_logger_notifier というのをつくった
exception_notification_fluent_logger_notifier という異様に長い名前の gem を作りました。長すぎて RubyGems.org のフォーマットが崩れます。*1
インストールすることで ExceptionNotifier::FluentLoggerNotifier
というクラスが生えます。
exception_notification はRack などに仕込んで例外が出たら通知を行なう gem です。
通知の方法として、メールや HipChat などいくつか組み込みの notifier があるのですが、独自の notifier を作成する方法が提供されています。
今回作った ExceptionNotifier::FluentLoggerNotifier
は、例外が発生した際に fluent-logger-ruby を経由して Fluentd にデータを送ることができます。
Rails で使用する場合は、 config/environments/production.rb
などに以下のような設定を記載することで動かすことができるというものです。
Whatever::Application.config.middleware.use ExceptionNotification::Rack, :fluent_logger => { :tag_prefix => "exceptions", :logger_settings => { :host => "localhost", :port => 8888, } :template => { :exception_class => ->(exception, options) { exception.class_name }, :exception_message => -> (exception, options) { exception.messaage }, } }
ユースケースとしてはいくつか考えられると思いますが、私の場合は fluent-plugin-hipchat で HipChat に例外を通知するのに使っています。 *2
*1:https://rubygems.org/gems/exception_notification_fluent_logger_notifier
*2:もちろん exception_notification 組み込みの HipChat notifier を使ってもいいのですが、通知のフォーマットを自由に設定できること、アプリが HipChat の API トークンについて気にしなくていいこと、などで FluentLoggerNotifier 経由で通知する方が優れています
文化の日なので cURL で GIF アニメ作るやつを作った
文化の日でしたね。
それはさておき、あまり知られていないことのようですが、 Heroku のインスタンスはデフォルトで ImageMagick がインストールされています。 なので、適切なライブラリ (たとえば Ruby だったら RMagick など) を使うことで簡単に画像をいじることができます。
さて、ある環境で ImageMagick が動くということが分かった時、我々がやるべきことはもちろん、アニメーション GIF を作ることです。
コマンドラインにおいて ImageMagick を使って GIF アニメを作る方法は簡単で、 convert
という ImageMagick が専有している非常に一般的な名前のコマンドを使って以下の方法で実現できます。
$ convert foo.jpg bar.png baz.gif output.gif
ImageMagick の Ruby バインディング (のデファクトスタンダード) である RMagick でも GIF アニメを作るのは同様に簡単です。
image_list = Magick::ImageList.new("foo.jpg", "bar.png", "baz.gif") image_list.write("output.gif")
ということで、実際 GIF アニメを作ること自体は ImageMagick がある環境では比較的簡単なのですが、もっと簡単にできそうということで、 GIF アニメを作って返すだけのサービスを Heroku に置きました。
Yet Another Something Which Generates Animated GIFs
使い方は非常に簡単で、 files
パラメータに元画像のファイルを配列として設定したリクエストを POST で送るだけで、GIF アニメが降ってきます。
便利ですね。*1
今はシンプルな GIF アニメしかできないですが、ご存知の通り ImageMagick には設定できる無数のパラメータがあるので、手の入れようはいっぱいあると思っています。
*1:好事家のみなさんのためにそんな大したものじゃないけど ソースコードも置いておきます。