シンプルな例
メソッド呼び出し(super・ブロック付き・yield) (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/doc/spec=2fcall.html
ブロック付きメソッドとは制御構造の抽象化のために用いられる メソッドです。最初はループの抽象化のために用いられていたため、 特にイテレータと呼ばれることもあります。 do ... end または { ... } で囲まれたコードの断片 (ブロックと呼ばれる)を後ろに付けてメソッドを呼び出すと、その メソッドの内部からブロックを評価できます。 ブロック付きメソッドを自分で定義するには yield 式を使います。
ソースコード
# ブロック付きメソッド
def add(x, y)
puts "begin: #{x}, #{y}"
yield(x + y) # 足した結果をブロックに渡す
puts "end: #{x}, #{y}"
end
# ブロック付きメソッドを呼び出す
add 2, 3 do |result|
puts "answer: #{result}"
end
実行結果
begin: 2, 3
answer: 5
end: 2, 3
Proc オブジェクトを使う
class Proc (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/Proc.html
ブロックをコンテキスト(ローカル変数のスコープやスタックフ レーム)とともにオブジェクト化した手続きオブジェクトです。
Proc は ローカル変数のスコープを導入しないことを除いて 名前のない関数のように使えます。ダイナミックローカル変数は Proc ローカルの変数として使えます。
ソースコード
# ブロック付きメソッド
def add(x, y)
puts "begin: #{x}, #{y}"
yield(x + y) # 足した結果をブロックに渡す
puts "end: #{x}, #{y}"
end
# Procオブジェクトを生成
header = ''
p = Proc.new{|result|
puts "#{header}: #{result}"
}
header = 'answer' # ブロック内で使う変数に値を代入
# ブロック付きメソッドを呼び出す
add 2, 3, &p
実行結果
begin: 2, 3
answer: 5
end: 2, 3
ループ処理
ソースコード
# ブロック付きメソッド
def double(array)
array.each do |e|
# 元の値と2倍した値をブロックに渡す
yield(e, e * 2)
end
end
# ブロック付きメソッドを呼び出す
double [2, 3, 5] do |src, dst|
puts "#{src} -> #{dst}"
end
実行結果
2 -> 4
3 -> 6
5 -> 10
ブロックをコールバックする
ソースコード
class Slots
def initialize()
@slots = {}
end
# マッチしたときに実行するブロックを登録する
def add(regexp, &block)
@slots[regexp] = block
end
# 文字列にマッチしたら対応するブロックを実行する
def match(str)
@slots.each do |regexp, block|
if matchdata = str.match(regexp)
puts "[match] #{block.yield(matchdata)}"
end
end
end
end
slots = Slots.new
slots.add(/hell/i) {|m| "'#{m.string}' has 'hell'."}
slots.add(/hello/i){|m| "'#{m.string}' has 'hello'."}
slots.match('He')
slots.match('HELL')
slots.match('Hello, Goodbye')
実行結果
[match] 'HELL' has 'hell'.
[match] 'Hello, Goodbye' has 'hell'.
[match] 'Hello, Goodbye' has 'hello'.
参考資料
- メソッド呼び出し(super・ブロック付き・yield) (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/doc/spec=2fcall.html
- class Proc (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/Proc.html
- class Regexp (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/Regexp.html
- 正規表現 (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html
- class MatchData (Ruby 2.4.0) https://docs.ruby-lang.org/ja/latest/class/MatchData.html