RubyのブロックオブジェクトProcの詳細解説
2022-01-30 16:34:55
Proc オブジェクト
Procは、ブロックから変換されるオブジェクトである。Procを作成する方法は、以下の4つです。
コード例
# Method 1
inc = Proc.new { | x | x + 1}
inc.call(2) #=> 3
# method 2
inc = lambda {| x | x + 1 }
inc.call(2) #=> 3
# method 3
inc = ->(x) { x + 1}
inc.call(2) #=> 3
# method 4
inc = proc {|x| x + 1 }
inc.call(2) #=> 3
上記4つの他に、&演算子を使ってコードブロックをProcオブジェクトに変換する方法があります。コードブロックをメソッドのパラメータとして渡す必要がある場合、このパラメータに & 記法を追加することで行う必要があり、その位置はパラメータの最後である必要があります。
この&という記号は、次のような意味です。これはブロックとして使用したいProcオブジェクトです。この&記号を削除すると、再びProcオブジェクトが得られます。
コード例
def my_method(&the_proc)
the_proc
end
p = my_method {|name| "Hello, #{name} !"}
p.class #=> Proc
p.call("Bill") #=> "Hello,Bill"
def my_method(greeting)
"#{greeting}, #{yield}!"
end
my_proc = proc { "Bill" }
my_method("Hello", &my_proc)
留意点
ブロックを使うときは、裏方のワーカーと位置づけるprocの存在を無視します。私はよく、次のようなコードを書きます。
def f(...)
...
yield
...
end
def f(... , &p)
...
p.call
...
end
def f(... , &p)
instance_eval &p
...
end
def f(... , &p)
...
defime_method m, &p
...
end
初心者の中には、次のようなコードを書いて、実行時にエラーを報告する人がいます。
def f(... , &p)
instance_eval p
end
def f(... , p)
instance_eval p.call
end
また、このように書かれています。
def f(... , &p)
instance_eval do
p.call
end
end
または
def f(...)
instance_eval do
yield
end
end
というようなコードも書いたことがあります。
def f(...)
instance_eval yield
end
ブロックをぶら下げるべきなのにprocオブジェクトを引数としてメソッドに渡してしまったり、&pがブロックでありメソッドに直接与えられることを理解していなかったり、ブロックとprocをきちんと区別せず、&pはブロック、pはproc、最終手段として明示的にprocを作らないという失敗をしたことがあります。ブロックとprocの関係に迷ったときは、数行読むだけでいいんです。
関連
-
Railsにフィールド暗号化ストレージを実装
-
Rubyの二分探索(dichotomous search)アルゴリズムの簡単な例
-
Rubyにおけるフックメソッドとメソッド呼び出しへのフックの追加例
-
Rubyオブジェクト指向プログラミングにおけるクラスメソッドとクラスエクステンション
-
モンキーパッチのプログラミングスタイルとRubyでの利用について
-
RubyのHash構造体の基本操作のまとめ
-
RubyプログラムにおけるXMLファイルの作成と解析のための方法
-
Ruby on Railsのパフォーマンスを最適化するためのいくつかの方法についての考察
-
ブログのスパムメッセージを簡単にブロックする方法
-
Rubyプログラミングにおけるアサインメント関連操作
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
挿入ソートアルゴリズムのRuby実装と高度な双方向挿入ソートコード例
-
Rubyのオブジェクト指向プログラミングでクラスとメソッドの基本を学ぶ
-
Ruby on RailsのWebプロジェクト構築のためのシンプルガイド
-
Rubyプログラムにおける正規表現の基本的な使い方に関するチュートリアル
-
Rubyのinstance_evalメソッドとclass_evalとの比較
-
Jekyll静的ウェブサイトのバックエンドエンジンのチュートリアル
-
RubyのXMLデータパースライブラリ「Nokogiri」の高度な使い方
-
Rubyのデザインパターン開発におけるProxyパターンの利用について
-
RubyのSimple FactoryパターンとFactory Methodパターンを利用する
-
Rubyでコレクションを書くためのガイド