Yield Example in Ruby For Rails book

I am going through the Ruby for Rails book. How do I run the following
code:

class C

def temp_chart(temps)
for temp in temps
converted = yield(temp)
puts “#{temp}\t#{converted}”
end
end

celsiuses = [0,10,20,40]
temp_chart(celsiuses) {|cel| cel * 9 / 5 + 32}

end

c = C.new
c.temp_chart(celsiuses)

I am getting error message:

NoMethodError: undefined method ?temp_chart? for C:Class

at top level in c.rb at line 11

TIA

You probably want

class C
def temp_chart(temps)
for temp in temps
converted = yield(temp)
puts “#{temp}\t#{converted}”
end
end
end

celsiuses = [0,10,20,40]

c = C.new
c.temp_chart(celsiuses)

I probably can’t explain why very well, but eventually Ruby for Rails
will.

Good luck!

When I run that code I get:

LocalJumpError: no block given

method temp_chart in c.rb at line 5
method temp_chart in c.rb at line 4
at top level in c.rb at line 13

That gave me an idea, ha, this looks like some kind_of? class
initialization… :smiley:

class X
def self.ordinary_class_method_is_to(&block)
block.call
end
def ordinary_instance_method_is_to(&block)
block.call
end

 ordinary_class_method_is_to do
     puts 'Buy bags...'
 end

end

x = X.new
x.ordinary_instance_method_is_to do
puts ‘Give away…’
end

Am 07.10.2006 um 09:39 schrieb Bala P.:

Thank you for your explanation. It works!!! I don’t know why any of the
authors who write Ruby
books use Java and the known concepts to learn this new language. It is
much easier to learn that
way.

So this block thingy is kinda like anonymous classes?

Rails for Java developers is in beta, who is writing Ruby for Java
Developers?

Hello, try this:

class C

def temp_chart(temps)
for temp in temps
converted = yield(temp)
puts “#{temp}\t#{converted}”
end
end
end

celsiuses = [0,10,20,40]

c = C.new
c.temp_chart(celsiuses) {|cel| cel * 9 / 5 + 32}

Explanation:
temps is an array argument (supplied here by celsiuses)

the method temp_chart also takes a block of executable code. That is
this:
{|cel| cel * 9 / 5 + 32}
It is this block of code which is executed when yield is used here:
yield(temp)
The block conatains a variable, cel, to which the elements of the
celsiuses array (from the array argument named temps) will be passed,
just like calling a named method with an array argument.

Blocks can be tricky to understand. Just remember that they work a bit
like unnamed functions that can be passed to methods. When the method
receives the block it can call the block using yield. The block
arguments (here cel) are like the formal arguments to a named method.
When yield specifies an argument (here temp) it has the effect of
calling the block and passing to it the named argument.

best wishes
Huw

Ruby In Steel
Ruby P.ming With Visual Studio
http://www.sapphiresteel.com

Hi –

On Sat, 7 Oct 2006, Bala P. wrote:

Thank you for your explanation. It works!!! I don’t know why any of
the authors who write Ruby books use Java and the known concepts to
learn this new language. It is much easier to learn that
way.

Do you mean why they don’t use Java? In my case it’s because I
don’t know Java, and also I really want to write about Ruby. Maybe
I’ll change my mind when someone writes Java for Ruby Developers :slight_smile:

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

I’ll change my mind when someone writes Java for Ruby Developers :slight_smile:

David your book is kinda like a good wine. It is getting better as it
ages on my Mac. I am reading
it the second time slowly and also running the examples. I understood
your explanation about
blocks, scopes etc. But only when I run the examples my brain is able to
fully absorb the material
in the book.

Hi –

On Sat, 7 Oct 2006, Bala P. wrote:

I’ll change my mind when someone writes Java for Ruby Developers :slight_smile:

David your book is kinda like a good wine. It is getting better as
it ages on my Mac. I am reading it the second time slowly and also
running the examples. I understood your explanation about
blocks, scopes etc. But only when I run the examples my brain is
able to fully absorb the material in the book.

That’s fine – it’s all part of it. Running the examples isn’t
“cheating” :slight_smile:

I’m glad you’re liking it.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Bala P. wrote:

So this block thingy is kinda like anonymous classes?

In principle they are anonymous methods rather than classes. If you
think of them like that it should be easier to understand what’s going
on when you pass arguments into them and these arguments initialize the
block variables between the upright bars (like |cel| in the example
above).

Blocks are kind of oddities (in my view!) in Ruby, however, as they
aren’t objects. True, they can be wrapped up inside objects (Procs) but
that doesn’t alter the fact that a block itself has no independent
existence. This contrasts with some other object oriented languages -
notably Smalltalk - in which a block is an object with its own methods.
Ask a standalone Smalltalk block to tell you its class and it will reply
that it is an instance of Block (or BlockClosure). Ask a standalone Ruby
block to tell you its class - e.g.

puts( {|cel| cel * 9 / 5 + 32}.class )

…and Ruby replies:

parse error, unexpected ‘|’, expecting ‘}’
puts( {|cel| cel * 9 / 5 + 32}.class )

However, I may be straying into arcane areas here :wink:

Keep things simple: think of blocks as anonymous methods that can be
‘called’ using ‘yield’ and you won’t go too far wrong.

best wishes
Huw

Ruby In Steel
Ruby P.ming With Visual Studio
http://www.sapphiresteel.com

Hi –

On Sat, 7 Oct 2006, Huw C. wrote:

Bala P. wrote:

So this block thingy is kinda like anonymous classes?

In principle they are anonymous methods rather than classes. If you
think of them like that it should be easier to understand what’s going
on when you pass arguments into them and these arguments initialize the
block variables between the upright bars (like |cel| in the example
above).

Thinking of them as methods has some pitfalls, though, since methods
always live in modules or classes and blocks don’t.

…and Ruby replies:

parse error, unexpected ‘|’, expecting ‘}’
puts( {|cel| cel * 9 / 5 + 32}.class )

However, I may be straying into arcane areas here :wink:

I think the best way to look at blocks is as a part of the syntax of
the Ruby method call:

[receiver dot] method_name [arg_list] [block]

Informally one does speak of blocks as anonymous functions, rather
than saying “a syntactic construct that gets wrapped in a Proc” (or
whatever). But it’s useful to keep the distinction in view that they
start life as syntax.

On that construction, a block is a kind of sibling to the argument
list – and, in both cases, they’re pure syntax: there’s no Block
class and no ArgumentList class. Also in both cases, the method can
grab what’s there and stash it in a variable:

  m(a,b,c) { puts "hi" }
    | | |  |

def m(x,y,z,&block)

In a sense, the &block thing is really a completely separate
transaction from the x,y,z part; it might almost be represented as:

def m(x,y,z) {&block}

or something. (I’m not advocating that, just making the point that
the block and &block are going on in parallel to, rather than as part
of, the passing of arguments.)

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

unknown wrote:

Thinking of them as methods has some pitfalls, though, since methods
always live in modules or classes and blocks don’t.

That’s true. In that case, thinking of them as anonymous functions
might be a better model. Then again, thinking of ‘free-floating’
functions in a rigorously OOP language raises its own problems :wink:

On that construction, a block is a kind of sibling to the argument
list – and, in both cases, they’re pure syntax:

I must say that I have problems with making Ruby’s blocks fit
comfortably into the Ruby universe. The arguments in an argument list
act as the receivers of the arguments passed in the ‘message’ sent to
that method. These formal arguments are therefore, as you say, ‘pure
syntax’. However, the objects to which the arguments are instantiated
are not mere syntax. They have a ‘real’ self-contained existence as
instances of Ruby classes. Blocks, on the other hand, do not have such
an existence.

I must say that I am very much prejudiced in favour of the Smalltalk
version of blocks (instances of a Block or Closure class) as that simply
seems to me to be consistent with the pure OOP paradigm.

That said, Ruby is by no means as strictly object oriented as Smalltalk
(compare its fairly permissive approach to encapsulation, for example),
which possibly explains why blocks are treated in this way.

best wishes
Huw

Ruby In Steel
Ruby P.ming With Visual Studio
http://www.sapphiresteel.com

Hi –

On Sat, 7 Oct 2006, Huw C. wrote:

I must say that I have problems with making Ruby’s blocks fit
comfortably into the Ruby universe. The arguments in an argument list
act as the receivers of the arguments passed in the ‘message’ sent to
that method. These formal arguments are therefore, as you say, ‘pure
syntax’.

I meant the argument list that’s part of the method call (rather than
the method). I should probably be saying parameter instead of
argument or something… but basically the (a,b,c) in meth(a,b,c).

However, the objects to which the arguments are instantiated
are not mere syntax. They have a ‘real’ self-contained existence as
instances of Ruby classes. Blocks, on the other hand, do not have such
an existence.

I must say that I am very much prejudiced in favour of the Smalltalk
version of blocks (instances of a Block or Closure class) as that simply
seems to me to be consistent with the pure OOP paradigm.

I believe that there was a Block class in CVS head two or three years
ago, for about a week :slight_smile: I further remember that its existence had
something to do with my having lobbied for it, though I can’t remember
the sequence in detail. It was a period when there was a lot of
discussion of the weirdnesses of Proc/proc/lambda/block/method. The
discussion doesn’t seem to be as lively any more, though at least some
of the weirdness is still there :slight_smile:

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

I found the fix, the problem is that it was expecting the block: {|cel|
cel * 9 / 5 + 32}
after the name. Now it runs fine.

[email protected] wrote:

In principle they are anonymous methods rather than classes. If you
think of them like that it should be easier to understand what’s going
on when you pass arguments into them and these arguments initialize the
block variables between the upright bars (like |cel| in the example
above).

Thinking of them as methods has some pitfalls, though, since methods
always live in modules or classes and blocks don’t.

This is a very good observation. You said in the book that one of the
advantages of the blocks
is that they can be combined in many ways. I did not find any example of
how you would combine it.

I am not clear on how you would combine it since it is not part of a
class or module.