Ruby Blocks
What is a block?
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.
Lambda method
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
Difference between lambda and Proc.new
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.
yield within a method
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
block_given? method defined in Ruby Kernel module
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
Method definitions’ parameters can specify a block and assign it to a variable
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.
Passing an array of arguments to a block
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 argumentRuby Blocks,