Detailed description of the code block and parameter transfer in Ruby, detailed description of ruby code transfer

Source: Internet
Author: User

Detailed description of the code block and parameter transfer in Ruby, detailed description of ruby code transfer

1. Block Declaration
After the function is called, the block declaration is enclosed by {...}, Or do. end encapsulation. {} Is generally used in single-line statements, and do... end is used in multi-line statements.\

(1..4) .each {| v | print "# {v}"} #Output 1 2 3 4

  Blocks can take parameters. Unlike function parameters, block parameters are encapsulated with ||. Of course, you can take multiple parameters. How to define these parameters is actually defined inside the function, which will be described later.

Second, the access of variables in the block
  Blocks can access variables outside the block, that is, variables outside the block are visible inside the block, such as

sum = 0
(1..5) .each do | v |
  name = 'smile' #name belongs to the variable within the block, and its visible range can only be within the block. Suppose there are no variables with the same name outside the block.
  sum = v #sum is visible inside the block
end
p sum #Output 15, sum has changed.
p name #Error! name is not accessible.

  Because of the variables inside and outside the block, some external variables may be accidentally modified, which is not what we want. Fortunately, after the Ruby 1.9 version, it provides a safe way to declare variables in the block, adding ";" after the block parameters, and placing the variables in the block after ";"

name = 'outside'
sum = 0
(1..5) .each do | v; name | #nameAfter ";", you can declare multiple variables, separated by commas
  name = 'inside' #name belongs to a variable within the block, and its visible range can only be within the block. Assume that there is no variable with the same name outside the block.
  sum = v #sum is accessible within the block
end
p sum #Output 15, sum has changed.
p name #Output outside without change.

Third, the yield statement
  Looking here, it may not be clear how the function calls the block. Now to introduce the call of the block, the key is the yield statement. In the function body, if yield is used, the function will call the function block.

def threeTime
  yield
  yield
  yield
end
threeTime {p 'Hello world!'}

  Is it easy to output three lines of Hello world! You should understand now, it is the block called by yield.
What are the parameters of the block? It is estimated that you have thought of the yield parameters, which can take parameters like the general function. See example

def takeBlock (p1)
 if block_given? # Determine whether there is a block. If there is no block declared during yield, an error will occur, so it will be better to make a judgment here.
  yield (p1) # P1 is passed to the block parameters, that is, s
 else
  p1
 end
endie
 
takeBlock ("no block") #output "no block"
takeBlock ("no block") {| s | s.sub (/ no /, '')} #output "block"

  Since yield can pass parameters to the block, in turn, can the block pass values to yield? The answer is yes. The value of the last sentence in the block is automatically passed to yield. See example

def nTime
 i = yield #When the first call, return the value of the block
 (0..i) .each {| v | yield (v)} # Here yield can also be placed in a block
end
nTime do | v |
 print "# {v}" if v
 9 #yield Number returned when called
end
#Output 1 2 3 4 5 6 7 8 9

Of course, the above example is just used as an example. In fact, no one would define it this way. A better definition is as follows:

def nTime (n)
 (0..n) .each {| v | yield (v)}
end
nTime (9) do | v |
 print "# {v}"
end

Let's take a look at the find implementation in Array

class Array
 def find
  for i in 0 ... size
   value = self [i]
   return value if yield (value)
  end
  return nil
 end
end
[1, 3, 5, 7, 9] .find {| v | v> 5} #Realize finding the first number greater than 5, and output 7.
 Because of the appearance of blocks, many for statements are missing in Ruby, and the code looks more user-friendly. Writing code is no longer a boring thing, but a pleasure.

Four, another way to pass blocks

def fun #without parameters
 yield
end
proc =-> {p 'haha'}
 
fun & proc
#####
def fun2 (x) #with parameters
 yield x
end
proc2 =-> (x) {p x}
fun2 1, & proc2

Five, instance_eval () and instance_exec ()
In Ruby, a very cool feature is provided. You can use the Objec # instance_eval (), Objec # instance_exec () method to insert a code block and make an object context probe (Context Proble) to drill into the code in the object Fragment, operate on it. With this feature, you can easily test the behavior of the object and view the current state of the object.

class MyClass
 def initialize
  @v = 1;
 end
end
obj = MyClass.new
obj.instance_eval do
 puts self # => # <MyClass: 0x007fbb2d0299b0>
 puts @v # => 1
end
obj.instance_exec (5) {| x | puts x * @v} # => 5

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.