About ruby block

Overview

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.

What is a block

--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

How to create a method that uses block

--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)>

Determine if block was passed

--Use block_given?

def three_times
  p block_given?
end

three_times
# => false
three_times { p 'y' }
# => true

I want to treat a block as an instance

--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 and lambda

--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

Difference between proc and lambda

Handling of arguments

--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)>

break, return behavior

--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

About ruby block
[Ruby] Block
About Ruby symbols
About ruby ​​form
About Ruby arrays
About Ruby inheritance
About Ruby Hashes
About Ruby Symbols
About Ruby variables
About Ruby methods
About Ruby Kernel Module
About Ruby error messages
About Ruby Hashes (continued)
About eval in Ruby
[ruby] About here documents
About Ruby if statement
[Ruby] About instance generation
About the [ruby] operator
Thinking about logic Ruby
Explanation about Ruby Range object
About Ruby hashes and symbols
Ruby About various iterative processes
About =
About Ruby and object model
About Ruby classes and instances
Explanation about Ruby String object
About the behavior of ruby Hash # ==
About Ruby single quotes and double quotes
About Ruby product operator (&) and sum operator (|)
[Super Introduction] About Symbols in Ruby
[Ruby] Yield but no block argument
About object-oriented inheritance and about yield Ruby
[Ruby] Review about nesting of each
Explanation about Array object of Ruby
About method.invoke
Ruby learning 4
About Kotlin
About attr_accessor
[Ruby] Array
About Hinemos
Ruby basics
Ruby learning 5
About inheritance
Ruby basics
About params
About Docker
Refactoring Ruby
About Rails 6
About form_for
About Spring ③
[Ruby on Rails] About bundler (for beginners)
Ruby learning 3
About enum
About polymorphism
About Optional
About JitPack
About Dockerfile
About encapsulation
Ruby setting 2
About Docker
About JAVA_HOME