Forum: Ruby yield

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Corey K. (Guest)
on 2007-03-17 00:10
this works fine:

def printer()
  yield "ball"
end

printer {|word_one| puts word_one}


but this does not:

def printer(arg)
  yield arg
end

printer("ball")
printer {|word| puts word}

why is that, cant yield be used with arguments?

thanks
Brian C. (Guest)
on 2007-03-17 00:17
(Received via mailing list)
On Sat, Mar 17, 2007 at 07:10:26AM +0900, Corey K. wrote:
>
> def printer(arg)
>   yield arg
> end
>
> printer("ball")
> printer {|word| puts word}
>
> why is that, cant yield be used with arguments?

It can. Your second function 'printer' takes one argument plus one
block.
However in the first case you were calling it without a block, and in
the
second case you were calling it without an argument.

What you need is:

  printer("ball") {|word| puts word}
Matthew M. (Guest)
on 2007-03-17 00:25
(Received via mailing list)
> why is that, cant yield be used with arguments?

It can, but you need to use it correctly:


> def printer(arg)
>   yield arg
> end

Good.


> printer("ball")
> printer {|word| puts word}

Not so good.  Try:

printer("ball") { |word| puts word }
Corey K. (Guest)
on 2007-03-17 00:36
Brian C. wrote:
> On Sat, Mar 17, 2007 at 07:10:26AM +0900, Corey K. wrote:
>>
>> def printer(arg)
>>   yield arg
>> end
>>
>> printer("ball")
>> printer {|word| puts word}
>>
>> why is that, cant yield be used with arguments?
>
> It can. Your second function 'printer' takes one argument plus one
> block.
> However in the first case you were calling it without a block, and in
> the
> second case you were calling it without an argument.
>
> What you need is:
>
>   printer("ball") {|word| puts word}


oh ok, my understanding for some reason was that the method was going to
remmeber that i set arg to "ball" so that when i used printer with the
block that "ball" would still be in arg. So is that why it isnt working,
is because when i call the printer method the second time the value
stored in arg is destroyed?
Chad P. (Guest)
on 2007-03-17 00:42
(Received via mailing list)
On Sat, Mar 17, 2007 at 07:36:21AM +0900, Corey K. wrote:
> >> why is that, cant yield be used with arguments?
>
> oh ok, my understanding for some reason was that the method was going to
> remmeber that i set arg to "ball" so that when i used printer with the
> block that "ball" would still be in arg. So is that why it isnt working,
> is because when i call the printer method the second time the value
> stored in arg is destroyed?

I'm just guessing here, but . . .

It looks like you're expecting something akin to class behavior from a
method.  Perhaps what you want to do is something more like this:

class Printer
  def initialize(arg)
    @arg = arg
  end

  def iterator_thingie
    yield @arg
  end
end

printer = Printer.new("ball")
printer.iterator_thingie {|word| puts word}


Then again, maybe that's not the kind of behavior you want.
Corey K. (Guest)
on 2007-03-17 00:47
Chad P. wrote:
> On Sat, Mar 17, 2007 at 07:36:21AM +0900, Corey K. wrote:
>> >> why is that, cant yield be used with arguments?
>>
>> oh ok, my understanding for some reason was that the method was going to
>> remmeber that i set arg to "ball" so that when i used printer with the
>> block that "ball" would still be in arg. So is that why it isnt working,
>> is because when i call the printer method the second time the value
>> stored in arg is destroyed?
>
> I'm just guessing here, but . . .
>
> It looks like you're expecting something akin to class behavior from a
> method.  Perhaps what you want to do is something more like this:
>
> class Printer
>   def initialize(arg)
>     @arg = arg
>   end
>
>   def iterator_thingie
>     yield @arg
>   end
> end
>
> printer = Printer.new("ball")
> printer.iterator_thingie {|word| puts word}
>
>
> Then again, maybe that's not the kind of behavior you want.

its not that i am looking to get any specific result its that i am
trying to understand what is going on behind the scenes so that i can
understand why what i did, did not work not just that it in fact did not
work.
Corey K. (Guest)
on 2007-03-17 00:58
Chad P. wrote:
> On Sat, Mar 17, 2007 at 07:36:21AM +0900, Corey K. wrote:
>> >> why is that, cant yield be used with arguments?
>>
>> oh ok, my understanding for some reason was that the method was going to
>> remmeber that i set arg to "ball" so that when i used printer with the
>> block that "ball" would still be in arg. So is that why it isnt working,
>> is because when i call the printer method the second time the value
>> stored in arg is destroyed?
>
> I'm just guessing here, but . . .
>
> It looks like you're expecting something akin to class behavior from a
> method.  Perhaps what you want to do is something more like this:
>
> class Printer
>   def initialize(arg)
>     @arg = arg
>   end
>
>   def iterator_thingie
>     yield @arg
>   end
> end
>
> printer = Printer.new("ball")
> printer.iterator_thingie {|word| puts word}
>
>
> Then again, maybe that's not the kind of behavior you want.

what i am basically trying to understand is:

When i do printer("ball") i am putting the string ball in the arg
variable of the printer method.

When i call the printer method with the block afterwards what happened
to my string i stored in arg? Was it destroyed or when i called the
printer method for the second time did ruby create a whole new arg
variable with nothing in it and thats why the way i did it didnt work?
Do you know what i mean i am trying to understand why what i did didnt
work.
Gary W. (Guest)
on 2007-03-17 01:16
(Received via mailing list)
On Mar 16, 2007, at 6:58 PM, Corey K. wrote:
>> Then again, maybe that's not the kind of behavior you want.
>
> what i am basically trying to understand is:
>
> When i do printer("ball") i am putting the string ball in the arg
> variable of the printer method.

Forget the block for a moment.  Your question pertains to method
arguments with or without an associated block.

Next, don't think of a variable as a container ("putting the
string 'ball' in the arg).  Variables are not containers in Ruby
they are names.  Think of sticking a post-it note on 'ball' and
written on the post-it note is 'arg'.

The post-it note gets created and stuck on 'ball' when you
call the method. The post-it note gets removed from 'ball'
when the method returns.  Within the method the identifier
'arg' can be used to identify the string (in this case 'ball').
Outside the method 'arg' is meaningless since the post-it note
labeled 'arg' has been discarded.

When you call a method a second (or third or fourth...) time,
a new post-it note is created and stuck on the object and
'arg' is once again written on the post-it note and can be
used to identify the object you provided.

printer('ball')         # within printer, arg refers to 'ball'
# no post-it note 'arg' between calls to printer
printer('baseball')     # within printer, arg refers to 'baseball'
# no post-it note 'arg' between calls to printer
printer('football')     # within printer, arg refers to 'football'




Gary W.
Chad P. (Guest)
on 2007-03-17 02:13
(Received via mailing list)
On Sat, Mar 17, 2007 at 07:58:15AM +0900, Corey K. wrote:
> > I'm just guessing here, but . . .
> >     yield @arg
>
> When i do printer("ball") i am putting the string ball in the arg
> variable of the printer method.
>
> When i call the printer method with the block afterwards what happened
> to my string i stored in arg? Was it destroyed or when i called the
> printer method for the second time did ruby create a whole new arg
> variable with nothing in it and thats why the way i did it didnt work?
> Do you know what i mean i am trying to understand why what i did didnt
> work.

Methods are not persistent things -- they are actions taken by objects.
When you call a method that you define outside of any class, it's
actually a method of the Self object (basically, a method of your
program).  Because actions do not maintain state (data, variables, what
have you), variables within methods go away when the methods are not in
use.  A method is an ephemeral, fleeting thing.  It's an occurrence, in
a way, rather than a thing.

A method, in fact, is much like a function in that respect (if you're
familiar with functions from other languages).  You put something in,
you get something out.

Blocks can be used to maintain state, but to do so you need to assign
them as objects to some kind of name/variable/thing that is outside of a
method.  That, of course, is because a block returned from a method and
stuck in a variable is basically the same as a closure in any other
language (that supports closures).

Hopefully that helps clear things up for you, and give you a glimpse of
other, sorta related topics in the language.
David A. Black (Guest)
on 2007-03-17 05:52
(Received via mailing list)
Hi --

On 3/16/07, Corey K. <removed_email_address@domain.invalid> wrote:
> >> why is that, cant yield be used with arguments?
>
>
> oh ok, my understanding for some reason was that the method was going to
> remmeber that i set arg to "ball" so that when i used printer with the
> block that "ball" would still be in arg. So is that why it isnt working,
> is because when i call the printer method the second time the value
> stored in arg is destroyed?

The two calls to printer are unrelated to each other. Each of them
uses a local variable 'arg', but they're two different variables.

The code block is, syntactically, part of the method call.  So if
there's no block for a given method call, that's that.


David
Bertram S. (Guest)
on 2007-03-17 07:39
(Received via mailing list)
Am Samstag, 17. Mär 2007, 07:10:26 +0900 schrieb Corey K.:
> def printer(arg)
>   yield arg
> end
>
> printer("ball")
> printer {|word| puts word}

How did you get this working? Both `printer' calls will
fail. Please run your code before you post it or at least
include the error message.

Please don't mind,

Bertram
John J. (Guest)
on 2007-03-17 10:26
(Received via mailing list)
Bertram, some code is not supposed to work.
It is hypothetical, or it is a snippet or the whole thing.
This thread is about structural and conceptual examples of "code
blocks" in Ruby, not actual working code.

though, some working code  might make it more clear for some people,
it is in the pickaxe book
This topic is locked and can not be replied to.