オープンソースのオブジェクト指向プログラミング言語「Ruby」の文法を一から学ぶための入門連載。最新版の2.1に対応しています。今回は、Rubyのメタプログラミングを学ぶ上での基礎知識となるメソッド、ブロック、Proc、lambda(ラムダ)、クロージャなどの基本的な使い方について。
連載7回目に当たる前回「Rubyのオブジェクト指向におけるクラスとモジュール、継承、Mixin、アクセス制御の使い方」では、Rubyのオブジェクト指向言語としての一側面を形作る、クラスやモジュールの概要と基本的な書き方を説明しました。
クラスやモジュールを駆使して、プログラムを適切に部品化して再利用したり、コードの重複を防ぐことは、Rubyで大規模なアプリケーションを作成するために役立ちます。
連載8回目に当たる今回は、メソッドやブロックといった仕組みについて掘り下げていきます。以降の連載で解説するメタプログラミングを学ぶ上での基礎知識となるので、しっかりと学んでいきましょう。
メソッドは、Rubyにおいてオブジェクトに干渉するための唯一の方法です。これまでの連載では、メソッド以外のテーマに焦点を当てて解説するために深く言及せずにメソッドを定義して使ってきました。ここでは、メソッドの定義の方法をあらためて解説します。本稿で説明する可変長引数やキーワード引数を駆使することで、ユーザーにとってより使いやすいクラスを実装できるようになります。
メソッド定義の基本形は、「def」に続けてメソッド名を書き、引数を羅列し、メソッドの処理を並べて最後に「end」で閉じます。method01.rbに例を示しましょう。
def parrot(word) puts word end parrot("meow") parrot("bowwow") parrot("cocka-a-doodle-doo") parrot("oink")
$ ruby method01.rb meow bowwow cocka-a-doodle-doo oink
ここでは、「parrot(オウム返しの意)」というメソッドを定義しています。やっていることは簡単で、引数に与えられたオブジェクトをputsメソッドに渡して、標準出力に流しているだけです。
引数に値を与えなかった場合のために、デフォルト値を設定できます。デフォルト値は、引数名に続けて「=(イコール)」を書き、その後にデフォルト値を書きます。method02.rbに例を示します。
def parrot(word="yack-yack") puts word end parrot("meow") parrot
$ ruby method02.rb meow yack-yack
6行目では引数を省略していますが、その場合、デフォルト値として設定した「yack-yack」が出力されています。
メソッドの定義や実行時には、カッコを省略できます。method03.rbに例を示します。
def parrot1(word) puts word end def parrot2 word puts word end parrot1("meow") parrot1 "bowwow" parrot2("cocka-a-doodle-doo") parrot2 "oink"
$ ruby method03.rb meow bowwow cocka-a-doodle-doo oink
経験上、メソッドの定義時にカッコを省略する書き方はあまり見掛けません。呼び出しの際、構文解析の関係上どうしてもカッコを省略できない場合もあります。ですので、定義時には原則カッコを付け、呼び出しの際もカッコを付けるのが基本です。では、なぜカッコを省略する書き方ができるようになっているのでしょうか?
答えは簡単で、Rubyでは予約語に見えるようなものも、メソッドとして定義されていることがあるからです。
例えば、前回のクラスやモジュールの解説で、インスタンス変数に外部からアクセスするために「attr_accessor」「attr_reader」というメソッドを使うと説明しました。これらのアクセサーメソッドは、あたかもRubyの予約語のようですが、Moduleクラスで定義されている立派なメソッドです。アクセサーメソッドをカッコ付きで呼び出すとどうでしょうか。比べてみましょう。
class Rabbit attr_accessor :name, :length_of_ears end class Rabbit attr_accessor(:name, :length_of_ears) end
何となく、カッコ付きの方が「これじゃない感じ」がしないでしょうか? 実はこれが、Rubyを始めたばかりの初心者を惑わす一因になっています。何がメソッドで、何が予約語なのか、区別しにくいからです。ただ、一度分かってしまえば何ということはありません。予約語は限られているので、それ以外は全てメソッドです。
ちなみに、カッコなしで呼び出すことで予約語っぽく振る舞うメソッドは、Ruby on Railsでふんだんに用意されています。ここでは詳しく述べませんが、アクションを実行する前に実行されるメソッドを指定する「before_filter」や、値の検証のために使う「validate」メソッドなど、多岐に渡ります。詳しくはRuby on Rails入門記事を参照してください。
メソッドは必ず何らかのオブジェクトを返します。返す値は、最後に評価されたオブジェクトです。ですので、必要な場合以外には明示的にreturnを書かないことが基本です。method04.rbに例を示しましょう。
def sum(x, y) x + y end def redundant_sum(x, y) return x + y end p sum(21, 21) p redundant_sum(21, 21)
$ ruby method04.rb 42 42
ここでは、明示的にreturnを書かないメソッドsumと、明示的にreturnを書くメソッドredundant_sumを定義しています。どちらも、引数に与えられたxとyを加算した結果を返しますが、冗長なreturnを省いたsumの方がスマートです。
Copyright © ITmedia, Inc. All Rights Reserved.