【Ruby】Proc

ABOUTこの記事をかいた人

気になること&知らないことをひたすらググることを得意としています。このブログでは最近気になったことを中心に記事を書いていきます。記事には間違った情報を書かないように細心の注意を払っていますが、もし誤りがあった場合はコメントやお問い合わせフォームからご指摘いただければ幸いです。

メソッドにブロックを渡す場合はブロックの内容をyieldで実行することもできましたが、Procというオブジェクトをとして引数を受け取る方法もあります。まずはProcクラスのオブジェクトを作ってみて挙動を確かめてみます。

proc!!
3
Proc

変数「foo」に格納した「Proc」クラスのオブジェクトは「call」メソッドを使って呼び出すことができます。今回はブロック変数として与えられたものをただ単に「puts」するだけにしてみました。「call」の引数として渡した変数「str」と「num」がちゃんとputsされていますね。

メソッド内でProcオブジェクトを使う

それではメソッドを呼び出し、Procオブジェクトを使ってみましょう。

proc!!!
10

ブロックをメソッドに引数として与えるためには「&変数名」という記述でメソッドの最後の引数に付け足す感じで記述を行います。これで「yield」と同様にブロックの内容をメソッドに渡すことができるようになりました。

ちなみにこの「&変数名」として渡された引数は「Proc引数」といいます。

block_given?メソッド

block_given?メソッドはそのメソッドにブロックが渡されているかいないかで真偽値(true,false)を返してくれます。

また同様にメソッドにProcオブジェクトとして機能している変数を記述しても真偽値が返ってきます。ちなみにブロックを渡している場合はProcオブジェクトが返ってきて、なにもブロックを渡していない場合は「nil」が返ってきます。

true
#<Proc:0x000000009a71d0@C:/Users/proc.rb:6>
false
nil

上記のProcオブジェクトの挙動(真偽値のようなもの)を利用してブロックを渡したときと渡していないときに違う挙動となるスクリプトを作ってみます。というかyieldの記事のArray_Create.rbと同じ内容のスクリプトをyieldではなくProcオブジェクトを使って表現してみました。

[1, 2, 3]
[3, 6, 9]

ブロックを渡していない方のメソッドは引数で指定した「1~3」の配列ができましたが、ブロックを渡した場合はブロック内で加工した変数が配列として作成されています。今回の場合は「block.call(strat_num)」でブロック変数「a」に渡した値「1~3」をそれぞれ3倍にして返して、それを配列として作成しています。

Procオブジェクトをインスタンス内で保持

「&変数名」で渡されたProcオブジェクトはインスタンス変数に格納すると他のメソッドでもブロックを呼び出すことができます。

#<Proc:0x00000000976aa8@C:/Users/proc.rb:14>
yes!!

このように記述することで「proc_in」メソッドを実行しブロックをインスタンス変数「@pro」に格納し、その後「proc_do」メソッドにて渡したブロックを実行することもできるようになります。

&変数名のまま他のメソッドに渡す

メソッド内で「&変数名」で受け取ったブロックは、「&変数名(Procオブジェクト)」といった形で記述すると、そのまま他のメソッドにブロックとして渡すことが可能となります。

a
b
c

これでまずproc_eachメソッドを実行し、配列オブジェクトを引数として渡し、ブロックも同時に渡しています。このブロックの処理内容はそのまま「myary.each(&block)」メソッドに渡すことができて配列に入れた文字列「a,b,c」がそれぞれputsされています。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

ABOUTこの記事をかいた人

気になること&知らないことをひたすらググることを得意としています。このブログでは最近気になったことを中心に記事を書いていきます。記事には間違った情報を書かないように細心の注意を払っていますが、もし誤りがあった場合はコメントやお問い合わせフォームからご指摘いただければ幸いです。