1. Block:
A block in Ruby is a code block composed of multiple lines of code. It can be considered as an anonymous method and is often used to iterate an array or range (such as the each or times method ); the syntax format is as follows:
{
// Code
}
OR
Do
// Code
End
Block Variable: When a block is created, it is called a block variable between two vertical bars (such as: | I |). The function is the same as a parameter of a normal method; for example: 5. each {| x | puts x}
2. Block and array
Blocks are often used to iterate arrays. As mentioned above, many methods are defined in arrays to accept Block parameters. commonly used methods include:
Collect: This method passes each element of the array to the block and returns a new array containing all elements. The value of the original array remains unchanged. If you use collect! The method will modify the value of the original array;
Each: The each method is similar to the collect method. The value of each element in the array is passed to the block. However, unlike collect, the each method does not create a new array containing the returned value; no each! Method;
Example:
A = [1, 2, 3]
B = a. collect {| x * 2}
Puts ("--")
Puts
Puts ("-B -")
Puts B
C = a. collect! {| X * 2}
Puts ("--")
Puts
-------------- Result ------------------
--
1
3
-B-
2
6
--
2
6
In additionHow can we iterate every character in a string? The first thing we need to do is to split the string using the split method, and then iterate;
Example:
A = "hello". each {| x | puts x}
A = "hello". split (//). each {| x | puts x}
------------------- Result -------------------------------
Hello
H
E
L
L
O
Block is special in Ruby because it is not an object, which is inconsistent with "Everything is an object" in Ruby. Every object is created in a class, we can use the class method to find the class to which an object belongs;
Example:
Puts ({1 => 2}. Class) # hash
Puts ({| x | puts (x)}. class # error
3. Proc and Lambda
Although blocks are not objects by default, they can be "changed to" objects. There are three methods for creating objects from a block and assigning them to variables. The format is as follows:
A = Proc. New {| x | puts x}
B = Lambda {| x | puts x}
C = proc {| x | puts x}
Let's take a look at the three creation methods. First, we can use Proc. create an object and pass a block as a parameter. Then, we can use the call of the proc class (one or more parameters can be passed to the call method, these parameters are passed to the block. The number of parameters depends on the number of parameters in the block;
We can also use the other two methods to create a proc object. The three methods are similar. The only difference is that proc is used. the new object does not check the number of parameters, and the other two methods check;
Example:
A = Proc. New {| x, y, z | x = y * z; puts x}
A. Call (600,) # =>
B = proc {| x, y, z | x = y * z; puts x}
B. Call (10, 20, 30, 40) # => Error
C = Lambda {| x, y, z | x = y * z; puts x}
C. call (10, 20, 30, 40) # => error
4. Yield
In Ruby, the block can be passed to the method as a parameter, and the yield (parameter can be passed) keyword is used in the method to call the code block;
Example 1: Without Parameters
Class Person
Def go ()
Yield
End
End
P = Person. new
P. go {puts ("hello world ")}
Note: We simply put the block on the right side of the method we want to pass in. The method receives the block and calls the block code when yield is executed;
Example 2: With Parameters
Class Person
Def go (spead)
Yield (spead)
End
End
P = Person. new
P. go ("ten miles per hour! ") {| X. capitalize! Puts x}
Note:
1. in some examples, the go method carries a parameter spead and passes this parameter to the block executed by yield. When the go method is called, I passed a parameter ("ten miles per hour! "), When the yield statement is executed, the block parameter is passed;
2. When you use the yield keyword to call a code block, if the number of input parameters is less than the number of parameters defined in the Code block, the parameters that are not passed will be automatically converted to nil. Otherwise, the last parameter is an array that contains the remaining pass parameters;
5. Pass the named proc object
When defining a method in Ruby, if a "&" symbol is added before the last parameter of the method, Ruby treats the parameter as a Proc object (Example 2 ); the Proc object is actually the encapsulation body of a code block. Therefore, when calling a method, a block must be passed as a parameter;
Example 1:
Def abc (a, B, c)
A. call # <= call block
B. call # <= call block B
C. call # <= call block c
Yield # <= yield unnamed block: {puts "four "}
End
Abc (a, B, c) {puts "four "}
Example 2:
Def test (&)
A. call # <= block & d yield
Yield # <= also block & d
End
Test {puts "hello"} # Method 1: pass a block
A = proc {puts "world "}
Test (& a) # Method 2: pass a Proc object
6. Program priority
When passing a block, use the block passed by {} to use do... The priority of end should be high. To avoid ambiguity, it is best to enclose parameters with braces;
1. foo bar do... End: passed to the foo method. bar is passed to foo as a parameter.
2. foo bar {...} : The block is passed to the bar, and the returned value is passed to the foo method as a parameter.
Example:
Def foo (B)
Puts ("--- in foo ---")
A = 'foo'
If block_given?
Puts ("(Block passed to foo )")
Yield ()
Else
Puts ("(no block passed to foo )")
End
Puts ("in Foo, Arg B =#{ B }")
Return "returned by" <
End
Def bar
Puts ("--- in bar ---")
A = 'bar'
If block_given?
Puts ("(Block passed to bar )")
Yield ()
Else
Puts ("(no block passed to bar )")
End
Return "returned by" <
End
#=========== Syntax "A"-do... end ==========
Puts ('--- (A) do block ---')
# Callfoo with block
Foo bar do | s | puts (s) end
# The above is equivalent
# Foo (bar) do | s | puts (s) end
# Or
# Foo (bar) {| s | puts (s )}
Puts
#========== Syntax "B"-{}========
Puts ('--- (B) curly braces block ---')
# Callbar with Block
Foo bar {| S | puts (s )}
------------------------ Result ----------------------------------
--- (A) do block ---
--- In bar ---
(No block passed to bar)
--- In Foo ---
(Block passed to foo)
Foo
In Foo, Arg B = returned by bar
--- (B) curly braces block ---
--- In bar ---
(Block passed to bar)
Bar
--- In Foo ---
(No block passed to foo)
In Foo, Arg B = returned by bar
Note: Can we use block_given? Method to Determine whether a method receives a block;