A deep understanding of the block Feature in Ruby, rubyblock
What is a block?
Block is not uncommon in Ruby. The official definition of block is "a piece of wrapped code ". Of course, I don't think this explanation will make you better understand.
A simpler description of block is "a block is a piece of code stored in a variable. It can be run at any time like other objects"
Then, let's look at some code and re-construct the code into a block form in Ruby. The code is more intuitive.
For example, add two numbers?
puts 5 + 6# => 11
Well, you can write it like this. However, this code only serves the First Half of the block definition-it is a piece of code. But it is not "wrapped up" or "stored in a variable ".
Therefore, we need to continue the modification. But before we wrap it up, we should first improve it to make it look more generic.
a = 5b = 6puts a + b# => 11
Good ~ In this way, we can replace the previous number with the variable. This code executes an addition process, but it is still not stored in a variable.
Now let's implement it.
addition = lambda { |a, b| return a+b }puts addition.call(5, 6)# => 11
Okay, now you have wrapped it up. This is a block!
Using the 'lambda 'keyword is the most common method for creating blocks in Ruby. There are other methods that can also be done, But Now no matter what other methods.
At this time, you may think, "Wait, it looks like a method, except that there are no classes and objects." You are right. It can even be understood as follows: A block is like a method, but it is not associated with any object.
Let's continue and take a closer look at the block.
A block contains a code block. You can allocate a name and a block. The code in the block is always enclosed in braces ({}) or do... end.
[1, 2, 3].each do |i| puts iend#=> 1 2 3
In the above example, the each method is followed by a do... end structure, which is a block.
You can pass a block to any method in Ruby.
def test;end test{ puts i}def test yield end test{puts "hello test!"} def test(x) yield(x) end test('world!'){|x| puts "hello #{x}"}
The yield keyword can not only mount block code, but also pass parameters to the block.
Def test (& block) block. call ("world") end test {| msg | puts "hello # {msg}"} block to the method and has been & converted to a Proc object. Def test (& block) inner_test (& block) end def inner_test yield ("haha! ") End test {| msg | puts" hello # {msg }"}
The block passed in by the test method is converted to a Proc object, and the inner_test in it uses "&" to convert the Proc object to a block)
Is a block an object? Of course, like other things in Ruby, block is also an object.
empty_block = lambda { }puts empty_block.object_id# => 28765760puts empty_block.class# => Procputs empty_block.class.superclass# => Object
As you can see, the block we created has an object_id that belongs to the Proc class (this is the name of a block in Ruby), and this class itself is the subclass of the Object.
We can even define the method from the block ). A method is bound to an object block to access the object's "status ".
Next I will demonstrate how to use a method to create a block in reverse order. There are some more traditional methods to implement the previous problems (and please forgive me for poor Object Modeling)
class Calculator def add(a, b) return a+b endendputs Calculator.new.add(5, 6)# => 11
This code can certainly work well. Then, make some modifications.
class Calculator def add(a, b) return a+b endendaddition_method = Calculator.new.method("add")addition = addition_method.to_procputs addition.call(5, 6)# => 11
Now, you can convert a traditional method into a block!
Block your code!
Let's construct four blocks for addition, subtraction, multiplication, and Division respectively. Each block should take two values as variables, then perform the operation and return the result.
Addition = lambda {| a, B | return a + B} Subtraction = lambda {| a, B | return a-B} Multiplication = lambda {|, B | return a * B} Division = lambda {| a, B | return a/B} # Use Addition through call. call (5, 6) # => 11