block, proc, lambda difference summary _ruby topics in Ruby

Source: Internet
Author: User
Tags closure

In the rule engine, Ruby's closures are particularly frequent, and there are several forms of usage, such as block,proc and lambda, that are confusing. In order to get a deeper understanding of the code, and again carefully learn Ruby's closure, especially Block,proc and lambda several uses of similarities and differences, this week's diary and you share the experience.

Closures are one of the special advantages of ruby relative to other languages, and many languages have closures, but only Ruby has the advantage of closing the pack. One of Ruby's philosophies: There are many solutions to the same problem, so there are many ways to use it in Ruby, so there are a number of methods for closures.

Let's take a look at a code example:

Example 1:

Copy Code code as follows:

def foo1
Yield
End

def foo2 (&b)
B.call if B
End

foo1 {puts "foo1 in"}
Foo2 {puts "Foo2 in"}
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 Code code as follows:

"Foo1 in block
"Foo2 in block
"Foo in proc"
"Foo in proc"
"Foo in Lambda"
"Foo in Lambda"

We are not a bit confused, the first is the method foo1 and Foo2 can receive closures, they are the difference between the two ways, and then as a parameter of the three kinds of closures block,proc and lambda what is the difference.

1. The difference between yield and block call

Yield and block call two can achieve the operation of the closure, from the actual operating effect, the difference is not small. The main difference is:

1.1 Transfer and preservation of closures

Because closures have been passed into parameters, they can be passed on or saved, for example:

Exampl 2:

Copy Code code as follows:

Class A
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 Ruby keyword, and yield is about 1 time times faster than block calls.

2. Block and proc, the difference between the lambda

Quite simply, the introduction of proc and Lambda is for reuse, avoiding duplicate definitions, for example, in Example 1, using proc variables to store closures, avoiding the repeated definition of two blocks.

3. The difference between proc and Lambda

This is probably the most confusing place, from the behavior of Example 1, their effect is consistent, why use two different ways of expression.

Copy Code code as follows:

Proc = proc.new {puts "foo in proc"}
Lambda_proc = lambda {puts "foo in Lambda"}

Indeed, for simple situations, such as Example 1, their behavior is consistent, but there is a significant difference in the main two places:

1.1 Parameter Check

Or an example of talking Example 3:

Copy Code code 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 Code code as follows:

"A is" B is nil
"A is 100"
"Argumenterror:wrong Number of arguments (1 for 2)
...

As you can see, Proc does not perform a number matching check on the parameters, and the lambda will report an exception if it does not match, so it is safe to recommend a lambda preference.

1.2 Back to Top

Or an example of talking Example 4:

Copy Code code as follows:

def foo
F = proc.new {return ' return ' from foo-Inside Proc '}
F.call # control leaves Foo here
Return ' Return to Foo '
End


def Bar
F = lambda {return ' return from Lambda '}
Puts F.call # control does no leave bar here
Return ' Return to bar '
End


Puts Foo
Puts bar

Output

Copy Code code as follows:

"Return to from Foo-inside proc
"Return" from Lambda
"Return" from Bar

As you can see, in Proc, return is the equivalent of performing the returns in the closure environment, and the lambda simply returned to the environment where the call closure was located.

Conclusion: Closures are a powerful feature of Ruby, and there are several ways in which they can be block,proc and lambda, so it needs to be understood 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.