私は可算ためeach
方法の例を見て:人はこの1つを使用していないのはなぜEnumerableのブロックリンクは許可されていますか?
def each(&block)
@items.each do |item|
block.call(item)
end
end
:
def each(&block)
@items.each(&block)
end
どんな違いがありますか?
私は可算ためeach
方法の例を見て:人はこの1つを使用していないのはなぜEnumerableのブロックリンクは許可されていますか?
def each(&block)
@items.each do |item|
block.call(item)
end
end
:
def each(&block)
@items.each(&block)
end
どんな違いがありますか?
実は私は、次のバージョンは、より一般的に見られていると思う:
def each
@items.each { |i| yield i }
end
これはあなたの最初のサンプルコードと同等です。
class Test
def initialize(items)
@items = items
end
def each1
@items.each { |i| yield i }
end
def each2(&block)
@items.each(&block)
end
end
を守ってください:このと2番目のバージョン間の微妙な違いがあります
irb(main):053:0> Test.new([1,2,3]).each2
=> #<Enumerator: [1, 2, 3]:each>
irb(main):054:0> Test.new([1,2,3]).each1
LocalJumpError: no block given (yield)
from (irb):43:in `block in each1'
from (irb):43:in `each'
from (irb):43:in `each1'
from (irb):54
from /usr/bin/irb:12:in `<main>'
バージョンはその代表者、何もブロックが指定されていない場合は反復可能で、実際に列挙子を返し根底にブロックされ非常にいいです。それは私たちがこのようなものを書くことができます:
irb(main):055:0> Test.new([1,2,3]).each2.map { |x| x + 1 }
=> [2, 3, 4]
は、私たちの明示的なバージョンで同じことを達成するために、我々はこのようにそれを適応させる必要があるだろう。でも、より詳細な
def each1
return enum_for(:each1) unless block_given?
@items.each { |i| yield i }
end
はどれ。ボトムライン(Bottomline):可能であれば、ブロックを基になる列挙型に委譲して、コードの重複やこれらのような微妙な問題から自分自身を守ります。
ところで、あなたのeach
メソッドの2つ折りの性質を理解したので、別の名前を付けるのが理にかなっています。たとえば、あなたがString#chars
かIO#lines
のような方法の例に従うと、あなたの方法items
呼び出すことができます。
def items(&block)
@items.each(&block)
end
ありがとう、あなたの3番目のコードの例は私に違いを示した:)のように、私は正しかった:) –
を(私はそう、私は答えを作成しません100%確実ではないけど、私の知る限り実際的な違いはありません最初はおそらく遅く、間違いなくもっと冗長である)。なぜ人々はそれを使用するのですか?おそらくそれは取得するのと同じくらい簡単なので、2番目のブロックはブロック/ Procsを回避する方法についていくつかの理解が必要です。 – tokland
@tokland:それは完全には正しいとは言えません。ブロックが2番目のブロックと等価でなければ、最初は列挙子を返す必要があります。 –
@Niklas、そうだよ、Rubyはそれぞれにブロックが渡されないときに列挙子を返すようになった。第二の理由を使用するもう一つの理由。 – tokland