Class array def iterate! (& Code) # note that the & Symbol self is used here. each_with_index do | N, I | self [I] = code. call (n) end endendarr = [1, 2, 4] arr. iterate! Do | n ** 2end # [1, 4, 9, 16]
When I read the code today, it was masked by this & symbol. In Ruby, various strange symbols are generated from time to time, and their functions are unknown. It is hard to find.
So I studied it carefully.
& The true meaning of the operator: The switching symbol between the proc object and the block.& Code: This is a block, and code is a proc object.Simply remove the & operator, we can get a proc object again.
========================================================== ==============
Well, if there is no context, it is completely unclear. Let's take a look at the example below. You will know when you run it.
Def evaluate (a, B) yield a, benddef math_by_proc (a, B, a_proc) a_proc.call (a, B) enddef math_by_named_block (a, B, & namedblock) puts "math_by_proc, b, namedblock "puts namedblock. class # & namedblock is a block, namedblock (remove &) is a proc, And the & operator is a switch. Puts math_by_proc a, B, namedblockputs "======" # lambdamylambda = Lambda & namedblock puts mylambda. class puts math_by_anonymouse_block a, B, & mylambda # Haha. In this case, puts "math_by_proc a, B, mylambda" puts math_by_proc A, B, mylambdaputs "======" # proc myproc = proc & namedblock puts myproc. class puts math_by_anonymouse_block a, B, & myproc # Haha. In this case, puts "math_by_proc a, B, myproc" puts math_by_proc a, B, myprocputs "= ==== "# Puts & namedblock. class # blocks cannot be directly assigned to a variable. However, you can pass # myblock = & namedblock # running failure # Puts myblock. class # So we use this method puts "math_by_anonymouse_block" puts math_by_anonymouse_block a, B, & namedblockputs "======" endmath_by_named_block (2, 3) {| X, Y | x * y}
Running result:
---------- Ruby run ---------- math_by_proc a, B, namedblockproc6 ======= proc6math_by_proc a, B, mylambda6 ===== proc6math_by_proc A, B, myproc6 ======= math_by_anonymouse_block6 ======= output completed (takes 0 seconds)-normal termination
A block is like an additional anonymous parameter of a method. Any method can be followed by a block when calling it. However, if this method contains the yield statement, it will call the block. If there is no yield statement, it will ignore this block.
For example:
def my_noyield puts "leave me alone. no yield !"enddef my_yield puts "I call you! come on" yieldendmy_noyield { puts "I'm coming!"}my_yield { puts "I'm coming!"}
This is to define a method with & operator parameters, which is equivalent to turning the previous anonymous parameter into a & variable name parameter. This parameter must be a block (not proc, remove & is proc)
def my_third(&myproc)puts "I call you! come on"yieldendmy_third { puts "I'm coming!"}
Here & myproc is a block, while myproc is a proc. For proc, we should be able to directly call Proc. Call.
So let's try the 4th method: Call This proc directly in the method instead of yield.
def my_fourth (&myproc)puts "I call you! come on"myproc.callendmy_fourth { puts "I'm coming!"}
In fact, it is a switching switch. With this switch, you can switch between proc and block. Proc/Lambda is also a switch (these two are Kernel Methods: Kernel # proc: Creates a new procedure object from the given block. equivalentProc.new
.)
Def my_fivth (& myproc) puts "I call you! Come on "# & myproc. Call: No. Can I reverse it twice? C_proc = proc & myprocc_proc.callendmy_fivth {puts "I'm coming! "} Def my_sixth (& myproc) puts" I call you! Come on "c_proc = Lambda & myprocc_proc.callendmy_sixth {puts" I'm coming! "}
Add a summary:
Callable objects can be in the following forms: blocks, Proc, lambda, and methods. The callable objects of different classes are slightly different.
However, you can still convert them using the following methods: Proc. New () method, methrod # to_proc () method, and & operator.