Rubyでlambdaメソッドを使うことで、メソッドの後ろで処理を定義するブロックをオブジェクトとして扱えるのをご存じでしょうか。Rubyのようなオブジェクト指向言語では、メソッドに処理を受け渡すブロックがよく使われます。そのようなブロックをオブジェクトにして、使いまわせるのがamdbdaメソッドの機能です。
今回はブロックの使い方とlmabdaメソッドでブロックをオブジェクトにする方法について解説します。
Rubyで使えるブロックの基本
Rubyには「ブロック」という仕組みがあり、これはメソッドの引数に処理を渡す書き方でよく使われます。オブジェクト指向のスクリプト言語であるRubyらしい機能の1つと言えるでしょう。
今回紹介するlambdaはブロックを扱うためのメソッドです。まずはブロックについて解説します。
ブロックはメソッドの引数
Rubyでは、変数に対する処理を「.」に続けて記述するメソッドで指定できます。さらにそのメソッドでは引数を指定できるものが多く、その中には引数として処理そのものを指定できるメソッドもあります。
例えば下の例を見てください。
arr = [1, 2, 3, 4] sum = 0 arr.each do |x| sum += x end p sum
この処理のeachメソッドは、引数として「do |x| sum += x end」をいう処理を受け取り実行します。この「do」から「end」までの処理のことをブロックと呼びます。
ブロックの範囲
先ほど、「do」から「end」までの処理のことをブロックと説明しましたが、ブロックの範囲を「{」と「}」で指定することも可能です。例えば、下記のように「do」から「end」までのブロックを「{」と「}」で書き換えられます。
ブロックを使った例
arr.each do |x| sum += x end arr.each { |x| sum += x }
Rubyのブロックをオブジェクトにできる
簡単なブロックであればメソッドの引数として記述した方が見やすいプログラムを作れます。しかし、簡単なブロックだけとは限りません。同じブロックを幾つもの箇所で使いたいケースもあります。
Rubyではブロックをオブジェクトとして登録しておき、それをプログラムの中で使用することが可能です。そして、その仕組みの1つがlambdaメソッドです。
ブロックをオブジェクトにする方法
先ほど説明したようにブロックはメソッドの引数として処理を渡せる機能です。もし同じような処理が複数あるのなら、あらかじめそれを定義しておき、それを使いまわせます。そしてRubyにはこのための機能が用意されており、それがProcとlambdaです。
次からブロックをオブジェクトに登録して、プログラムの中で使いまわす方法について紹介します。
Procクラスを使う
ブロックをオブジェクトに登録してプログラム内で利用できる方法が、Procクラスのオブジェクトを作る方法です。newメソッドでブロックを指定してオブジェクトを作れば、そのオブジェクトのcallメソッドでそのブロックを呼び出せます。
Procクラスのオブジェクトの定義方法
オブジェクト名 = Proc.new ブロック
Proc.newで作ったオブジェクトを呼び出す際はcallを使います。
Procクラスのオブジェクトの使い方
オブジェクト名.call
Procを用いたブロックを定義する例
nameconn = Proc.new do |a, b| a + "." + b end ans = nameconn.call("my", "name") p ans # "my.name"が表示される
この例では、Proc.newの処理により、”my”と”name”が”.”で接続されるので、my.nameが表示されます。
Proc.newはprocで書き換えできる
先ほど説明したProcクラスによるオブジェクト定義は、procメソッドで書き換えられます。なお、このprocメソッドは、Kernelクラスという特殊なクラスのメソッドで、先ほどのProcクラスとは別の機能です。
Procクラスのオブジェクトをprocで置き換えた例
nameconn = proc do |a, b| a + "." + b end ans = nameconn.call("my", "name") p ans # "my.name"が表示される
procの代わりにlambdaを使う
先ほどブロックをオブジェクトにするProc.newと同じ機能を、procメソッドで書き換えられると紹介しましたが、procメソッドの別名もあります。それが今回紹介するlambdaメソッドです。
つまりlambdaメソッドとは、クラスをオブジェクトに定義して、使いまわすためのメソッドです。なお、定義したブロックを呼び出すには、Proc.newと同じくcallを使います。
lambdaを用いたブロックを定義する例
nameconn = lambda do |a, b| a + "." + b end ans = nameconn.call("my", "name") p ans # "my.name"が表示される
なお、この例については後で詳しく解説します。
ブロックを作るlambdaメソッドの基本
先ほど説明したようにRubyのメソッドの引数として処理を渡す際に使用するのがブロックです。そして、lambdaメソッドを利用することで、同じブロックをプログラムの中で使いまわせます。
次からlambdaメソッドの基本について解説します。
lambdaメソッドの文法
今回紹介するlambdaは、lambdaに続けてブロックの処理を記述し、それをブロック名に紐づけて、他で再利用できるようにメソッドです。
lambdaの文法
ブロック名 = lambda ブロック
lambdaで作ったオブジェクトを呼び出す際はcallを使います。
lambdaで宣言したブロックを呼び出す方法
ブロック名.call
ブロックには、「do」と「end」の間、または「{」と「}」の間に処理を記述できます。また、|x|のように引数で渡す変数を宣言し、ブロック内で使用することも可能です。そして、lambdaメソッドで宣言したブロックは、そのブロック名に「.call」を付けて呼び出します。
lambdaメソッドの使用例
先ほど説明したlambdaメソッドを使う例を次に紹介します。
lambdaを用いたブロックを定義する例
nameconn = lambda do |a, b| a + "." + b end ans = nameconn.call("my", "name") p ans # "my.name"が表示される
この例では、lambdaメソッドを使い、nameconnというブロック名でブロックを宣言しています。内容は、「a + “.” + b」で、この処理で使う引数はaとbの2つです。そして、このブロックを「nameconn.call(“my”, “name”)」で呼び出し、その結果を変数に格納し表示しています。
lambdaメソッドはアロー演算子で代用できる
先ほどlambdaメソッドの使い方を紹介しましたが、このメソッドはアロー演算子「->」で代用できます。Rubyの特徴は、短く読み易いプログラムが書ける点ですが、アロー演算子はRubyらしい書き方の1つです。
次からアロー演算子を使ったブロックの宣言の仕方について説明します。
アロー演算子の使い方
アロー演算子はLambdaメソッドの代用ですが、ブロックの中で使う引数の指定方法が違います。lambdaメソッドではブロック内に||を用いて引数を宣言しましたが、アロー演算子ではブロックの中ではなくブロックの前に()の中に書きます。
アロー演算子の文法
ブロック名 = -> (引数) do ブロック end
先ほどのlambdaメソッドで記述した例は、次のように書き換えることが可能です。
lambdaの例
nameconn = lambda do |a, b| a + "." + b end
アロー演算子の例
nameconn = -> (a, b) do a + "." + b end
まとめ
これまで紹介したように、lambdaメソッドはメソッドをオブジェクトとして登録し、ブログラムの中で使いまわせるようにするメソッドです。
Rubyのオブジェクト指向プログラムらしい書き方の1つとも言えるブロックですが、引数に処理を引き渡す機能のため、毎回指定しなければなりません。それをオブジェクトにして使いまわせれるようにしたのがこのlambdaメソッドです。
さらにlambdaメソッドと同じ機能として、procメソッドやアロー演算子もあります。ぜひ、今回紹介したlambdaメソッドをうまく活用してください。