Ruby
Block

Ruby ブロックについて学ぶ

More than 3 years have passed since last update.

Ruby力の基礎固めとして、ブロックについて学んだことをまとめます。


ブロックとは


メソッド呼び出しの際に引数と一緒に渡すことのできる処理のかたまり | たのしいRuby P199



ブロックつきメソッド呼び出しの例

[1, 2, 3, 4, 5].each do |i| # do ~ end は { ~ } でもOK

puts i ** 2
end
=> 1
4
9
16
25


ブロックの使い方

代表的な使い方が以下の3つです。

- 繰り返し

- 処理の隠蔽

- 処理の一部の差し替え


繰り返し

# 例)hash

sum = 0
outcome = {'join' => 1000, "shopping" => 1000, 'food' => 4000}
outcome.each do |item, price|
sum += price
end
puts sum
=> 6000

# 例)file読込
file = File.open('sample.txt')
file.each_line do |line|
print line
end
=> aaa
bbb
ccc
ddd
file.close


処理を隠す

# 例)自動的にファイルが閉じられる

file = File.open('sample.txt') do |file|
file.each_line do |line|
print line
end
end
=> aaa
bbb
ccc
ddd


計算の一部の差し替え

# Array#sortの場合

a = [3, 4, 5, 2, 6, 1, 7]

# ブロックなし
sorted = a.sort
=> [1, 2, 3, 4, 5, 6, 7]

# デフォルトの処理と同じ
sorted = a.sort do |a, b|
a <=> b
end
=> [1, 2, 3, 4, 5, 6, 7]

# リバース
sorted = a.sort do |a, b|
b <=> a
end
=> [7, 6, 5, 4, 3, 2, 1]

str_a = ["udon", "yakisoba", "somen", "ra---men"]

# 文字数順
sorted = str_a.sort do |a, b|
a.length <=> b.length
end
=> ["udon", "somen", "yakisoba", "ra---men"]


ブロックつきメソッドの作り方


ブロックの処理 → 合計値を算出するメソッドの例


def total(from, to)
result = 0
from.upto(to) do |num|
if block_given?
result += yield(num)
else
result += num
end
end
return result
end

p total(1, 10)
=> 55
p total(1, 10){|num| num ** 2}
=> 385


ブロック変数とyieldの引数の関係

ブロック変数とyieldの引数の数はあわなくてもエラーにはならない


# ブロック変数がyield引数より多い場合
def block_args
yield()
end
block_args do |a|
p [a]
end
=> nil

# ブロック変数がyield引数より少ない場合
def block_arg
yield(1,2,3)
end
block_arg do |a|
p a
end
=> 1

# ブロック変数を*aで受け取る場合
def block_arg
yield(1,2,3)
end
block_arg do | *a |
p a
end
=> [1, 2, 3]


ブロックのオブジェクト化

Procを使う。ブロックを別メソッドに引き渡すことが可能になる

# Proc変数を使用する例

def total2(from, to, &block) # &引数名にすると与えられたブロックはProcオブジェクト化される
result = 0
from.upto(to) do |num|
if block # 判定式も変更
result += block.call(num) # block.callで呼び出し
else
result += num
end
end
return result
end


ローカル変数とブロック変数

主な特徴は2つ

- ローカル変数はブロック内でも共有

- ブロック変数は外側とは切り離されている


参考