Example Ruby Code

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}" }

···

--
Posted via http://www.ruby-forum.com/.

Christopher Davidson wrote:

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
marnen@marnen.org

--
Posted via http://www.ruby-forum.com/\.

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

···

On 08.12.2009 18:30, Christopher Davidson wrote:

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}" }

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Hi,

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

···

Am Mittwoch, 09. Dez 2009, 02:30:58 +0900 schrieb Christopher Davidson:

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
*
Discover String#notempty? at <http://raa.ruby-lang.org/project/step&gt;\.

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.

···

On Dec 8, 10:30 am, Christopher Davidson <davidson...@gmail.com> wrote:

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}" }

Marnen Laibow-Koser wrote:

Christopher Davidson wrote:

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
marnen@marnen.org

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?

···

--
Posted via http://www.ruby-forum.com/\.

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.

···

On Tuesday 08 December 2009 03:03:18 pm Christopher Davidson wrote:

Marnen Laibow-Koser wrote:
> Christopher Davidson wrote:
>> 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...

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?