leaning diary Rails

【Learning Diary38】ブロック/イテレータ/Procオブジェクト

19/11/2023

【Learning Diary38】ブロック/イテレータ/Procオブジェクト

ブロックとは

メソッド呼び出しの際、引数と一緒に渡すことができる処理の塊です。

 

そのようなメソッド呼び出しを「ブロク付きメソッド呼び出し」、「ブロック付き呼び出し」といいます。

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
オブジェクト.メソッド名(引数リスト) do |ブロック変数|
繰り返したい処理
end
オブジェクト.メソッド名(引数リスト) { |ブロック変数|
繰り返したい処理
}
オブジェクト.メソッド名(引数リスト) do |ブロック変数| 繰り返したい処理 end オブジェクト.メソッド名(引数リスト) { |ブロック変数| 繰り返したい処理 }
オブジェクト.メソッド名(引数リスト) do |ブロック変数|
  繰り返したい処理
end


オブジェクト.メソッド名(引数リスト) { |ブロック変数|
  繰り返したい処理
}

イテレータ

ブロックを受け取るメソッドのうち、繰り返し処理を行うものと特にイテレータと呼びます。

 

代表的なものにeachがあります。

 

Proc

ブロックをオブジェクトとして受け取る方法としてProcオブジェクトがあります。

 

Proc.newメソッドをブロック付きメソッドとして呼び出すと、ブロックをオブジェクトとして利用することができるようになります。

 

Procオブジェクトに対してcallメソッドを呼び出すことで、ブロックの手続きを実行できます。

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Good_night = Proc.new do |name|
puts "Good night,#{name}."
end
Good_night.call("World")
Good_night.call("Ruby")
>Good night,World.
Good night,Ruby.
Good_night = Proc.new do |name| puts "Good night,#{name}." end Good_night.call("World") Good_night.call("Ruby") >Good night,World. Good night,Ruby.
Good_night = Proc.new do |name|
  puts "Good night,#{name}."
end

Good_night.call("World")
Good_night.call("Ruby")

>Good night,World.
Good night,Ruby.

 

メソッド間でブロックの受け渡しを行うときには、ブロックをProcオブジェクトとして変数で受け取っって、次のメソッドに渡す流れになります。

 

メソッド定義の際、最後の引数を「&引数名」の形にすると、その引数を呼び出すときに与えられたブロックは自動的にProcオブジェクトにまとめられて引数として渡されます。

 

変数の前に&をつけて受け取る引数のことをProc引数と言います。

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def total2(from,to,&block)
result = 0
from.upto(to) do |num|
if block
result += block.call(num)
else
result += num
end
end
return result
end
p total2(1,10)
p total2(1,10){|num|num **2}
#=55
385
def total2(from,to,&block) result = 0 from.upto(to) do |num| if block result += block.call(num) else result += num end end return result end p total2(1,10) p total2(1,10){|num|num **2} #=55 385
def total2(from,to,&block)
  result = 0
  from.upto(to) do |num|
    if block
      result += block.call(num)
    else
      result += num
    end
  end
  return result
end

p total2(1,10)
p total2(1,10){|num|num **2}

#=55
385

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def call_each(ary,&block)
ary.each(&block)
end
call_each [1,2,3] do |item|
p item
end
❯ ruby call_each.rb
1
2
3
def call_each(ary,&block) ary.each(&block) end call_each [1,2,3] do |item| p item end ❯ ruby call_each.rb 1 2 3
def call_each(ary,&block)
  ary.each(&block)
end

call_each [1,2,3] do |item|
  p item
end

❯ ruby call_each.rb
1
2
3

 

 

 

-leaning diary, Rails