I think many people know that they use do end somehow, I think that many people didn't understand it because the hurdles would rise a little when proc came out. Therefore, along with reorganizing my knowledge, I have compiled it so that many people can understand ruby's grammar firmly and code efficiently.
--Ruby allows you to pass a series of procedures to a method
--block is described by do end
or{}
-The argument is|x|
like|
Write it in the same way as a normal method
[*1..3].each do |i|
p i
end
# => 1
# => 2
# => 3
3.times { |i| p i }
# => 0
# => 1
# => 2
--Use ** yield to execute block ** or ** Use & block (see below) ** --If you are using a formal argument for block, you can use it by passing an argument to yield. --Yield can be used many times --yield will result in an error if used if no block is passed
def three_times
3.times { yield }
end
three_times { p 'a' }
# => "a"
# => "a"
# => "a"
def three_times
3.times { |j| yield(j) }
end
three_times { |i| p i }
# => 0
# => 1
# => 2
def calculate
p yield(1, 2)
p yield(2, 3)
end
calculate { |a, b| a + b }
# => 3
# => 5
calculate { |a, b| a * b }
# => 2
# => 6
def three_times(&block)
3.times { yield } rescue p $!
end
three_times
# => #<LocalJumpError: no block given (yield)>
--Use block_given?
def three_times
p block_given?
end
three_times
# => false
three_times { p 'y' }
# => true
--block can be converted to and from Proc object by using &
--You can pass it as a block by doing & proc_object
as a method argument.
--By using & block
as the formal argument of the method, ** the block can be received as a Proc object **
--If you receive a plain block without using &
as an argument, it will be proc instead of lambda (the difference between proc and lambda will be described later).
--If you pass lambda as an argument with &
, it will be received as lambda
proc_object = Proc.new do |a|
p a
end
3.times(&proc_object)
# => 0
# => 1
# => 2
def three_times(&block)
3.times { |j| block.call(j) }
end
three_times { |i| i }
# => 0
# => 1
# => 2
--Proc objects have Proc
andProc (lambda)
(referred to as proc and lambda respectively).
--Both are Proc
classes
-proc isProc.new { |x| }
Orproc { |x| }
Write
-lambda islambda { |x| }
Or->(x) { }
Write
p Proc.new {}
# => #<Proc:0x00007f3e59459978@/tmp/nvimaASrm8/2:1>
p Proc.new {}.instance_of?(Proc)
# => true
p lambda {}
# => #<Proc:0x00007f3e59459838@/tmp/nvimaASrm8/2:2 (lambda)>
p lambda {}.instance_of?(Proc)
# => true
--When the argument is extra --proc: Through --lambda: error --If there are not enough arguments --proc: becomes nil --lambda: error
x = proc { |a, b| p [a,b] }
x.call(:a, :b, :c)
# => [:a, :b]
x = lambda { |a, b| p [a,b] }
x.call(:a, :b, :c) rescue p $!
# => #<ArgumentError: wrong number of arguments (given 3, expected 2)>
x = proc { |a, b| p [a,b] }
x.call(:a)
# => [:a, nil]
x = lambda { |a, b| p [a,b] }
x.call(:a) rescue p $!
# => #<ArgumentError: wrong number of arguments (given 1, expected 2)>
--When executed in the method that defines Proc
** If you want to return the result of the procedure, use next
in both lambda and proc! **
def hoge
x = proc { return 2 }.call
p "x: #{x}"
return 1
end
p "method: #{hoge}"
# => "method: 2"
def hoge
x = lambda { return 2 }.call
p "x: #{x}"
return 1
end
p "method: #{hoge}"
# => "x: 2"
# => "method: 1"
def hoge
x = proc { break 2 }.call
p "x: #{x}"
return 1
end
p "method: #{hoge}" rescue p $!
# => #<LocalJumpError: break from proc-closure>
def hoge
x = lambda { break 2 }.call
p "x: #{x}"
return 1
end
p "method: #{hoge}"
# => "x: 2"
# => "method: 1"
def hoge(x)
p "x: #{x.call}"
return 1
end
x = proc { break 2 }
p "method: #{hoge(x)}" rescue p $!
# => #<LocalJumpError: break from proc-closure>
x = lambda { break 2 }
p "method: #{hoge(x)}"
# => "x: 2"
# => "method: 1"
Recommended Posts