概要
lambda や Proc の使い方をメモがてら紹介します
環境
- macOS 10.15.7
- Ruby 2.7.1p83
lambda を使って Proc オブジェクトを作成する
まずは基本中の基本です
lambda メソッドにブロックを渡すと Proc オブジェクトが返ってきます
それを変数に格納してあとから call メソッドを呼び出すことでブロックに定義した処理を実行することができます
my_lambda = lambda do
puts 'ok'
end
puts my_lambda1.class
my_lambda.call
引数付きの lambda
lambda には引数を与えることもできます
ブロックを定義する際にブロック引数を与えることで call 時に引数を与えることができます
my_lambda = lambda do |val|
puts val
end
my_lambda.call('hello')
作成した Proc オブジェクトをメソッドに与える
Proc オブジェクトを引数としてメソッドに渡すこともできます
受け取るメソッドは &block
という感じで Proc オブジェクトを受け取れるようにするだけです
my_lambda = lambda do |val|
puts val
end
def test_lambda_arg(val, &block)
block.call(val)
# yield(val)
end
test_lambda_arg('hello', &my_lambda)
メソッドに Proc オブジェクトを渡す場合は &
を付与してブロックとして渡します
メソッドは受け取った Proc オブジェクトに対して call メソッドを呼び出すだけです
また別の呼び方として受け取った Proc オブジェクトを yield とするだけでも呼び出すことができます (更に言うと引数の &block
も省略できます、ここでは紹介しないので詳しくはこちらなどを参照してください)
クラスのインスタンス変数として Proc オブジェクトを管理する
Proc オブジェクトは当然インスタンス変数としても管理できます
先程紹介したように yield を使うこともできます
class Test
def initialize(&block)
@block = block
end
def my_call(val)
@block.call(val)
end
end
my_lambda = lambda do |val|
puts val
end
t = Test.new(&my_lambda)
t.my_call('hello')
initialize に Proc オブジェクトを渡す
応用テクニックの一つとして initialize に Proc オブジェクトを渡すことでインスタンス変数の初期化などを行うこともできます
class Test
attr_accessor :val1, :val2
def initialize(&block)
block.call(self)
end
def print()
puts @val1
puts @val2
end
end
t = Test.new do |obj|
obj.val1 = 'val1'
obj.val2 = 'val2'
end
t.print
クラス側ではブロックで初期化されるであろうインスタンス変数を attr_accessor
で事前に定義しておく必要がります
また initialize 内では引数として受け取った Proc オブジェクトに self を与えることで自信のクラスのインスタンス変数を参照できるようにします
initialize に引数をわざわざ追加する必要がなくなるのでコードの修正が小さくなるのがメリットかなと思います
最後に
lambda と Proc オブジェクトの基本的な使い方を紹介しました
これ以外にもスコープの話などのあるので詳しくは参考サイトにある公式のドキュメントが参考になると思います
0 件のコメント:
コメントを投稿