mapに与える&を.(ドット)で繋ぎたい

投稿者: Anonymous
class Hoge
  attr_accessor :foo

  def initialize(value)
    @foo = Foo.new(value)
  end
end

class Foo
  attr_accessor :value

  def initialize(value)
    @value = value
  end
end

values = [
  Hoge.new(1),
  Hoge.new(2)
]


p values.map{|hoge| hoge.foo.value} #=> 問題なし
p values.map(&:foo.value) #=> エラー

undefined method `value’ for :foo:Symbol (NoMethodError)

サンプルソースは上記のとおりです。
エラーが起きているものの行の上の行と同等の動きをすると想定していますが、文法的に認識してくれずエラーのようです。正しい書き方はありますか?

解決

結論から言うと不可能です。

まず文法上の認識の間違いがあります。
&:foo.valueの解釈は、
&[:foo.value]となります。 よって :foo に .value が存在せずエラーとなります。
検証方法としてvalues.map(&:FOO.downcase)を実行してみてください。:FOO.downcase #=> :fooですから何のエラーも起こしません。

次に、values.map(&:'foo')が可能なのでvalues.map(&:'foo.value')が可能であると思われるかもしれません。しかしこれも不可能です。
なぜならvalues.map{|x| x.send(:'foo.value')}と等しくなりますのでundefined method `foo.value’が発生します。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *