Assign blocks to variables

If you want to work on a function that takes a block as input, is it
possible to assign the block to a variable?
In other words, how would you parameterize this in irb:

myfunc {
otherfunc { |a|
print a
}
}

On Jul 25, 2010, at 9:00 AM 7/25/10, poseid wrote:

You hand blocks in as a variable to a function by prepending a variable
name with an ampersand:

myfunc(&block)

Is that what you’re looking for?

poseid wrote:

If you want to work on a function that takes a block as input, is it
possible to assign the block to a variable?
In other words, how would you parameterize this in irb:

myfunc {
otherfunc { |a|
print a
}
}

You can assign blocks to variables like this:
irb(main):001:0> b1 = lambda{puts “hello”}
=> #<Proc:[email protected](irb):1 (lambda)>
irb(main):002:0> b1.call
hello
=> nil
irb(main):003:0> b2 = proc{puts “hello”}
=> #Proc:[email protected]:3(irb)
irb(main):004:0> b2.call
hello
=> nil
irb(main):005:0>

Notice that there’s a subtle difference between #proc and #lambda if the
block takes parameters:

irb(main):005:0> b3 = lambda{|arg| p arg}
=> #<Proc:[email protected](irb):5 (lambda)>
irb(main):006:0> b4 = proc{|arg| p arg}
=> #Proc:[email protected]:6(irb)
irb(main):007:0> b3.call(1)
1
=> 1
irb(main):008:0> b4.call(1)
1
=> 1
irb(main):009:0> b3.call
ArgumentError: wrong number of arguments (0 for 1)
from (irb):9:in call' from (irb):9 from /home/marvin/Programmieren/Programme/irb_/irb_.rb:37:in
irb(main):010:0> b4.call
nil
=> nil
irb(main):011:0>

#lambda acts more like a method, checking wheather it was given all
necessary arguments, whereas #proc just assigns nil to parameters that
weren’t provided.

However, to write a function that takes a block you don’t have to take
care about that[*]. There’s the “yield” keyword that invokes a supplied
block and raises a LocalJumpError if no block was supplied.

irb(main):011:0> def foo
irb(main):012:1> yield
irb(main):013:1> end
=> nil
irb(main):014:0> foo{puts “Hello, World!”}
Hello, World!
=> nil
irb(main):015:0>

Additionally, with #block_given? you can check wheather a block has been
supplied.

Marvin

[*] You could define a method like as “def foo(&block)”, than you get a
#proc-ed block in the variable “block”.

On Jul 25, 8:58 am, poseid [email protected] wrote:

If you want to work on a function that takes a block as input, is it
possible to assign the block to a variable?

You can capture a block parameter passed to a method using an
ampersand name at the end. You can pass a proc as a block to a method
by throwing an ampersand before it. There are also other ways to
create a proc value, such as using the ‘proc’ or ‘lambda’ methods, or
the arrow syntax available in 1.9:

def capture_block(&my_block); my_block; end
def with42; yield 42; end
b1 = capture_block{ |n| puts “N is #{n}” }
=> #Proc:[email protected]:3(irb)

with42( &b1 )
N is 42

b2 = proc{ |n| puts “I said, it is #{n}” }
=> #Proc:[email protected]:5(irb)

with42( &b2 )
I said, it is 42

b3 = ->(n){ puts “Oh my #{n}” }
=> #<Proc:[email protected](irb):11 (lambda)>

with42( &b3 )
Oh my 42

#lambda acts more like a method, checking wheather it was given all
necessary arguments, whereas #proc just assigns nil to parameters that
weren’t provided.

Thank you all.
#proc is solving my problem!

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs