[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

yield vs. return

klochner

1/28/2009 8:09:00 PM

I couldn't find any meaty discussions on this topic, so maybe it's
worth a post.

Does it make sense to use yield at the end of a function, where you're
essentially
using yield to replace a return value? For example:

def returnfoo
return foo
end

vs.

def yieldfoo
yield foo
end

I see a lot of ruby programmers doing the latter, but consider the
former to
be more straightforward. There are a lot of cases where yielding is
more elegant
than return, but I don't consider this to be one of them. Anyone care
to weigh in?
5 Answers

Stefano Crocco

1/28/2009 8:22:00 PM

0

Alle mercoled=EC 28 gennaio 2009, klochner ha scritto:
> I couldn't find any meaty discussions on this topic, so maybe it's
> worth a post.
>
> Does it make sense to use yield at the end of a function, where you're
> essentially
> using yield to replace a return value? For example:
>
> def returnfoo
> return foo
> end
>
> vs.
>
> def yieldfoo
> yield foo
> end
>
> I see a lot of ruby programmers doing the latter, but consider the
> former to
> be more straightforward. There are a lot of cases where yielding is
> more elegant
> than return, but I don't consider this to be one of them. Anyone care
> to weigh in?

yield and return do completely different things, and you can't use one in=20
place of the other. return tells ruby to stop executing the method and retu=
rn=20
its argument to the caller. yield tells ruby to call the block passed to th=
e=20
method, giving it its argument. yield will produce an error if the method=20
wasn't called with a block:

def test_yield
yield 43
end
test_yield # notice that no block was passed to the method
=3D> LocalJumpError: no block given

In ruby, there's no need to put a return at the end of a method, as the met=
hod=20
will always return the value of the last expression. This means that a meth=
od=20
defined this way:

def test_return
return 4
end

will give exactly the same result as a method defined this way:

def test_no_return
4
end

Can you give an example of a situation where you think yield is used in pla=
ce=20
of return? This way, we'll be able to understand better what you're referri=
ng=20
to and make more useful comments.

Stefano

klochner

1/28/2009 8:39:00 PM

0

On Jan 28, 3:21 pm, Stefano Crocco <stefano.cro...@ali
> Can you give an example of a situation where you think yield is used in place
> of return? This way, we'll be able to understand better what you're referring
> to and make more useful comments.
>
> Stefano

The calling code would need to be modified to work with yield vs.
return.

Here's a slightly different example, because I see this a lot with
multivariate return values:

##return style, with calling code below
def returnfoo
return foo1,foo2
end
a,b = returnfoo
puts a; puts b

vs.

##yield style, with calling code below
def yieldfoo
yield foo1, foo2
end
yieldfoo {|a,b| puts a; puts b }


What I'm getting at is that I see ruby programmers use yield to
essentially return values to the caller, the distinction being whether
the block is executed by the caller or by the method (returnfoo/
yieldfoo). It could be done either way because no operations are
performed by the method after the yield.

F. Senault

1/28/2009 9:04:00 PM

0

Le 28 janvier 2009 à 21:09, klochner a écrit :

> I see a lot of ruby programmers doing the latter, but consider the
> former to be more straightforward. There are a lot of cases where
> yielding is more elegant than return, but I don't consider this to
> be one of them. Anyone care to weigh in?

Depends on what you do with it. I kinda like to use yield in "builder"
statements where the code will we nested.

For instance, something like (completely random example) :

box.contents do |c|
c.title = "Blah"
c.font = "Courier"
c.color = "Blue"
c.para do |t|
t.text = "This is blahblah"
t.color = "Black"
end
end

While you could do something like :

c = box.contents
c.title = "Blah"
c.font = "Courier"
c.color = "Blue"
t = c.para
t.text = "This is blahblah"
t.color = "Black"

(The code behind the 'para' method would probably just be 'yield @para'
or 'yield Para.new(self)'.)

The best (IMHO) is, of course, the freedom of :

def funcfoo
yield foo if block_given?
foo
end

Where you can nest or assign.

Fred
--
Hey God, I really don't know what you mean (Nine Inch Nails,
Seems like salvation comes only in our dreams Terrible Lie)
I feel my hatred grow all the more extreme
Hey God, can this world really be as sad as it fucking seems ?

klochner

1/28/2009 9:25:00 PM

0

On Jan 28, 4:04 pm, "F. Senault" <f...@lacave.net> wrote:
> Le 28 janvier 2009 à 21:09, klochner a écrit :
>
> > I see a lot of ruby programmers doing the latter, but consider the
> > former to be more straightforward.  There are a lot of cases where
> > yielding is more elegant than return, but I don't consider this to
> > be one of them.  Anyone care to weigh in?
>
> Depends on what you do with it.  I kinda like to use yield in "builder"
> statements where the code will we nested.
>
> The best (IMHO) is, of course, the freedom of :
>
> def funcfoo
>   yield foo if block_given?
>   foo
> end


thanks Fred, this sounds sane to me.

Robert Klemme

1/29/2009 8:31:00 AM

0

2009/1/28 klochner <klochner@gmail.com>
>
> On Jan 28, 3:21 pm, Stefano Crocco <stefano.cro...@ali
> > Can you give an example of a situation where you think yield is used in place
> > of return? This way, we'll be able to understand better what you're referring
> > to and make more useful comments.
> >
> > Stefano
>
> The calling code would need to be modified to work with yield vs.
> return.
>
> Here's a slightly different example, because I see this a lot with
> multivariate return values:
>
> ##return style, with calling code below
> def returnfoo
> return foo1,foo2
> end
> a,b = returnfoo
> puts a; puts b
>
> vs.
>
> ##yield style, with calling code below
> def yieldfoo
> yield foo1, foo2
> end
> yieldfoo {|a,b| puts a; puts b }
>
>
> What I'm getting at is that I see ruby programmers use yield to
> essentially return values to the caller, the distinction being whether
> the block is executed by the caller or by the method (returnfoo/
> yieldfoo). It could be done either way because no operations are
> performed by the method after the yield.

IMHO that would be a bad use case for /yield/. The power of /yield/
comes from the fact that the method is in control _when_ and _how
often_ it invokes /yield/ and _what_ it passes on. Basically your
block is an anonymous callback function. For methods that simply do a
computation that does not need adjustment by custom code (the
callback) using /return/ is the most appropriate method.

Since with /yield/ the method is in control another typical idiom is
safe cleanup:

def x
yield 123
ensure
cleanup
end

File.open with block works that way.

Kind regards

robert



--
remember.guy do |as, often| as.you_can - without end