Yield example baffling - need help

I'm studying the yield statement for the first time, today.

All's well until I see this example:

def myeach(myarray)
iter = 0
while (iter < myarray.length):
yield(myarray[iter])
iter += 1
end

testarray = [1,2,3,4,5]
myeach(testarray) {|item| print "#{item}:"}
→ 1:2:3:4:5:

I see a method with one parameter. There a block to the right of the method call, inexplicably. It would make sense if some iteration were going on, but I don't see that at all. One call, one execution (with a loop), and we're out. What does "item" have to count through?

How can that yield do anything? How does it know about the block? It's not passed in. The iteration appears to be happening IN the method, using a block it cannot possibly see. Ouch! After some minutes, I'm not getting this at all.

Can anyone clear my head for me. I've never seen anything like this. Or is it just a weird Ruby idiom I'll just have to accept?

Thanks in advance.

Tom

···

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tom Cloyd, MS MA, LMHC - Private practice Psychotherapist
Bellingham, Washington, U.S.A: (360) 920-1226
<< tc@tomcloyd.com >> (email)
<< TomCloyd.com >> (website) << sleightmind.wordpress.com >> (mental health weblog)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tom Cloyd wrote:

I'm studying the yield statement for the first time, today.

All's well until I see this example:

def myeach(myarray)
iter = 0
while (iter < myarray.length):
yield(myarray[iter])
iter += 1
end

testarray = [1,2,3,4,5]
myeach(testarray) {|item| print "#{item}:"}
→ 1:2:3:4:5:

I see a method with one parameter. There a block to the right of the method call, inexplicably. It would make sense if some iteration were going on, but I don't see that at all. One call, one execution (with a loop), and we're out. What does "item" have to count through?

How can that yield do anything? How does it know about the block? It's not passed in. The iteration appears to be happening IN the method, using a block it cannot possibly see. Ouch! After some minutes, I'm not getting this at all.

Can anyone clear my head for me. I've never seen anything like this. Or is it just a weird Ruby idiom I'll just have to accept?

Thanks in advance.

Tom

Arrgh. What a dolt. I just realized that ALL the yield examples I've been studying have this block sitting over to the right - I was converting the curly braces to parens in my mind, and so didn't see them. It IS idiomatic weirdness. I yield to higher wisdom.

t.

···

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tom Cloyd, MS MA, LMHC - Private practice Psychotherapist
Bellingham, Washington, U.S.A: (360) 920-1226
<< tc@tomcloyd.com >> (email)
<< TomCloyd.com >> (website) << sleightmind.wordpress.com >> (mental health weblog)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hi --

I'm studying the yield statement for the first time, today.

All's well until I see this example:

def myeach(myarray)
iter = 0
while (iter < myarray.length):
yield(myarray[iter])
iter += 1
end

testarray = [1,2,3,4,5]
myeach(testarray) {|item| print "#{item}:"}
→ 1:2:3:4:5:

I see a method with one parameter. There a block to the right of the method call, inexplicably. It would make sense if some iteration were going on, but I don't see that at all. One call, one execution (with a loop), and we're out. What does "item" have to count through?

How can that yield do anything? How does it know about the block? It's not passed in. The iteration appears to be happening IN the method, using a block it cannot possibly see. Ouch! After some minutes, I'm not getting this at all.

Can anyone clear my head for me. I've never seen anything like this. Or is it just a weird Ruby idiom I'll just have to accept?

I don't think it's weird, and I'd encourage you not to feel glum about
having to accept it. It's actually very elegant and cool.

The block, like the argument list, is a syntactic construct, part of
the method call. It is not, however, an argument; as you say, it is
not passed in (though you can "capture" it in a variable if needed).
It represents an anonymous function that is being made available for
execution, via yield, to the method.

When you say the method can't possibly see the block, you're assuming
that in a state of nature, methods can receive arguments but can't see
code blocks :slight_smile: Of course none of it happens except because of how
it's engineered, and the code block is part of the engineering, just
like the argument list.

David

···

On Thu, 15 Jan 2009, Tom Cloyd wrote:

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2\)

http://www.wishsight.com => Independent, social wishlist management!

Tom Cloyd wrote:

How can that yield do anything? How does it know about the block? It's
not passed in. The iteration appears to be happening IN the method,
using a block it cannot possibly see. Ouch! After some minutes, I'm not
getting this at all.

Maybe it's clearer if you rewrite myeach to show explicitly the block
being passed in, and being called.

def myeach(myarray, &block) # <<<
iter = 0
while (iter < myarray.length):
block.call(myarray[iter]) # <<<
iter += 1
end
end

Even if there is no &foo in the argument list, you can still pass a
block when you call the method. The method can call it anonymously using
'yield', and test for its presence using 'block_given?' (*)

BTW, Proc# is an alias for Proc#call, so this gives you three choices:

block.call(args) # only if block captured into a variable
block[args] # ditto
yield args

HTH,

Brian.

(*) It's occasionally a source of head-scratching when you pass a block
to a method which doesn't expect one, and so it's silently ignored. Ruby
can't and doesn't warn you of this.

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

Tom Cloyd wrote:

I'm studying the yield statement for the first time, today.

All's well until I see this example:

def myeach(myarray)
iter = 0
while (iter < myarray.length):
yield(myarray[iter])
iter += 1
end

testarray = [1,2,3,4,5]
myeach(testarray) {|item| print "#{item}:"}
→ 1:2:3:4:5:

I see a method with one parameter. There a block to the right of the method call, inexplicably. It would make sense if some iteration were going on, but I don't see that at all. One call, one execution (with a loop), and we're out. What does "item" have to count through?

How can that yield do anything? How does it know about the block? It's not passed in. The iteration appears to be happening IN the method, using a block it cannot possibly see. Ouch! After some minutes, I'm not getting this at all.

Can anyone clear my head for me. I've never seen anything like this. Or is it just a weird Ruby idiom I'll just have to accept?

Thanks in advance.

Tom

Arrgh. What a dolt. I just realized that ALL the yield examples I've been studying have this block sitting over to the right - I was converting the curly braces to parens in my mind, and so didn't see them. It IS idiomatic weirdness. I yield to higher wisdom.

Half the fun, actually, is that while you know what you're yielding,
you never know exactly what you're yielding *to* :slight_smile:

The block construct actually has two common use patterns: iterating
through collections, and yielding "magic pen" objects.[1] An example
of the magic pen is File.open:

   File.open("blah", "w") do |fh|
     fh.puts(whatever)
   end

where the open method, which you never have to see, does the
housekeeping, including closing the file for you. You just get the
magic pen (the file handle). That pattern is, I think, particularly
nice.

David

[1] http://dablog.rubypal.com/2007/2/18/the-magic-pens-of-ruby

···

On Thu, 15 Jan 2009, Tom Cloyd wrote:

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2\)

http://www.wishsight.com => Independent, social wishlist management!

David A. Black wrote:

Hi --

Tom Cloyd wrote:

I'm studying the yield statement for the first time, today.

All's well until I see this example:

def myeach(myarray)
iter = 0
while (iter < myarray.length):
yield(myarray[iter])
iter += 1
end

testarray = [1,2,3,4,5]
myeach(testarray) {|item| print "#{item}:"}
→ 1:2:3:4:5:

I see a method with one parameter. There a block to the right of the method call, inexplicably. It would make sense if some iteration were going on, but I don't see that at all. One call, one execution (with a loop), and we're out. What does "item" have to count through?

How can that yield do anything? How does it know about the block? It's not passed in. The iteration appears to be happening IN the method, using a block it cannot possibly see. Ouch! After some minutes, I'm not getting this at all.

Can anyone clear my head for me. I've never seen anything like this. Or is it just a weird Ruby idiom I'll just have to accept?

Thanks in advance.

Tom

Arrgh. What a dolt. I just realized that ALL the yield examples I've been studying have this block sitting over to the right - I was converting the curly braces to parens in my mind, and so didn't see them. It IS idiomatic weirdness. I yield to higher wisdom.

Half the fun, actually, is that while you know what you're yielding,
you never know exactly what you're yielding *to* :slight_smile:

The block construct actually has two common use patterns: iterating
through collections, and yielding "magic pen" objects.[1] An example
of the magic pen is File.open:

File.open("blah", "w") do |fh|
fh.puts(whatever)
end

where the open method, which you never have to see, does the
housekeeping, including closing the file for you. You just get the
magic pen (the file handle). That pattern is, I think, particularly
nice.

David

[1] http://dablog.rubypal.com/2007/2/18/the-magic-pens-of-ruby

David - very nice! Plus, you made me howl with laughter. Yes, I often cannot see to what I am yielding. And of course, we spend a lifetime approaching the Great Yield. Um...but not tonight, I think!

Thanks for your eloquence.

t.

···

On Thu, 15 Jan 2009, Tom Cloyd wrote:

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tom Cloyd, MS MA, LMHC - Private practice Psychotherapist
Bellingham, Washington, U.S.A: (360) 920-1226
<< tc@tomcloyd.com >> (email)
<< TomCloyd.com >> (website) << sleightmind.wordpress.com >> (mental health weblog)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~