Example Ruby Code

  • Thread starter Christopher Davidson
  • Start date
C

Christopher Davidson

Can anybody explain how this code actually works in simple terms if
possible :).

def animals
yield "Tiger"
yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }
 
M

Marnen Laibow-Koser

Christopher said:
Can anybody explain how this code actually works in simple terms if
possible :).

def animals
yield "Tiger"
yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }

Go read about blocks in Ruby. If you don't understand something once
you've done that, hopefully you'll have a more specific question to
ask...

Best,
-- 
Marnen Laibow-Koser
http://www.marnen.org
(e-mail address removed)
 
R

Robert Klemme

Can anybody explain how this code actually works in simple terms if
possible :).

def animals
yield "Tiger"
yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }

The code defines a method "animals" which accepts an anonymous callback
function (the block). That callback is invoked via "yield" and
arguments to "yield" are passed to the block.

Kind regards

robert
 
B

Bertram Scharpf

Hi,

Am Mittwoch, 09. Dez 2009, 02:30:58 +0900 schrieb Christopher Davidson:
Can anybody explain how this code actually works in simple terms if
possible :).

def animals
yield "Tiger"
yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }

That's short for

def animals &block
block.call "Tiger"
block.call "Giraffe"
end

b = proc { |x| puts "Hello, #{x}" }
animals &b

Bertram
 
P

Phrogz

Can anybody explain how this code actually works in simple terms if
possible :).

def animals
  yield "Tiger"
  yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }

In case you know JavaScript, and are comfortable with functions as
first-class values, you might write this as:

function animals( doSomething )
{
doSomething( "Tiger" );
doSomething( "Giraffe" );
}

animals( function(x){ console.log( "Hello, %s", x ) } );

//or more explicitly
var myLogger = function(x){
console.log( "Hello, %s", x );
}
animals( myLogger );


As Robert said, the notation for "blocks" in Ruby defines an anonymous
callback, and yield invokes it. As Bertram points out, there is an
alternate way of defining a method so that the block is explicitly
associated with a variable.
 
C

Christopher Davidson

Marnen said:
Go read about blocks in Ruby. If you don't understand something once
you've done that, hopefully you'll have a more specific question to
ask...

Best,
-- 
Marnen Laibow-Koser
http://www.marnen.org
(e-mail address removed)

I read about Blocks and thought I understood this quite well, I
understand how this is working nearly, the only thing I don't understand
is how the |x| can be calling the defined yields earlier? Is |x| a
special scenario?
 
D

David Masover

I read about Blocks and thought I understood this quite well, I
understand how this is working nearly, the only thing I don't understand
is how the |x| can be calling the defined yields earlier? Is |x| a
special scenario?

No, that's not what's happening.

If you understand the Javascript example Phrogz gave, go with that. I'm going
to try an example in Ruby...

A block is a block of code. It's like a function or a method, only it's not
tied to anything yet. Let's rework this example. I'm going to show you a step-
by-step reworking, from stuff I'm guessing everyone already knows, to this.
Since I have no idea how much you know, I'm not going to explain too much, so
stop me where you get confused:


def say_hello(x)
puts "Hello, #{x}"
end

def animals
say_hello "Tiger"
say_hello "Giraffe"
end


Just a simple method. If you understand how animals works, you should
understand how say_hello works in the above.


SayHello = proc {|x|
puts "Hello, #{x}"
}

def animals
SayHello.call "Tiger"
SayHello.call "Giraffe"
end


Here, SayHello is just a global constant which holds that proc. You can see
where it's kind of like a method, but not really. You can't just do
SayHello("Tiger"), you have to do SayHello.call("Tiger").

But if you know what constants are, you know it can also be a variable:


def animals(block)
block.call "Tiger"
block.call "Giraffe"
end

say_hello = proc {|x|
puts "Hello, #{x}"
}

animals(say_hello)


That's still doing the same thing, but using a variable instead of a constant.
And of course, you could do that last part shorter:

say_hello = proc {|x| puts "Hello, #{x}" }
animals(say_hello)

And why do you need to assign it to a variable? You can just pass it in:

animals(proc {|x| puts "Hello, #{x}" })

So where are we?


def animals(block)
block.call "Tiger"
block.call "Giraffe"
end

animals(proc {|x| puts "Hello, #{x}" })


Ruby actually has a little bit of syntactic sugar here, which Bertram Scharpf
showed you. Let's take a step back:


def animals(block)
block.call "Tiger"
block.call "Giraffe"
end

say_hello = proc {|x| puts "Hello, #{x}" }
animals(say_hello)


Now, it turns out that the following is almost exactly the same:


def animals(&block)
block.call "Tiger"
block.call "Giraffe"
end

say_hello = proc {|x| puts "Hello, #{x}" }
animals(&say_hello)


The difference is, that ampersand is telling Ruby that this is _the_ block for
the animals function. That means you can make it a lot shorter:


def animals
yield "Tiger"
yield "Giraffe"
end

say_hello = proc {|x| puts "Hello, #{x}" }
animals(&say_hello)


You're almost there -- see, those yields are just block.call. And the block is
still there inside animals, it's just invisible. And the final step is just:


def animals
yield "Tiger"
yield "Giraffe"
end

animals {|x| puts "Hello, #{x}" }


See, when you call animals that way, it uses that block as the default block.
And when you call yield, you're calling the default block.


Now, I lied. It'll actually be a lambda, not a proc. But proc is close enough,
it makes sense here, and it's shorter to write.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top