Analysis of Proc class and Proc class method Proc. new in Ruby, procproc. new
Proc is the process object obtained after the block and its context (the scope of local variables and the stack framework) are objectized. You can use Proc like an anonymous function, but it does not import the scope of local variables (dynamic local variables can be used as Proc local variables ).
In the following example, the var variable can be called only because Proc keeps the scope of local variables.
var = 1$foo = Proc.new { var }var = 2def foo $foo.callendp foo # => 2
If return or retry occurs in Proc, The LocalJumpError exception is thrown.
def foo proc { return }endfoo.call# => in `call': return from proc-closure (LocalJumpError)def foo proc { retry }endfoo.call# => in `call': retry from proc-closure (LocalJumpError)
If you add "&" to Proc and pass it to a method with a block, its operation is similar to calling a block. But strictly speaking, there are still the following differences.
# No problem (1.8). each {break} # In ruby 1.6.7. In 1.6.8, an exception occurs. proc = Proc. new {break} (1 .. 5 ). each (& proc) # LocalJumpError in ruby 1.6 # Run eachproc = Proc again in ruby 1.8. new {retry} (1 .. 5 ). each (& proc) # => retry from proc-closure (LocalJumpError)
This is exactly the limit when the Proc object is used to call a block.
Proc.newProc.new { ... }
After the block and its context are objectized, results are returned.
If no block is provided, the block contained in the method that calls this method is converted to a Proc object and returned.
def foo pr = Proc.new pr.call(1,2,3)endfoo {|args| p args }# => [1, 2, 3]
Proc. new Method Depth
Proc. new: After the block and its context are objectized, the result is returned.
If no block is provided, the block contained in the method that calls this method is converted to a Proc object and returned.
Def foo pr = Proc. new pr. call (, 3) endfoo {| args | p args }#=> [1, 2, 3] This is the same as def foo yield (, 3) in the following example) endfoo {| args | p args }#=> [1, 2, 3]
If the main call method does not contain blocks, ArgumentError is thrown.
def foo Proc.newendfoo# => -:2:in `new': tried to create Proc object without a block (ArgumentError) from -:2:in `foo' from -:4
When Proc. new is used, if the Proc # initialize method is defined, this method is called during object initialization. In addition, it is the same as proc.
You can use the Proc. new method or specify a block for the proc method to create a Proc object representing the block.
Execute the block by calling the Proc # call method. When the Proc # call method is called, the parameter is used as a block variable. The value of the last expression in the block is the return value of Proc # call. Proc # call also has a name called Proc # [].
# Leap = Proc. new do | year % 4 = 0 & year % 100! = 0 | year % 400 = 0end p leap. call (2000) # => truep leap [2013] # => falsep leap [2016] # => true
After you set block variables to the form of | * array |, you can receive variable parameters in the form of arrays like method parameters.
Double = Proc. new do | * args | args. map {| I * 2} # All elements multiply by double end p double. call (1, 2, 3) # => [2, 3, 4] p double [2, 3, 4] # => [4, 6, 8]
In addition, the parameter formats that can be used to define common methods, such as default parameters and keyword parameters, can be used to define block variables and assigned to the Proc # call method.