Creating and Calling a Ruby Block
Code Blocks in ruby are only valid when you use it as an argument to a method call. They are not valid blocks in other context.
Blocks can be initialized in several ways which are all equal in things they do and accomplish.
my_block = Proc.new {|item| puts item}
my_block = ->(item){puts item}
my_block = proc{|item| puts item}
my_block = lambda{|item| puts item} //this way of creating a code block act like a method
We can make a call to our block via my_block.call(“Hello World!”). However, the only way you can get method like behavior from the code blocks specified above is by creating it with lambda expression.
Code Blocks are easy to call and they can be passed to any method without too much hassle. We can pass code block to a method but it will do nothing unless you invoke yield. Keyword yield acts as a special method which issues a call to code block as if code block was a Proc object.
Put(“Hello World”) {puts “Hello Universe”}
Here is an example of correct usage of code block with the yield keyword utilized.
def my_call
puts “Hello ”
getting = yield (“World”) //call to a block
puts “Calling #{getting}
end
my_call do |world|
puts “Crazy #{world}”
end
The result will print out “Hello Calling Crazy World”. Another good example of code block usage is in implementing of hash table search. We can pass code block to hash find method in order to locate our record.
my_hash = {0=>1, 1=>2, 2=>3}
my_hash.find { |key, value| key>1} //will return an [2,3] result set.
Ruby will generate an error of type “no block given” in case when a method calls yield but the caller did not pass a code block to it.
You can use block_given? In order to write a metho that takes an optional code block. For example:
def repeat(rep_num)
rep_num.times {yield} if block_given?
end
//calling with the code block
repeat(2) {puts “World”} //will print World twice
repeat(2) //No error generated
You can pass a code block variable as a method argument by putting it all the way at the end and adding ampersand sign in front of it, so your code know that this argument is for code block you method calls.
Example of the above mentioned implementation is provided below.
If bigger(collection, &block)
block ? collection.select(&block).max : collection.max
end
my_array = [1,2,3]
bigger(my_array) {|m| i<3} //will produce 2
bigger(my_array) //will produce 5 without error…
Code Blocks are Closures and here is an example that proves this point.
def add_number(my_array, my_num)
my_array.collect { |n| n + my_num }
end
add_all([1,2],100) //will give you an updated array of [101,102]
It is important to note that in Ruby block contains a references not copies. In addition, any data structure can be enumerated and code blocks used to performed actions similar to array iterations as example. Moreover, any object we define that in turn implements the each method can be wrapped in an Enumerator.