RESULT:
0:10
0:30 # This result was not expected
1:10
1:20
1:30
2:10
2:20
2:30
My question is, why, when using the second method, does the “break” not seem
to break completely out of the loop, but rather acts like a “next” by
terminating the current unit of iteration. I would not expect to get the
"0:30" result. I was under the impression that block.call/yeild were
synonymous.
In message “Re: block.call vs. yield” on 03/04/25, Yukihiro Matsumoto matz@ruby-lang.org writes:
I noticed that the use of block/yield differs slightly when a “break” is
called in the code.
You’ve found something unnatural. Let me examine.
As a conclusion, you will have compatible behavior when you use
blk.yield (new method in 1.8) instead of blk.call. Fix will be
available soon on the CVS.
As a conclusion, you will have compatible behavior when you use
blk.yield (new method in 1.8) instead of blk.call.
···
----- Original Message -----
From: “Yukihiro Matsumoto” matz@ruby-lang.org
I’m sorry… I don’t understand. Will blk.yield do the same thing that
yield did? Is blk.call going away, or will it still do something different
from yield? And finally, what is the difference between blk.call and
blk.yield?
I noticed that the use of block/yield differs slightly when a “break” is
called in the code.
You’ve found something unnatural. Let me examine.
As a conclusion, you will have compatible behavior when you use
blk.yield (new method in 1.8) instead of blk.call. Fix will be
available soon on the CVS.
Language comment:
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
David
···
On Fri, 25 Apr 2003, Yukihiro Matsumoto wrote:
In message “Re: block.call vs. yield” > on 03/04/25, Yukihiro Matsumoto matz@ruby-lang.org writes:
----- Original Message -----
From: “Yukihiro Matsumoto” matz@ruby-lang.org
As a conclusion, you will have compatible behavior when you use
blk.yield (new method in 1.8) instead of blk.call.
I’m sorry… I don’t understand. Will blk.yield do the same thing that
yield did? Is blk.call going away, or will it still do something different
from yield? And finally, what is the difference between blk.call and
blk.yield?
It’s documented in the new ri (basically parameter passing conventions)
Invokes the block, setting the block's parameters to the values in
params using something close to method calling semantics. Returns
the value of the last expression evaluated in the block. See also
Proc#yield.
a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
a_proc[9, 1, 2, 3] #=> [9, 18, 27]
a_proc = Proc.new {|a| a}
a_proc.call(1,2,3) #=> [1, 2, 3]
call checks the number of parameters matches that in the call.
a_proc = Proc.new {|a,b| a}
a_proc.call(1,2,3)
produces:
prog.rb:1: wrong number of arguments (3 for 2) (ArgumentError)
from prog.rb:1:in `call'
from prog.rb:2
Invokes the block, setting the block's parameters to the values in
params using yield semantics (closer to those of parallel
assignment). Returns the value of the last expression evaluated in
the block. See also Proc#call.
a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
a_proc = Proc.new {|a| a}
a_proc.yield(1,2,3) #=> [1, 2, 3]
a_proc = Proc.new {|a,b| a}
a_proc.yield(1,2,3) #=> 1
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
Sorry I don’t understand. Do you mean you don’t want a method with
reserved word name?
Could you restate your statement?
matz.
p.s.
Wish I were born in English speaking country.
I now see what David is saying. I had failed to
read all of the thread.
I agree, ‘yield’ as a method name is not ideal.
Perhaps ‘invoke’ – although that is not mentally
associated with ‘yield’ nor is it mentally
distant enough from ‘call’.
I think those are the two real difficulties in
naming this method: 1. We want people to know
it has the semantics of yield; 2. We want them
to know it is different from call.
As a conclusion, you will have compatible behavior when you use
blk.yield (new method in 1.8) instead of blk.call. Fix will be
available soon on the CVS.
Language comment:
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
Sorry I don’t understand. Do you mean you don’t want a method with
reserved word name?
What I got from David’s comment, and what the word ‘yield’ suggests to me,
is that a block itself does not yield, but rather a block is executed because
some other process has opted to yield process control.
For example, when driving in the States (and I imagine there is something
similar elsewhere) there are signs that say, ‘Yield’, meaning one driver
must pause and allow other drivers to proceed. The pausing driver
is the one processing the ‘yield’ message, rather than those drivers given
the go-ahead.
Could you restate your statement?
matz.
p.s.
Wish I were born in English speaking country.
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
Sorry I don’t understand. Do you mean you don’t want a method with
reserved word name?
Could you restate your statement?
matz.
p.s.
Wish I were born in English speaking country.
That’s OK. Sometimes we wish we were born in a Japanese speaking country
so we could read all those Ruby books & docs you have over there.
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
Sorry I don’t understand. Do you mean you don’t want a method with
reserved word name?
Could you restate your statement?
The follow-ups captured most of my meaning, but I’ll follow up myself
anyway.
In a ‘yield’, the block is being yielded to – it is not, itself,
yielding control. Therefore, what you’d really need, to describe a
yield in terms of the block as a receiver, would be something like:
blk.be_yielded_to
which I’m not advocating, of course; it’s just that
blk.yield
suggests that the block is performing an action described as
'yield’ing, which I don’t think it is.
Also, the use of ‘yield’ as shorthand for ‘call with certain
semantics’ (if I’m understanding that correctly) seems very obscure
to me. This would be very hard to explain to someone learning Ruby
(“The block isn’t actually yielding control; the method is called
‘yield’ because elsewhere in the language there’s something called
‘yield’ that has the same calling semantics…”).
In that regard, to me it has a similar feel to:
proc { |a,*b| … } .def # call proc using arg semantics
# of a method definition
As a conclusion, you will have compatible behavior when you use
blk.yield (new method in 1.8) instead of blk.call. Fix will be
available soon on the CVS.
Language comment:
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
I now see what David is saying. I had failed to
read all of the thread.
I agree, ‘yield’ as a method name is not ideal.
Perhaps ‘invoke’ – although that is not mentally
associated with ‘yield’ nor is it mentally
distant enough from ‘call’.
I think those are the two real difficulties in
naming this method: 1. We want people to know
it has the semantics of yield; 2. We want them
to know it is different from call.
I think that if the semantics of yield are to be generalized, they
should be thought of as something other than the semantics of yield.
It seems to me that the situation is somewhat like this:
type 1 semantics type 2 semantics
> > > >
> > > >
methods Proc#call yield Proc#whatever
in which case, yield and Proc#whatever share semantics, but there’s no
reason (except “historical reasons”) to define them as “yield
semantics”.
I agree that ‘invoke’ is problematic. It’s sort of arbitrary; it is a
different word, but there’s no reason to favor the idea that it
differs in a particular way from call.
Maybe something like call_with_… or call_as… ? (Not sure what the
… would be.)
I’m sorry… I don’t understand. Will blk.yield do the same thing that
yield did? Is blk.call going away, or will it still do something
different
from yield? And finally, what is the difference between blk.call and
blk.yield?
It’s documented in the new ri (basically parameter passing conventions)
Maybe I’m just slower than usual… but I still don’t get it.
I understand the difference in parameter passing conventions between call
and yield. No problem there. My question is this: How were parameter
passing conventions causing the behavior in the original post?
‘yield’ as a method name for blocks strikes me as awkward. In the
past I’ve never thought of 'yield’ing as an action performed by
blocks, nor as something they’re asked to do; it’s more that they are
executed because they get control because a ‘yield’ has already
happened.
Sorry I don’t understand. Do you mean you don’t want a method with
reserved word name?
What I got from David’s comment, and what the word ‘yield’ suggests to me,
is that a block itself does not yield, but rather a block is executed
because
some other process has opted to yield process control.
For example, when driving in the States (and I imagine there is something
similar elsewhere) there are signs that say, ‘Yield’, meaning one driver
must pause and allow other drivers to proceed. The pausing driver
is the one processing the ‘yield’ message, rather than those drivers given
the go-ahead.
Just to throw in my opinion: I’m not sure this
is what David was saying, but the use of the
word ‘yield’ was counter-intuitive to me when
I was learning Ruby.
I thought it was used in the sense of “produce” –
yield a result, produce a result. So I expected
to be like a “return” statement. I would have
chosen a word like “invoke” instead.
But I think the rationale is that you “yield”
control to the block you are calling, which
then returns control. So it’s “yield” as in
a multiprocessing context. I would guess that
is how CLU came to use that term, and I guess
Ruby got it from CLU. (I’m only going by
hearsay.)
In a ‘yield’, the block is being yielded to – it is not, itself,
yielding control. Therefore, what you’d really need, to describe a
yield in terms of the block as a receiver, would be something like:
blk.be_yielded_to
which I’m not advocating, of course; it’s just that
blk.yield
suggests that the block is performing an action described as
'yield’ing, which I don’t think it is.
Also, the use of ‘yield’ as shorthand for ‘call with certain
semantics’ (if I’m understanding that correctly) seems very obscure
to me. This would be very hard to explain to someone learning Ruby
(“The block isn’t actually yielding control; the method is called
‘yield’ because elsewhere in the language there’s something called
‘yield’ that has the same calling semantics…”).
Hmm, understandable. It’s not obscure for me at all though.
Actually, as a Japanese, I don’t use the word “yield” for any other
purpose, so that my feeling is far different from yours.
Anyway, what is your opinion to make them better?
Naming is the key of problem solving. If you choose good name, you
will succeed.
I think that if the semantics of yield are to be generalized, they
should be thought of as something other than the semantics of yield.
It seems to me that the situation is somewhat like this:
type 1 semantics type 2 semantics
> > > >
> > > >
methods Proc#call yield Proc#whatever
in which case, yield and Proc#whatever share semantics, but there’s no
reason (except “historical reasons”) to define them as “yield
semantics”.
Iff you can name it a good name.
The name “yield” tells you “how different from #call”. This is
important. Other names (e.g. invoke) tells you the fact it’s
different from #call, but not how.
But there still be possibility for the better name.
p.s.
Wish I were born in English speaking country.
That’s OK. Sometimes we wish we were born in a Japanese speaking country
so we could read all those Ruby books & docs you have over there.
Phil
You know, I’ve often thought that Ruby would not be so good if there
were no language barrier: What better motivation for making it
completely understandable and have so few surprises? Names are well
chosen and not just defended in the documentation. Methods do what
you’d expect, so incomplete docs are less of a hindrance than it might
be otherwise.
I find this to hold particularly true in the ruby core, but the dRb
module is similarly elegant, as are others.
I understand the difference in parameter passing conventions between call
and yield. No problem there. My question is this: How were parameter
passing conventions causing the behavior in the original post?
Because there are 2 differences between #call and #yield : one affect
parameter passing, the other affect the break keyword
···
Sat Jun 23 22:28:52 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
----- Original Message -----
From: dblack@superlink.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Saturday, April 26, 2003 10:13 AM
Subject: Re: block.call vs. yield
Maybe something like call_with_… or call_as… ? (Not sure what the
… would be.)
The method name :yield was immediately intuitive to me, as was the
concept of “yield semantics”. One thing every Ruby programmer must
learn fairly early is the special treatment of arguments to “yield”.
So yes, the only reason for the name is “historical reasons”, but I
can’t imagine a better name appearing.
If you want to take a step back and look for a unifying concept, which
I applaud, then I think the only choice is to abolish “yield
semantics”. The splat (*) operator allows you to achieve the same
result anyway - when you want to.
hash.each do |o|
# Array === o
end
is annoying to some people. They would rather have an error (wrong
number of parameters) than an unexpected value being assigned to the
parameter, and I sympathise. After all…
hash.each do |*o|
# Array === o
end
applies, so why not force intentions to be explicit?
I’m happy to keep “yield” the way it is.
Gavin
···
On Sunday, April 27, 2003, 1:13:40 AM, dblack wrote:
I think that if the semantics of yield are to be generalized, they
should be thought of as something other than the semantics of yield.
It seems to me that the situation is somewhat like this:
type 1 semantics type 2 semantics
> > > >
> > > >
methods Proc#call yield Proc#whatever
in which case, yield and Proc#whatever share semantics, but there’s no
reason (except “historical reasons”) to define them as “yield
semantics”.