目次
Procについて
Procクラスはブロックをオブジェクト化するクラスです。
つまりProcオブジェクトとは、Procクラスを利用してオブジェクト化されたブロックのインスタンスのことを指します。
ブロック単体だけではオブジェクトとして定義できないため、ブロックをオブジェクト化したい場合にProcを利用します。
Procは『オブジェクトの生成 → オブジェクトの呼び出し』の手順で実行します。
Procオブジェクトの作成方法
Procオブジェクトの作成方法について紹介します。
引数なしのProcオブジェクト作成方法
引数なしの場合は以下のようになります。なお、ブロックを定義する際は{...}
の代わりにdo ... end
を利用してもOKです。
### Proc.new パターン
proc_example = Proc.new {
# 処理
}
### proc パターン
proc_example = proc {
# 処理
}
### -> パターン
proc_example = -> {
# 処理
}
### lambda パターン
proc_example = lambda {
# 処理
}
具体的には以下のようになります。
### Proc.new パターン
message_proc_new = Proc.new {
"Hi"
}
### proc パターン
message_proc = proc {
"Hi"
}
### -> パターン
message_arrow = -> {
"Hi"
}
### lambda パターン
message_lambda = lambda {
"Hi"
}
### 実行結果
message_proc_new.call
=> "Hi"
message_proc.call
=> "Hi"
message_arrow.call
=> "Hi"
message_lambda.call
=> "Hi"
引数ありのProcオブジェクト作成方法
### Proc.new パターン
proc_example = Proc.new do |引数|
# 処理
end
### proc パターン
proc_example = proc do |引数|
# 処理
end
### -> パターン
proc_example = -> (引数) {
# 処理
}
### lambda パターン
proc_example = lambda do |引数|
# 処理
end
具体的には以下のようになります。
なお仮引数と実引数の数が異なる場合、lambda
と->
はエラーになり、Proc.new
とproc
はエラーになりません。
### Proc.new パターン
message_proc_new = Proc.new do |name|
"Hi #{name}."
end
### proc パターン
message_proc = proc do |name|
"Hi #{name}."
end
### -> パターン
message_arrow = -> (name) {
"Hi #{name}."
}
### lambda パターン
message_lambda = lambda do |name|
"Hi #{name}."
end
### 実行結果(仮引数と実引数の数が一致している場合)
message_proc_new.call("Bob")
=> "Hi Bob."
message_proc.call("Bob")
=> "Hi Bob."
message_arrow.call("Bob")
=> "Hi Bob."
message_lambda.call("Bob")
=> "Hi Bob."
### 実行結果(仮引数と実引数の数が一致していない場合)
message_proc_new.call
=> "Hi ."
message_proc.call
=> "Hi ."
message_arrow.call
# ArgumentError: wrong number of arguments (given 0, expected 1)
message_lambda.call
# ArgumentError: wrong number of arguments (given 0, expected 1)
Procオブジェクトの実行方法
Procオブジェクトの実行方法について紹介します。
引数なしのProcオブジェクト実行方法
### call パターン
proc_example.call
### yield パターン
proc_example.yield
### .() パターン
proc_example.()
### [] パターン
proc_example[]
具体的には以下のようになります。
message_proc = proc {
"Hi"
}
### call パターン
message_proc.call
=> "Hi"
### yield パターン
message_proc.yield
=> "Hi"
### .() パターン
message_proc.()
=> "Hi"
### [] パターン
message_proc[]
=> "Hi"
引数ありのProcオブジェクト実行方法
### call パターン
proc_example.call(引数)
### yield パターン
proc_example.yield(引数)
### .() パターン
proc_example.(引数)
### [] パターン
proc_example[引数]
具体的には以下のようになります。
message_proc = proc do |name|
"Hi #{name}."
end
### call パターン
message_proc.call("Bob")
=> "Hi Bob."
### yield パターン
message_proc.yield("Bob")
=> "Hi Bob."
### .() パターン
message_proc.("Bob")
=> "Hi Bob."
### [] パターン
message_proc["Bob"]
=> "Hi Bob."
メソッド内でProcオブジェクトを実行する方法
Procオブジェクトをメソッドの引数にする場合はブロック引数(&
)を利用します。
引数なしのProcオブジェクトを利用する場合
def example(&ブロック引数)
ブロック引数.call
end
具体的には以下のようになります。
def message(&block)
print "Hey Bob. "
block.call
print " to eat hamburgers."
end
message_proc = proc {
print "Let's go to McDonald's"
}
message(&message_proc)
# Hey Bob. Let's go to McDonald's to eat hamburgers.
引数ありのProcオブジェクトを利用する場合
def example(引数, &ブロック引数)
ブロック引数.call(引数)
end
具体的には以下のようになります。
def message(destination, &block)
print "Hey Bob. "
block.call(destination)
print " to eat hamburgers."
end
message_proc = proc do |destination|
print "Let's go to #{destination}"
end
message("McDonald's", &message_proc)
# Hey Bob. Let's go to McDonald's to eat hamburgers
ブロック引数の定義位置は引数の最後にする必要があります。
ブロック引数の仮引数の位置が最後でないと以下のようにシンタックスエラーとなります。
### ブロック引数の仮引数の位置が最後でないとシンタックスエラーになる
def message(&block, destination)
print "Hey Bob. "
block.call(destination)
print " to eat hamburgers."
end
# SyntaxError: unexpected ',', expecting ')'
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!