Newbie Question: Blocks and Parameters

Hi Guys,

Please have patience with my possibly basic basic question. I am
learning Ruby and studying blocks/closures right now and confused
without being able to find an answer. I was studying and first came
across this example

[1,2,3].each {|x| puts "This is #{x}. "}

and this makes sense to me I believe. for each object (which is
integers 1, 2, 3), it runs the {} block code, passing in the integer
objects in as variable 'x', then puts out the string including the 'x'
variable.

Now what gets me confused is once I get to these following examples:

class MyClass
  def command1()
    yield(Time.now)
  end
end

m = MyClass.new
m.command1() {|x| puts "Current time is #{x}"}

In the above example, how does 'x' get the Time.now value? In the first
code I have above, 'x' becomes the actual integer object (1, 2, and 3).
So in this case, how does the 'x' variable in this block code get the
Time.now value when executed through yield?

I hope my question even makes sense. I'm hoping by asking I can clarify
any mistaken ideas I have on blocks/closures.

···

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

You can pass any function a block, whether it will use it, or not. In
order to execute the block passed to a function, that function must
call yield. The arguments to yield get passed in as arguments to the
block.

Going back to your first example. A possible implementation of .each

class Array
  def each
    x=0
    while x<self.size
      yield(self)
      x+=1
    end
  end
end

Thus, in this example calling each calls yield passing in one at a time
each member of the array. Thus your block gets excuted once for each
member of the array. Does that help? I'm not sure how to explain it
better.

···

-----Original Message-----
From: derekwrobel@gmail.com [mailto:derekwrobel@gmail.com]
Please have patience with my possibly basic basic question. I am
learning Ruby and studying blocks/closures right now and confused
without being able to find an answer. I was studying and first came
across this example

[1,2,3].each {|x| puts "This is #{x}. "}

and this makes sense to me I believe. for each object (which is
integers 1, 2, 3), it runs the {} block code, passing in the integer
objects in as variable 'x', then puts out the string including the 'x'
variable.

Now what gets me confused is once I get to these following examples:

class MyClass
  def command1()
    yield(Time.now)
  end
end

m = MyClass.new
m.command1() {|x| puts "Current time is #{x}"}

In the above example, how does 'x' get the Time.now value? In the
first
code I have above, 'x' becomes the actual integer object (1, 2, and 3).
So in this case, how does the 'x' variable in this block code get the
Time.now value when executed through yield?

Your definition of command1 depends on an implicit rather than explicit block parameter. The implicit block parameter is called by the yield keyword. An alternative definition of command1 that uses an explicit block parameter would be:

class MyClass
  def command1(&block)
    block.call(Time.now)
  end
end

There is a small penalty for using an explicit block parameter as the implicit block must be wrapped up in a Proc object and bound to the formal parameter rather remaining implicit. The implicit form is most often used when the block is invoked during the execution of the method whereas the explicit form is more common when the block is going to be stored to be called at some later time (such as with callbacks).

Gary Wright

···

On Dec 14, 2009, at 8:15 PM, Derek Michael wrote:

Now what gets me confused is once I get to these following examples:

class MyClass
def command1()
   yield(Time.now)
end
end

m = MyClass.new
m.command1() {|x| puts "Current time is #{x}"}

In the above example, how does 'x' get the Time.now value? In the first
code I have above, 'x' becomes the actual integer object (1, 2, and 3).
So in this case, how does the 'x' variable in this block code get the
Time.now value when executed through yield?

Walton Hoops wrote:

Going back to your first example. A possible implementation of .each

class Array
  def each
    x=0
    while x<self.size
      yield(self)
      x+=1
    end
  end
end

Thus, in this example calling each calls yield passing in one at a time
each member of the array. Thus your block gets excuted once for each
member of the array. Does that help? I'm not sure how to explain it
better.

Thanks to the both of you for the explanations. I think I understand
now. I assume you mentioned the 'possible' implementation of .each
method to imply to me that the each method must have a yield in it since
it does something when you pass a block/closure, yes?

···

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

Correct. The each method (which in MRI is probably implemented in C)
yields values to the block. Walton provided a possible implementation
in Ruby of the each method to show you the possible internal logic of
each: go through the elements of the array and yield them to the block
one at a time.

In Ruby all methods can receive a block. They can use it without
having to "declare" it if you use the yield keyword. If you want to
explicitly refer to it, you need to "declare" it in the argument list,
as Gary showed:

def m(arg1, arg2, &blk)
# do something with blk
end

As Gary said, you usually use the explicit version when you want to
store the block for later use, and use yield in the other cases. For
example:

class Callback
def initialize &blk
@callback = blk
end
def random
n = rand(100)
@callback.call(n)
end
end

irb(main):033:0> c = Callback.new {|rnd| puts "a random number is #{rnd}"}
=> #<Callback:0xb7d10f44 @callback=#<Proc:0xb7d11098@(irb):33>>
irb(main):034:0> c.random
a random number is 26
=> nil
irb(main):035:0> c.random
a random number is 73
=> nil

Calling the random method will use the block provided when
constructing the object as a callback.

Jesus.

···

On Tue, Dec 15, 2009 at 8:29 AM, Derek Michael <derekwrobel@gmail.com> wrote:

Walton Hoops wrote:

Going back to your first example. A possible implementation of .each

class Array
def each
x=0
while x<self.size
yield(self)
x+=1
end
end
end

Thus, in this example calling each calls yield passing in one at a time
each member of the array. Thus your block gets excuted once for each
member of the array. Does that help? I'm not sure how to explain it
better.

Thanks to the both of you for the explanations. I think I understand
now. I assume you mentioned the 'possible' implementation of .each
method to imply to me that the each method must have a yield in it since
it does something when you pass a block/closure, yes?

Thanks guys. I think I'm slowly wrapping my head around this.

Now sort of in the lines of the callback you mentioned, I started
reading about the & operator and being able to convert blocks to procs
and vice versa.

Here is an example of the code I was reviewing:

puts "----Define a method which takes block as a Proc object argument"
def my_method(count, &my_block)
  value = 1

  # Execute the block "count" times while updating the vlaue i
  1.upto(count) do |i|
    value = value * i
    my_block.call(i, value)
  end

end

puts "----Invoke the method passing a code block"
my_method(5) {|i, result| puts "my_method(#{i}) = #{result} "}

So in this case, the variable 'i' gets the value of variable 'count'
assigned to it when executing the upto method which invokes a yield? Am
I understanding this correctly? It took me a while looking at that code
again, to understand where the 'i' was getting it's value...

···

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

There are two 'i' in your code. The one inside my_method, which is the
block param for the block passed to the upto method, will get each
value from 1 to count in each iteration, because that is what upto
yields to the block. The 'i' outside, the one which is a block param
of the block passed to mymethod, will get the same value in each
iteration, since you are calling it with the same 'i' that upto
yields. So it will get 1,2,3,4 and 5.

The example is a little bit contrived, if you are wrapping your head
around yielding, blocks, etc. Try with simpler examples first:

def my_method(&my_block)
  my_block.call(55)
end

my_method {|x| puts x} #=> 55

def my_method(&my_block)
  1.upto(5) do |i|
    my_block.call(i)
  end
end

my_method {|number| puts number} #=> 1 2 3 4 5

BTW, the above are "equivalent" to this:

def my_method
  yield 55
end

and

def my_method
  1.upto(5) do |i|
    yield i
  end
end

which for this simple cases I prefer. I usually use the &blk form when
I want to store the block for later use.

Jesus.

···

On Fri, Dec 18, 2009 at 11:19 PM, Derek Michael <derekwrobel@gmail.com> wrote:

Thanks guys. I think I'm slowly wrapping my head around this.

Now sort of in the lines of the callback you mentioned, I started
reading about the & operator and being able to convert blocks to procs
and vice versa.

Here is an example of the code I was reviewing:

puts "----Define a method which takes block as a Proc object argument"
def my_method(count, &my_block)
value = 1

# Execute the block "count" times while updating the vlaue i
1.upto(count) do |i|
value = value * i
my_block.call(i, value)
end

end

puts "----Invoke the method passing a code block"
my_method(5) {|i, result| puts "my_method(#{i}) = #{result} "}

So in this case, the variable 'i' gets the value of variable 'count'
assigned to it when executing the upto method which invokes a yield? Am
I understanding this correctly? It took me a while looking at that code
again, to understand where the 'i' was getting it's value...

Thank you so much Jesus, and the others who commented. You all have
helped tremendously! I really didn't want to move onto RoR until I
completely understood the basics of Ruby and I think I'm getting there
finally!

···

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