よもやま話β版

よもやま話を書きます。内容はぺらぺら。自由に書く。

目玉焼きの焼き方の名前(雑学

初めて習った目玉焼きの作り方は、焼き始めたあとに水を足して蒸し焼きにするやり方だった。 自分はこれを唯一無二の目玉焼きと信じて20年ほど生きたあと、一人暮らし中に、蒸し焼きせずにフライパンに落として待つだけで白身が固まるという発見をした。しかもこの方法だと黄身の半熟加減を決めるのが蒸し焼きよりもやりやすかった。

すごい発明だぞと喜んでいたが、これは世界の新発見ではなかった。すでに名前が付いていたのだ。

  • sunny-side up: 片面のみ焼く方法
  • turn over: 両面焼く方法
  • basted egg: 蒸し焼き

世界の物事には大抵新発明というのは残念ながらなくて、大概既存の便利なものや概念が存在している。しかしそれらの既存のものを少しずつ付け足したり、組み合わせたりしてより便利なものを作るということも立派な仕事と言えるはずだ。 自分は多分新発明する力はないけど、gemとか既存のノウハウでサービスを保守開発運営することはできる。できることでとりあえず粛々と頑張っていこう。

朝ごはんの目玉焼きを見ながら、なんとなくそういうことをつらつら考えた。おしまい。

最高と最低限の開発グラデーション

とある機能を開発するにあたって、最高を目指す開発と、最低限の開発と言うものがあると思う。 ざっくり箇条書きしてみよう。
ただし、 どちらも要件は実現されていて、機能は正しく動いている ものとする。

最低限の開発

  • 設計がちょっとあやしい
  • テストコードがない
  • 命名がダサい
  • 野暮ったい実装
  • コピペコードを含む
  • 見落とされたtypoがある

最高を目指す開発

  • 将来のことも検討されているシンプルで美しい設計
  • メンテしやすいテストコードがある
  • よく検討された分かりやすい命名
  • スマートな実装
  • コードが適切に再利用されていて重複していない
  • typoなどの安易なミスは駆逐されている

開発のグラデーション

何事にもハイとローの2方面があって、そして選択肢はその両極端にあるのではなく、常にその中間のどこかにもたくさん存在する。 以前お世話になった方がよく言っていた「グラデーション」という単語を強く覚えていて、自分も参考にしている。 開発にもグラデーションがあって、時と場合に応じて一部取捨選択をする場合がある。

設計を綺麗にしきれずにある程度で妥協するとか、
テストコードが一部省略されたりとか、
安易なtypoミスを気づいたけど修正する余裕がないとか...。

その時々で納期とかチームの総合力とか、色々な周辺要素に応じて出来る限界は決まってくる。 もちろん最高の開発を目指すことがベストだが、要件の実現に対してかけるべきコストと天秤にかけてうまい具合に妥協点を探り、確実に要件を達成していくほかない。ベストな妥協点を探って実装に落とし込む力というのも重要なのだ。
そう自分に言い聞かせながら、今日も最高と最低の合間の出来の実装をmergeするのだった。

ちなみに

最低限の対義語、一応「最高限」というものがあるようだが、耳慣れない。 人間高みを見るとキリがない(から、限という漢字がつくと違和感がある)ということなのだろうか...。

kotobank.jp

Rubyのnext, return の違いを再履修

qiita.com

完璧にハマったところを、上記記事に救われました。感謝... :pray:
自分でも再履修してみる。

サンプル

次のような実行結果を期待してコードを書いたとします。

hey
hello
hello
# hello.rb
def hello
  3.times.map do |n|
    return 'hey' if n.zero?
    'hello'
  end
end

puts hello

しかし実際の実行結果は次のようになります。

hey

なぜそうなるのか

return の説明を改めて見直してみます。
https://docs.ruby-lang.org/ja/2.5.0/doc/spec=2fcontrol.html#return

式の値を戻り値としてメソッドの実行を終了します。

hello.rbreturn と書いているのはブロック内ですが、あくまでメソッドの終了を支持しているので、helloメソッドの戻り値として「hey」が返されました。ブロックの戻り値を指定したい場合は next を使います。

https://docs.ruby-lang.org/ja/2.5.0/doc/spec=2fcontrol.html#next

nextはもっとも内側のループの次の繰り返しにジャンプします。

# hello.rb
def hello
  3.times.map do |n|
    next 'hey' if n.zero?
    'hello'
  end
end

puts hello
hey
hello
hello

基本はメソッドが戻り値を返すコードを書くのですが、そのノリでブロック内でreturnを使うとまずいですね。

ちなみにバグは自動テスト(RSpec)によって気づくことができました。
やはりテストは重要。

映画で思い知る子供の頃と大人の今の獲得情報量の違い

風邪を引いてしまい、超楽しみにしていた後輩との飲み会をキャンセルして家に帰って寝込み始めた頃合いに、テレビをつけると「紅の豚」が金曜ロードショーでやっていた。 体調の悪さとテレビの内容からにわかに幼稚園〜小学校低学年の時代を思い出した。 その時代は頻繁にひどい風邪を引いて、昼間は家で寝こんでいるということも多かった。 ベッドの側には小さなテレビとビデオデッキがあって、父が趣味を兼ねて撮り溜めたビデオテープが山ほど積まれていた。 小さい自分のお気に入りはジブリ映画だった*1。トトロとかナウシカとか魔女の宅急便とかをそれこそ飽きるほど見た。もちろん紅の豚も。
だからストーリー全編は一通り頭に入っている。
そのはずなのだけど、いまになって改めて腰を据えて視聴すると、細かい描写とかセリフから得られる情報量が天と地ほども違うことに驚いてしまう。見ている映像はもちろん当時と寸分違わないはずなのに...。

勘違いしていたこと、いまさら気づいたこと

1930年代くらいのイタリア

銀行員に愛国債券をセールスされるシーン、「札束が紙くず並みの値打ちしかない」、「ファシストの秘密警察」、「アドリア海/ミラノ」といったキーワードから舞台がファシスト党の時代のイタリアだということが示唆されている。
が、子供時代はそういうのをよく分からないので、たぶん 海外のちょっと昔の話なんだな? くらいの認識だった気がする。

女性ばかりで飛行艇をこしらえること

フィオが設計すると言い出したときに難色を示すポルコ、ぞろぞろ工房に入ってくる女性たちに面食らっていたり、「女の手を借りて戦闘艇を作ることをお許しください」というお祈りの文句から女性が飛行艇を作るというのはイレギュラーなことである、そして男たちが出稼ぎで居ないからだという説明がされているが、小さい頃は全然そういうことは疑問に思ったりとかしていなかった。テキパキ食事の支度がされたり飛行艇の部品を作っていくシーンはすごく好きで覚えている。だが、そもそもそれらが女性たちばかりでこなす仕事にしてはイメージが真逆という示唆だと思う。おそらく戦争のにおいが強いとか、野蛮(? めっちゃロマンがあって良いな〜と個人的には思うところだが、世間一般的にはそんな感じなのだろうか)とか、エンジニアリングの要素が強いとか。昔はそういうことをまっっったく気づいて居なかったけど、そういう空気感を読み取れるようになってしまったんだなぁと感じた。

カーチスは空賊の用心棒

てっきりカーチスは空賊の一味だと信じ込んでいた。久々に視聴してちょっと混乱した。
たしかにただの仲間にしては浮いているし青いし雰囲気が違いすぎるし行動がよく分からない。 用心棒という単語を昔は知らなかったんだと思う。 あと今更ながら、むちゃくちゃ惚れっぽいなこの人...なんて感想を抱いた。

フェラーリンさん

映画館でポルコの隣に座って不機嫌そうな感じだった人と、空軍から逃げる方法を教えてくれた人と、最後にジーナに馬鹿騒ぎをやめさせるように連絡した人が全部同じ人だったということは小さい頃は本当に気づかなかった。 それどころか、覚えているのは「映画館でポルコの隣に座って不機嫌そうな感じだった人」で、逃げる方法を教えてくれたシーンは「よく分からないけど手信号で豚に真珠と言い残していった謎の人」で、「ジーナは通信を自分で傍受して危機を察知した」ものと思っていた。小さい頃の自分まじで映画全然見てないじゃん...だめやん...。フェラーリンさんごめんなさい。

最後のシーンはかなり未来

「あれからいくつかの動乱があって」と最後にフィオが静かに語り、その後のホテル・アドリアーノの様子を眺めて映画は終わる。 動乱というのはおそらく戦争とかのことを指しているし、集まっている面々の姿をみると結構老けている。これ10~20年くらい経っているんじゃないだろうか...。しかもフィオの会社のピッコロ社の名前のついた飛行機がよく見たらめっちゃ進化したデザインに変わっている。細かい映像のディテールに小さい頃は気づけなかったのか、病気の時ばかりに見ていたもんで最後は寝落ちしていたかもしれない。改めて気づいた。

その他、会話の端々細かく挟まれる皮肉とか絵に出てこない情報

なんか海外ドラマとかでありそうな皮肉とかが入ってくるけど、子供の頃は基本的によく聞き流していたと思う。 ポルコが怠惰な豚である罪とか猥褻物陳列罪とかひどい余罪をふんだんに付けられていたりとか、会話の中の面白い要素はすべて受け取り損ねていたように思う。

こどものころ、分かった気になっていたけど、まず語彙と経験が足りなかった

昔ベットの中でテレビ画面をじっと見ているしかなかったときは、この映画の隅々まで楽しみ尽くしていたような気がしていたけど、世界は狭かった。あのころ、母にイギリスはどこにあるか知っているかと聞かれて、「イギリスは大国だからきっとこの辺」とアフリカ大陸を指差していたらしい。本当に語彙も経験も何もかも不足していた。 いまの自分も、5年後10年後の自分からみたら、語彙も経験も何もかも不足している状態なのかもしれない。

初心を忘れずがんばらなきゃなぁと思いつつ、いまは風邪をとっとと治したい。

*1:ただし火垂るの墓を除く。無茶苦茶怖かったのを覚えている、そして唯一自主的に見た記憶が一度もない。

config/localesの中身を考える(小分けが好き)

ソースコードが増えていくにあたって、1ファイルがどんどこ伸びていくか、ファイル数ががんがん増えていくかの2択があるが、自分は後者のファイル数を増やす方がいいと考えている。長いファイルの一部を編集するのはインデントとかのミスのリスクが高いと感じる。

えいやでRails開発していて、I18nを利用していると、config/locales 以下にどんどこファイルができる。 次のようにconfigに設定しておけば、ファイル群を階層化しても読み込みしてくれる。

参考: Rails国際化 (I18n) API | Rails ガイド

# config/application.rb
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]

中身のYAMLさえ形式に則っていれば、ファイル名はなんでもよいので、あえてルールでしばらないと1ファイルの中身がもりもり増えていく。例えば開発超初期はモデル数が1,2個だったりして、まぁ分けるまでもないかと思ってこうしたとする。

config/locales
└── models
    └── ja.yml
# config/locales/models/ja.yml
ja:
  activerecord:
    models:
      user: ユーザ
      book:attributes:
      user:
        name: 名前
      book:
         title: タイトル
         price: 価格

まだこの時点ではいいかもしれない。では今後開発が進んだらどうなるだろう?
永遠に肥大していく ja.yml とどこかで決別することを迫られることになるはずだ。

config/locales
└── models
    ├── user.ja.yml
    └── book.ja.yml
# config/locales/models/user.ja.yml
ja:
  activerecord:
    models:
      user: ユーザ
    attributes:
      user:
        name: 名前
# config/locales/models/book.ja.yml
ja:
  activerecord:
    models:
      book:attributes:
      book:
         title: タイトル
         price: 価格

小分けにしておいたほうが参照もパッとできて良さそう、と考えている。

ちなみに、Railsガイドの例では config/locales/models/book/es.rbconfig/locales/models/book/en.rb というようにモデル名をディレクトリ名としてその下に言語別のファイルを格納しているが、基本的にいま自分が関わっているプロジェクトがjaしか見ていないので、ディレクトリ化していない。もしenとjaを併用しなければいけないシーンになったらRailsガイドの通りにネストしたほうがよさそうだ。

オフィスが出来て変わったこと/ごみ処理券

コワーキング時代は気にしなくて良かったものとして、事業系ゴミ処理券の存在がある。 事業をやっているところはゴミを出す際にゴミ袋にこの券を貼って出す必要がある。(これは中央区の例)

f:id:beta_chelsea:20181030092825j:plain:w320

20Lゴミ袋用の券が1束10枚綴りで1520円。
10L、20L、45Lと種類も色々あって、サイズによってお値段とシールの色が違う。

普段家庭ゴミもマンションのゴミ捨て場に出すだけなので、事業としてこのようにゴミ処理券が必要という事実を改めて知って、ゴミ削減を意識することが増えた。 コワーキング時代はゴミはまとめて施設の方で対応してくれたので気にする必要がなかった。 色々助けられていたんだなぁとしみじみ感じる...。

とりあえず毎回事業者名のところに名前を書くのが超面倒なのでそろそろ気軽に使える会社名のハンコ欲しくなってきた。

困難は分割せよ(diffを減らしてmergeしていく話)

超小規模エンジニアチーム*1とはいえ、ときにはでかいリリースの必要性に迫られることがあります。 今回取り組んだ機能実装では、3つのmigration、4つのcontrolller、たくさんのviewとテストのファイルを新規作成しました。

ぼっちでやるにあたって、でかいプルリクはでかいというだけでリスクです。見直しにも集中力が必要でしんどいです。 ちょっとでもまともにリリースするため、自分は全体像が完成したら、切り出せそうなところを抽出して先にリリースするようにしています。困難は分割せよという言葉が合いそうだなぁと思います。

多種多様な意見がありますし、将来の自分が見たら考えが変わっていて後ろから刺される可能性もありますが、現時点での自分のやり方を挙げてみます。

まず master ブランチからfeatureブランチを生やします。featureブランチを育てるだけ育てます。このときcommit名とかにはあんまり気を配りません。とにかく80~90%くらいの完成度を目指してcommitを積みまくります。 ほぼほぼ完成に近づいたら全体を眺めます。全体の中から既存の機能に対する変更や、単体で更新できそうな機能(child_a, child_bとします)を考えます。

masterブランチから改めてchild_a, child_bを生やし、抽出できる機能を移植します。 移植には $ git checkout ブランチ -- ファイル名 を使うと便利です。

$ git checkout -b feature master
$ git commit -m "バリバリ開発"
...
$ git checkout -b child_a master

こうするとfeatureブランチから app/models/hoge.rb をとってこれる。
とってきたデータはステージされている状態となっている。

$ git checkout feature -- app/models/hoge.rb
$ git status
On branch feature
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   app/models/hoge.rb

$ git commit -m "hoge.rbだけ取り出して先にリリースするぞ"

この時点でchild_aのdiffを眺めて、もうちょっと良くできないか考えます。 大抵の場合、膨れ上がったfeatureブランチでは見つからなかった問題点や不足していたテストなどに気づき、この時点で手を入れます。 その後、納得できたらmasterに先にmergeします。

$ git commit -m "さらにリファクタしたぞ"
$ git checkout master
$ git merge child_a

ここで child_a は feature に含まれるものよりもだいぶ変わっている状態です。 変更を取り込むとき、merge派とrebase派がいるような気がするんですが、自分はrebase派です。 何回も繰り返してコンフリクトを修正するのが面倒なので、自分はfeature ブランチに積み上がったコミット群をひとまとめにしてからmasterにrebaseします。

# featureに移動して10件のcommitをひとまとめにしてしまう
$ git checkout feature
$ git rebase -i HEAD~10
# 全部squashする。歴史はあとで改変する。
# ひとつにまとまったらmasterへrebaseする
$ git rebase master
# おそらくコンフリクトするので、うまく修正する。

これをfeatureブランチを機能が分解できなくなるまで繰り返し、最後にfeatureブランチの歴史を整えなおして全機能のリリースが完了します。

一通り書き出したけどあんまり分かりやすいとは言えない説明になった。 うーん、図解とかが入れば良かったかもしれない。 Gitで歴史をどうにかするごにょごにょは別途記事にしようかな。

*1:チームといいつつぼっちでやっています。2018年秋の時点ではリファラルで仲間を探しています。