[Ruby] Block

block

Method call with block

There are three main uses.

  1. Loop abstraction
  2. Addition of functions to blocks. Typically resource management.
  3. Callback function / event handler

Block as a closure

The block is a closure. That is, ** free variables appearing in the code inside the block follow the block's external environment **. Free variables in a block are resolved in the context outside the block, which is the external environment.

In the example below, the local variable count is shared outside and inside the block.

str = 'Hello, World'
count = 0
str.each_line do |line|
  print line
  count += 1
end
print count # => 1

Local variables, self, instance variables associated with self, method calls, etc. can all be used in the block in the same way as outside.

def some_method
  3.times { p self } #self is not 3 but some_method self
end

Preservation of environment

** The external environment referenced by the block is preserved as long as the block exists **. Even if the method execution is completed, the internal code block uses the local variable at the time of method execution.

In the example below, create_counter converts the code block inside the method into a Proc object and returns it to the caller. Calling the Proc # call method executes a block of code.

The local variable count in the execution context of the create_counter method can only be referenced by the Proc returned by the method. That is, the internal state can be concealed.

def create_counter
  count = 1
  return Proc.new do
    count += 1
    p count
  end
end
counter = create_counter
p counter.class # => Proc
counter.call # => 2
counter.call # => 3

counter2 = create_counter
counter2.call # => 2
counter.call # => 4
counter2.call # => 3

Block parameters

The block passed to the method can receive arguments when it is called back from the method. Blocks can also have their own local variable = block parameter.

a = "str"
[1, 2, 3].each { |a| p a } #This a is different from the above a
p a # => "str"

There are two points to be aware of from what we have learned so far.

Definition of method with block

yield expression

def foo_bar_baz
  yield "foo"
  yield "bar"
  yield "baz"
end

#Or

def foo_bar_baz
  #Enum when not given a block_Generate and return Enumerator with for
  return enum_for(:foo_bar_baz) unless block_given?
  %w[ foo bar baz ].each do |item|
    yield item
  end
end

foo_bar_baz do |item|
  puts item
end
# => foo
#    bar
#    baz

map-like

def my_map
  [yield(1), yield(2), yield(3)]
end
p my_map { |i| i + 1 }
# => [2, 3, 4]

Proc

If you want to get the calling block as an object, use a Proc object.

The & handler in the example below is called the block argument.

class SleepyPerson
  def register_handler(&handler)
    @event_handler = handler
  end
  def wake_up!
    @event_handler.call Time.now, "woke up"
  end
end
john = SleepyPerson.new
john.register_handler { |time, message| p [time, message] }
john.wake_up!

Block from Proc

proc = Proc.new { puts "Proc was called" }
3.times(&proc)
# => Proc was Called
#    Proc was Called
#    Proc was Called

Summary

For the time being, this seems to be important

reference

-First Ruby

Recommended Posts

[Ruby] Block
Ruby learning 4
[Ruby] Array
Ruby basics
Ruby learning 5
Ruby basics
Refactoring Ruby
Ruby learning 3
Ruby setting 2
Ruby learning 2
Refactoring Ruby
ruby calculator
Ruby learning 6
Ruby settings 1
Refactoring Ruby
Ruby basics
Ruby memo
Ruby learning 1
Ruby Review 1
[Ruby] Module
Introduction to Ruby 2
ruby Uppercase letters
ruby search problem
Ruby Learning # 25 Comments
Ruby to_s method
[Ruby] postfix if
[Ruby] FizzBuzz problem
Ruby text conversion
Ruby basic terms
ruby exception handling
Ruby Learning # 13 Arrays
About Ruby symbols
Ruby Learning # 1 Introduction
Ruby Learning # 34 Modules
[ruby] drill output
I started Ruby
[Ruby] Iterative processing
ruby API problem
Ruby vertical writing
About ruby ​​form
[ruby] drill output
Ruby Learning # 14 Hashes
[ruby] drill output
[Ruby] each nested
[Ruby] FizzBuzz problem
Ruby Hash notes
Class in Ruby
[Ruby] slice method
Ruby standard output
[Ruby] end_with? method
[Ruby] Method memorandum
Chart type Ruby
[Ruby] Hash retrieval
[WIP] Ruby Tips
[ruby] drill output
Ruby exception handling
About Ruby arrays
[ruby] Double hash
Ruby Learning # 33 Inheritance
About Ruby inheritance
Variables / scope (ruby)