The differences among block, proc, and lambda in Ruby are summarized.

Source: Internet
Author: User

The differences among block, proc, and lambda in Ruby are summarized.

In the rule engine, Ruby closures are frequently used, and there are several forms of usage such as block, Proc, and lambda, which is confusing. To gain a deeper understanding of the code, I once again carefully studied the Ruby closures, especially the similarities and differences between block, proc, and lambda. I will share my experiences with you in this weekly record.

Closures are one of Ruby's special advantages over other languages. Many languages have closures, but only Ruby gives full play to the advantages of closures. Ruby's philosophy: there are multiple solutions to the same problem in reality, so there are also multiple solutions in Ruby, so there are also multiple methods to use closures.

Let's look at an example of code:

Example 1:
Copy codeThe Code is as follows:
Def foo1
Yield
End

Def foo2 (& B)
B. call if B
End

Foo1 {puts "foo1 in block "}
Foo2 {puts "foo2 in block "}
Proc = Proc. new {puts "foo in proc "}
Foo1 (& proc)
Foo2 (& proc)
Lambda_proc = lambda {puts "foo in lambda "}
Foo1 (& lambda_proc)
Foo2 (& lambda_proc)

Output:
Copy codeThe Code is as follows:
"Foo1 in block
"Foo2 in block
Foo in proc
Foo in proc
Foo in lambda
Foo in lambda

Are you confused? First, the methods foo1 and foo2 can receive closures. What are the differences between the two statements, and then the three closure blocks as parameters? What is the difference between proc and lambda.

1. Differences between yield and block call

Yield and block call can both implement the operation closure. In terms of the actual running effect, there is little difference. The main difference is:

1.1 transfer and storage of closures

Because the closure has been passed to the parameter, it can be passed or saved. For example:

Exampl 2:
Copy codeThe Code is as follows:
Class
Def foo1 (& B)
@ Proc = B
End
Def foo2
@ Proc. call if @ proc
End
End

A = A. new
A. foo1 {puts "proc from foo1 "}
A. foo2

1.2 Performance

Yield is not a method call, but a keyword of Ruby. yield is about twice faster than block call.

2. Differences between block, proc, and lambda

The introduction of proc and lambda is simple and straightforward to reuse and avoid repeated definitions. For example, in example 1, use the proc variable to store closures and avoid repeated definitions of two blocks.

3. Differences between proc and lambda

This is probably the most confusing place. From the perspective of Example 1's behavior, their effects are the same. Why do we use two different expressions.
Copy codeThe Code is as follows:
Proc = Proc. new {puts "foo in proc "}
Lambda_proc = lambda {puts "foo in lambda "}

Indeed, for simple cases, such as Example 1, their behaviors are consistent, but there are major differences in the two areas:

1.1 parameter check

Example 3:
Copy codeThe Code is as follows:
Def foo
X = 100
Yield x
End

Proc = Proc. new {| a, B | puts "a is # {a. inspect} B is # {B. inspect }"}
Foo (& proc)


Lambda_proc1 = lambda {| a | puts "a is # {a. inspect }"}
Foo (& lambda_proc1)
Lambda_proc2 = lambda {| a, B | puts "a is # {a. inspect} B is # {B. inspect }"}
Foo (& lambda_proc2)

Output

Copy codeThe Code is as follows:
"A is 100 B is nil
"A is 100
ArgumentError: wrong number of arguments (1 for 2)
...

It can be seen that proc does not check the number of parameters, while lambda does. If it does not match, an exception is reported. Therefore, we recommend that you prioritize lambda for security reasons.

1.2 return to upper layer

Example 4:

Copy codeThe Code is as follows:
Def foo
F = Proc. new {return "return from foo from inside proc "}
F. call # control leaves foo here
Return "return from foo"
End


Def bar
F = lambda {return "return from lambda "}
Puts f. call # control does not leave bar here
Return "return from bar"
End


Puts foo
Puts bar

Output

Copy codeThe Code is as follows:
Return from foo from inside proc
Return from lambda
Return from bar

It can be seen that in proc, return is equivalent to executing the return in the closure environment, while lambda only returns the environment where the call closure is located.

Conclusion: closure is a powerful feature of Ruby. Its expressions block, proc, and lambda are slightly different. To use it well, you need to understand it in depth.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.