Python の内包表記とRuby のブロック

Pythonista が Ruby に優越感を抱くのに、内包表記の存在がある。内包表記は select + map でいけるし、日本人としてはあまり読みやすいとは思えない(内包表記は英語だと語順が自然)ので、Ruby 風に書くと確かに冗長だけれども、Ruby には採用しないみたいなことを Matz は書いていた。確かにちょっと冗長かな。ある本に Python

{x:str(y * y) for x, y in {1:2, 3:4}.items()}}

Ruby

{1=>2, 3=>4}.inject({}) do |result, key_value|
  result[key_value[0]] = (key_value[1] ** 2).to_s
  result
end

と翻訳してあった。さすがにこれは変数名と行分けに悪意を感じる。比較するなら

{1=>2, 3=>4}.inject({}) {|h, (x, y)| h[x] = (y ** 2).to_s; h}

ではないの? それから、冗長にはちがいないけれど

 (h = {1=>2, 3=>4}).each_key {|x| h[x] = (h[x] ** 2).to_s}

とも書ける。Ruby 2.1 以降なら

 {1=>2, 3=>4}.map {|x, y| [x, (y ** 2).to_s]}.to_h

とかね。これなら(読みやすさで)内包表記にそれほど劣るとは思えない。

Python入門[2&3対応]

Python入門[2&3対応]


module Enumerable
 def maph(&bl)
   map(&bl).to_h
 end
end

{1=>2, 3=>4, 5=>6}.maph {|k, v| [k, (v ** 2).to_s]}
#=>{1=>"4", 3=>"16", 5=>"36"}

とかあってもよさそうな気が。いや、いらんな…。


※追記
以下でもよい。

 {1=>2, 3=>4}.each_with_object({}) {|x, h| h[x[0]] = (x[1] ** 2).to_s}

色いろありますな。(11/10)