Ruby Blocks

A block allows you to pass another function to a function (method) as an argument.
A block can only be passed in as a method argument. A block is a nameless function.

The lambda method is defined in Kernel module and returns a Proc object. A block can be passed as an argument to the lambda method.

You can assign this lambda method to a variable, like this:

irb(main):006:0> print_subject = lambda {|subject| puts subject }
=> #

irb(main):008:0> print_subject.call('Ruby')
Ruby
=> nil

irb(main):009:0> print_subject.class
=> Proc

According to the Ruby docs, lambda method is “Equivalent to Proc.new, except the resulting Proc objects check the number of parameters passed when called.”

When using Proc.new instead of lambda, if there are more arguments passed into the ‘call’ method than the block expects, those arguments are ignored; If there are less arguments passed into the ‘call’ method than the block expects, the rest of the block’s arguments are assigned nil values.

When you call ‘yield’ within a method which passes a block as an argument, the block passed as an argument to the method, gets invoked.

When a block is appended to a method call, it is automatically converted to a Proc object. The yield allows the method to access this Proc.

def method_with_block
  puts "in method"
  yield('1')
end

method_with_block { |num| puts "in block where #{num} was passed into block argument" }

The above prints:

in method
in block where 1 was passed into block argument

You can pass blocks to methods by using do.. end.. instead of { }.
For example, you can do this instead:

method_with_block do |num|
  puts "in block where #{num} was passed into block argument"
end

Within a method, you can determine if a block was passed into that method with block_given?
See http://ruby-doc.org/core/classes/Kernel.html#M005924

You can define a method, specify that it takes a block as an argument and assign that block to any variable you like by doing:

def some_method(&block)
  block.call
end

some_method { puts 'Hello' }

The above prints:

Hello

The &block argument has to be the last argument to the method, however.

def some_method(*args, &block)
  args.each do |a|
    block.call(a)
  end
end

some_method(1,3,5,7,9,11) { |a| puts "in block where #{a} was passed into block argument" }

The above prints the following to the screen:

in block where 1 was passed into block argument
in block where 3 was passed into block argument
in block where 5 was passed into block argument
in block where 7 was passed into block argument
in block where 9 was passed into block argument
in block where 11 was passed into block argument
VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)
Facebook Twitter Email

Leave a Reply