ちなみに

火曜日の空は僕を押しつぶした。

Enumerable#inject(init, sym)が格好良すぎる件について

Enumerable#map(sym)とは大違いですね(追記、そんなメソッドはない)

renconで、多重かもしれないHashの値をhash[:foo][:bar][:baz]といきなりアクセスして取得しても大丈夫なように、1つ1つ取り出して確認して最後までたどり着ければその値を返すというメソッドを書いたときに(オリジンルじゃないですよ)、うじひささんに指摘された書き方が、

# @confが多重Hash
def conf(*keys)
  keys.inject(@conf, :[]) rescue nil
  # FAIL: keys.inject(@conf, :[]) raise nil (thx ujihisa)
end

で、これはinject(init)を使って書くとこう、

def conf(*keys)
  keys.inject(@conf) do |conf, key|
    cont[key] or break nil
  end
end

なんかかったるくなりましたね。
読み易さの面で言うと後者に軍配が上がるのですが、「@confからkeysを引数に[]を呼び出して、途中で問題が発生したらnilを返したいんだ」という気持ちを率直に表しているのは前者なのではないでしょうか。
まぁなんと言うか、見た目が格好良いのは確実に前者です。好みの問題でしょうが。


最近はコーディングスタイルをどうするのか、考えながら書いているのですが、その時の主な基準が

  • 読み易いか
  • 自分の意思を出来るだけ素直に表しているか
  • 横に長過ぎないか

なので、出来るだけ短い*変態的*なコードは書かない様にしていたのですが、こういうのを見ると決意が揺らいでしまいます。

ましてや、[ruby-list:45691]で挙げられていた、

"File::Stat".split(/::/).inject(Object){|s,m| s.const_get(m) } # => File::Stat

が、

'File::Stat'.split(/::/).injet(Object, :const_get) #=> File::Stat

と書いてみて一発で動いた日には...ねぇ?


(追記)
これを書いていて気づいたのですが、シンボルは暗黙的にProcオブジェクトに変換されるようになったので、inject(@conf, &:[])と書く必要はないのですね。ずっとary.map(&:meth)って書いていました。

(さらに追記)
完全に勘違い。Enumerable#inject(init, sym)はそういうメソッド、map(&:meth)はmap() { }の別の書き方なだけ。