3 ms·
Genuinely no idea what your statement does, but “yield 123” or “yield from xyz” is infinitely more clear.
by orf 6y ago
Genuinely no idea what your statement does, but “yield 123” or “yield from xyz” is infinitely more clear.
- regularfry 6y agoI think nestling somewhere in the core of the GP's comment is that Ruby also has `yield`, and using it (or related functionality) is pervasive.
- inopinatus 6y agoThat’s the idiom for an enumeration method called without a block. It’s why you can chain them, as in ary.map.with_index and so forth.
- vidarh 6y agoIt creates an Enumerator (for practical purposes consider it a continuation) over the method "each" unless you've passed in an argument named "block", which by convention would be a block argument (a closure passed after the argument list effectively) that will evaluate to Proc object. Consider this example: class Foo def each yield(42) yield(:hello) yield(:world) end end You can now do: Foo.new.to_enum(:each) (In this case the ":each" is redundant - to_enum defaults to :each, so you could do Foo.new.to_enum) And you will get back an Enumerator that supports the Enumerable interface, giving you methods like map, inject, to_a (to array) etc. as a facade to the original object so you can do (for example: Foo.new.to_enum.to_a => [42, :hello, :world] (you can achieve a similar thing by including Enumerable into the class in question, but to_enum lets you do this on arbitrary objects without messing around with the class) It allows any method to return something that behaves like a collection class without needing to pass more than a method that implements "each" by yielding each value of the collection. You can also do this with a bare lambda, btw., but the syntax is a bit awkward as "yield" is syntactic sugar over calling the "call" method over an implicit (unnamed) block argument that isn't quite as transparent as you might like: ob = ->(&block) { block.call(42); block.call(:hello); block.call(:world) }.to_enum(:call) The explicit "&block" argument is needed because "yield" has lexical scope where defined. "ob" is now an enumerator that supporters each, to_a, map etc.: ob.to_a => [42, :hello, :world]
- DarkWiiPlayer 6y ago> for practical purposes consider it a continuation But it's not though. While coroutines can be used to implement one-shot continuations and vice versa, they are very different features and behave completely differently.
- vidarh 6y agoWhile you're technically right, in terms of using it as a shortcut to give superficial understanding of how Enumerator functions the distinctions are largely irrelevant.
- DarkWiiPlayer 6y ago> “yield 123” or “yield from xyz” is infinitely more clear It's funny because the first is exactly how you write this in ruby.