"「怠慢はプログラマの美徳」というけれど"について

「怠慢はプログラマの美徳」というけれど
http://d.hatena.ne.jp/kwatch/20080426/1209230638

Java 屋とスクリプト言語屋の間には、「めんどくさい」と感じるセンスについて超えられない壁が存在している。

とのこと。

前にとり上げたけど、アクセッサの記述がその典型例。本質的でない記述がずらっと並んでいることに、Java 屋はホントに何も感じないのだそうだ。あれがどれだけ readability を下げているか、まったく分かっていない。

まぁRubyにくらべると冗長だよなぁ。ただそれは自分的には別にいいや。
問題は(C++もだけど)いちいちメソッドでラップする作業がそのまんまずらずら並ぶってところだと思う。
Rubyはメタなメソッドがやってくれる。
C#みたいに専用の構文があるほうがまだいい。

たとえばテキストファイルひとつ読み込むのも FileInputStream と InputStreamReader (と BufferedReader) を組み合わせて書かないといけない。

これは…。確かに正直うっとおしいとは思うけど、これはLLと抽象化の度合いに違いがあるからなんとも言えないなぁ。
この上のprintの話もそうだけど、組み合わせて短く書ける手段も用意すればいいのだろうか。それはそれで、たたでさえでかいクラスライブラリがとんでもないことになるような。
割り切ってたくさんの機能に高い抽象性だけを持たせたのがLLか。


どうもコメントの反応がなぁ…。PHPのときも思ったけど、なんで飯食ってる人が多い言語へのケチはあんなふうに「文句とかいらねーよ黙ってろよばか」みたいな感じなんだろうか。
生活成り立たせてるツールにdisられるのがうっとおしいってのはわからなくもないけど、JavaとかPHPとかぐらいになると少々のことでは動じないだろ…。
文句つけるのは応援の一種なんだぞ大抵…。

見てみろよ、どの言語とはいわないけどある言語なんて遅いとか実装が素人くさいとか…。
あ、なんか話題が変わりそうだから終わる。

HashのArray

んでこの話。

data = [
  {'name'=>'Foo', 'age'=>20, 'email'=>'foo@mail.com'},
  {'name'=>'Bar', 'age'=>21, 'email'=>'bar@mail.net'},
  {'name'=>'Baz', 'age'=>22, 'email'=>'baz@mail.org'},
]

これを、

data = %h{
  ['name', 'age', 'email'],
  ['Foo',   20,   'foo@mail.com'],
  ['Bar',   21,   'bar@mail.net'],
  ['Baz',   22,   'baz@mail.org'],
}

こう書きたいという話が。

えぇ…。標準でいるかな、コレ?
第一最初のArrayだけ特別扱いなのが気に食わない。自分で書いて使うならともかく…。
というかちょっと面倒臭がらなければほとんど似たようなもんが書けないか?

keys = %w[name age email]
data = [
  ['Foo',   20,   'foo@mail.com'],
  ['Bar',   21,   'bar@mail.net'],
  ['Baz',   22,   'baz@mail.org'],
].map{|vals|
  h = {}
  keys.zip(vals){|k, v| h[k] = v }
  h
}

これぐらいでも「めんどくさくてイヤ」って言われてしまうのだろうか。
メソッドで抽象化するなら、

def hash_list(*keys)
  yield.map{|vals|
    h = {}
    keys.zip(vals){|k, v| h[k] = v }
    h
  }
end

data = hash_list('name', 'age', 'email'){[
  ['Foo',   20,   'foo@mail.com'],
  ['Bar',   21,   'bar@mail.net'],
  ['Baz',   22,   'baz@mail.org'],
]}

見た目的にはわりと良くない?

ところで、

h = {}
keys.zip(vals){|k, v| h[k] = v }
h

どっちにもこういうのが出てきた。つまりalistからHashへの変換を抽象化するものが標準であれば、メソッドにしなくても

keys = %w[name age email]
data = [
  ['Foo',   20,   'foo@mail.com'],
  ['Bar',   21,   'bar@mail.net'],
  ['Baz',   22,   'baz@mail.org'],
].map{|vals| keys.zip(vals).alist_to_hash }

おお。大分良くないか。
Rubyの変化を追えてないからわかんないけど、増えてないかな? 1.9とかで。
1.8にもバックポートされてる新メソッドはたくさんあるんだよね。

欲しいなー。可変引数とか多重代入とか、Arrayでしゃばりすぎな感もあるけど、Array#assocとかArray#rassocとかあるんだから、この際Array#assoc_to_hashとかだめ?


とりあえずそれがあれば自分は%h記法はいらないかな。抽象化は再利用し易いレベルで機能を切り分けてやってもらえたほうが嬉しい。


追記:
rubikitchさんがStructを使った方法を述べていらっしゃった。なるほど。

[ruby]そこでStructですよ
http://d.hatena.ne.jp/rubikitch/20080428/1209352827

そーだよ、なんでもHashにしたがるから駄目なんだよ。Struct使おうよ。[]でもアクセスできるよ?(<-思いつかなかった癖に)

キーが同じHashがいくつも続くのが嫌なら、そのデータ構造をまず抽象化しとけよ、っていうもやもやがやっと言葉にできた。Struct使うと宣言的で分かり易いなぁ。