連載
» 2014年09月29日 18時00分 UPDATE

若手エンジニア/初心者のためのRuby 2.1入門(8):Rubyの面白さを理解するためのメソッド、ブロック、Proc、lambda、クロージャの基本 (1/3)

オープンソースのオブジェクト指向プログラミング言語「Ruby」の文法を一から学ぶための入門連載。最新版の2.1に対応しています。今回は、Rubyのメタプログラミングを学ぶ上での基礎知識となるメソッド、ブロック、Proc、lambda(ラムダ)、クロージャなどの基本的な使い方について。

[著:麻田優真、監修:山根剛司,株式会社アジャイルウェア]

※編集部注

本連載はRuby 2.1プログラミングの入門連載です。Ruby on Railsについて学びたい方は連載「開発現場でちゃんと使えるRails 4入門」をご覧ください。


メタプログラミングを学ぶ上での基礎知識

「若手エンジニア/初心者のためのRuby 2.1入門」のインデックス

連載目次

 連載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")
method01.rb
$ ruby method01.rb
meow
bowwow
cocka-a-doodle-doo
oink
method01.rbの実行結果

 ここでは、「parrot(オウム返しの意)」というメソッドを定義しています。やっていることは簡単で、引数に与えられたオブジェクトをputsメソッドに渡して、標準出力に流しているだけです。

引数のデフォルト値

 引数に値を与えなかった場合のために、デフォルト値を設定できます。デフォルト値は、引数名に続けて「=(イコール)」を書き、その後にデフォルト値を書きます。method02.rbに例を示します。

def parrot(word="yack-yack")
  puts word
end
 
parrot("meow")
parrot
method02.rb
$ ruby method02.rb
meow
yack-yack
method02.rbの実行結果

 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"
method03.rb
$ ruby method03.rb
meow
bowwow
cocka-a-doodle-doo
oink
method03.rbの実行結果

 経験上、メソッドの定義時にカッコを省略する書き方はあまり見掛けません。呼び出しの際、構文解析の関係上どうしてもカッコを省略できない場合もあります。ですので、定義時には原則カッコを付け、呼び出しの際もカッコを付けるのが基本です。では、なぜカッコを省略する書き方ができるようになっているのでしょうか?

 答えは簡単で、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)
method04.rb
$ ruby method04.rb
42
42
method04.rbの実行結果

 ここでは、明示的にreturnを書かないメソッドsumと、明示的にreturnを書くメソッドredundant_sumを定義しています。どちらも、引数に与えられたxとyを加算した結果を返しますが、冗長なreturnを省いたsumの方がスマートです。

       1|2|3 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。