Ruby block, Proc and lambda introduction

Source: Internet
Author: User


1.Block:



A block in Ruby is a block of code consisting of multiple lines of code that can often be considered an anonymous method, commonly used to iterate over an array or range (such as each, The Times method), and the syntax format is as follows:


The code is as follows


{

Code

}

OR

Todo

Code

End


Block variable: When creating a block, between two vertical bars (e.g. | i |)  Called a block variable, the action is the same as the parameter of a normal method; such as: 5.each{| x | Puts X}






2.Block and Array



Block is often used to iterate algebraic groups, as mentioned above, so many methods are also defined in the array to accept chunk parameters;



Collect: This method passes each element of the array to the block and returns a new array that includes all the elements, and the value of the original array is unchanged. If you use collect! Method just modifies the value of the original array;



The Each:each method is somewhat similar to the Collect method, which passes the value of each element of the array to the block, but unlike collect, each method does not create a new array containing the return value; there is no each! method;



Cases:


The code is as follows


A = [1,2,3]

b = a.collect{|x| X*2}

Puts ("-a-")

Puts a

Puts ("-b-")

Puts B

c = a.collect! {|x| x*2}

Puts ("-a-")

Puts a

--------------result------------------

-a-

1

3

-b-

2

6

-a-

2

6


In addition, how do we iterate over each character in a string? The first thing we need to do is to split the string in the split method and then iterate.



Cases:


The code is as follows


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 block change is not an object, which is incompatible with "all objects" in Ruby; Each object is created in a class, and we can use the class method to find out which class the object belongs to.



Cases:


The code is as follows

Puts ({1=>2}.class) #Hash

Puts ({|x| puts (x)}.class #error





3.Proc and Lambda



Although block defaults are not objects, they can "become" objects. There are three ways to create objects from the block and assign them to variables in the following format:


The code 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 of all, we can use Proc.new to create an object and pass a block as an argument to it; then we can call the Proc class (you can pass one or more arguments to the calling method, These parameters are passed to the block, and the number of parameters depends on the number of parameters in the block to execute the code in the Block;



We can also use the other two methods to create a Proc object, three methods are similar; the only difference is that objects created with Proc.new do not check the number of parameters, and other two methods check;



Cases:


The code is as follows





A = proc.new{|x,y,z| x=y*z; puts X}



A.call (10,20,30,40) #=>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, a block can be passed as a parameter to a method, in which a yield (which can pass parameters) is used to invoke the code blocks;



Example 1: With no parameters


  code is as follows

 

       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 block, and the block code is invoked when the yield is executed;



Example 2: With parameters


The code is as follows


Class Person

def go (spead)

Yield (spead)

End

End

p = person.new

P.go ("Ten miles per hour!") {|x| x.capitalize! puts X}


Note:



1. In some cases, the go method takes a parameter, Spead, and passes the parameter to the block that is executed by yield, and when I call the went method, I pass an argument ("Ten miles per hour!"), and when executed to the yield statement, is passed to the block parameter;



2. When you invoke a code block using the yield keyword, if the number of arguments passed in is less than the number of parameters defined in the code block, then the parameter that is not passed is automatically converted to nil. Conversely, the last argument is an array that contains the remaining pass parameters;






5. Passing the named proc Object



When you define a method in Ruby, if you add a "&" symbol before the last formal parameter of the method, Ruby will treat the parameter as a Proc object (example 2), and the Proc object is actually a wrapper for the code block, Therefore, it is necessary to pass a block as the parameter when calling the method;



Example 1:


The code is as follows


DEF ABC (A, B, c)

A.call #<= Call Block A

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:


  code is as follows


def test (&a)

A.call #<= Block &d yield

Yield #<= also block &d

End

Test{puts "Hello"} #法一, passing a block

A = Proc{puts "World"}

Test (&a) #法二, passing a proc object





6. Program Priority



When passing a block, the block passed with {} is higher than the priority of using Do...end; In order to avoid ambiguity, it is best to enclose the arguments with curly braces;



1. Foo Bar Do...end: Passed into the Foo method, bar is passed as a parameter to Foo



2. Foo Bar {...} : The block is passed to bar, and the returned value is passed as a parameter to method foo



Cases:


The code is as follows





def foo (b)



Puts ("---in foo---")



A = ' foo '



If Block_given?



Puts ("(blocks passed to foo)")



Yield (a)



Else



Puts ("(No block passed to foo)")



End



Puts ("in foo, arg b = #{b}")



Return ' returned by ' << a



End






def Bar



Puts ("---in Bar---")



A = ' bar '



If Block_given?



Puts ("(blocks passed to bar)")



Yield (a)



Else



Puts ("(No block passed to bar)")



End



Return ' returned by ' << a



End



# ========== Syntax "A"-do. End =======



Puts ('---(A) do block---')



# calls Foo with block



Foo Bar do |s| Puts (s) end






# The above is equivalent to



# foo (bar) do |s| Puts (s) end



# or



# foo (bar) {|s| puts (s)}



Puts



# ========== Syntax "B"-{} =======



Puts ('---(B) curly braces block---')



# calls Bar with block



Foo bar{|s| puts (s)}



------------------------result----------------------------------



---(A) do block---



---in bar---



(No block passed to bar)



---in foo---



(Blocks 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: We can use the Block_given method to determine whether a method has received a block;


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.