52日目
今日の学習
Ruby
Ruby本の第10章を学習。昨日はyield
までを学んだ。
Proc
Proc
クラスは、ブロックをオブジェクト化するためのクラス。なので、Proc
クラスのインスタンスといえば、ブロック(何らかの処理の塊)を指す。
Proc
クラスのインスタンス(オブジェクト)を生成するには、Proc.new
を用いる。
hello_proc = Proc.new do 'hello' end # do...endではなく下の書き方でもOK hello_proc = Proc.new { 'hello' }
生成したProc
オブジェクトは実行されてはじめて効力を持つ。call
メソッドを使用して呼び出す。
# 先ほど作ったProcオブジェクト hello_proc.call #=> hello
実行時に引数を利用するProc
オブジェクトを定義することもできる。
add_proc = Proc.new do |a, b| a + b end # もしくは add_proc = Proc.new { |a, b| a + b } add_proc.call(10, 20) #=> 30 # 初期値をつけておくことも可能 add_proc = Proc.new { a = 10, b = 20| a + b }
また、Proc.new
を用いずとも、proc
メソッドを利用することでも生成できる。
# Proc.newを利用しない add_proc = proc { |a, b| a + b }
Procオブジェクトをブロックの代わりに渡す
Proc
オブジェクトとブロックの異なる点は、Proc
オブジェクトにした場合はオブジェクトとして扱うことができる点。
これで、変数に入れて別のメソッドに渡したり、Proc
オブジェクトに対してメソッドを呼び出すことができる。
前回、ブロックを引数として受け取る学習をしたが、ここで使ったarity
メソッドは、実はProc
クラスのインスタンスメソッドらしい。
つまり、arity
メソッドを呼び出すときにブロックがProc
オブジェクトに変化しているということらしい。
このとき利用していたブロックの部分を代わりにProc
に置き換えるというテクニックをRuby本では紹介してある。
あらかじめ作成したProc
オブジェクトを渡す場合にも、手前に&
をつける必要がある(&
がないと普通の引数が渡されたとみなされる)。
例 greeting(&hello_proc)
また、Ruby本ではProcオブジェクトを普通の引数として渡す方法についても説明してある。
引数として渡す場合は、逆に&
をつけないようにする。
メソッドが受け取れるブロックは最大で1つだが、Proc
オブジェクトの場合は、ただのオブジェクト扱いになるため、引数として渡すぶんには最大数に制限がない。
(あまりにも全部そのまま引用してしまうことを避けるためこのような記述で済ませることにする)
Proc.newとラムダ
上ではすでに2つのProc
オブジェクトの作成方法を学習した。
Proc.new
を用いるproc
メソッドを用いる
このほかにもまだ二種類あり、どの方法を使っても作成されるものはProc
クラスのオブジェクトになるが、以下の方法で作成したものは挙動が異なるらしい。
lambda
メソッドを用いる
lambda { |a, b| a + b }
->
構文を用いる(アロー演算子と呼ばれる)
->
はラムダ
を作成するためのラムダリテラル
->(a, b) { a + b } # かっこは省略可能 -> a, b { a + b } # do...endも使用可能 ->(a, b) do a + b end # 引数がなければ全て省略可能 -> { 'hello' }
上二つの場合、引数のあるメソッドを呼び出す際に、引数の過不足があってもエラーが起こったりしない。
しかし、下二つのラムダ
で作成しているProc
オブジェクトは、引数の数に対して厳密なチェックが行われる。よって、引数の過不足があればエラーが発生するようになっている。
Proc
オブジェクトがラムダ
かどうかを調べたい場合は、lambda?
メソッドを利用する。ラムダ
であればtrueになる。