Kamuycikap - SentenceDataBase

日々の勉強の記録を気分で書き綴るブログ

メソッドと属性

前のセクションでは、レシーバとメソッドをドットで区切る事により、単純なインスタンスや変数と共にメソッドが使われていた。
メソッド名が記号文字の場合は、ドットが省略される。
メソッドは次の用に引数を取る事が出来る。

Time.mktime(2000,"Aug",24,16,0)

メソッド呼び出しはオブジェクトを返すので、通常はメソッド呼び出しを次の用に連結、つまり積み重ねる事が出来る。

3.succ.to_s
  /(x.z).*?(x.z).*?/.match("x1z_1a3_x2z_1b3_").to_a[1..3]
  3+2.succ

累積した式が、その特定のメソッドをサポートしていないタイプの場合は、問題が起きる可能性がある。
具体的に、メソッドの中には特定の条件下でnilを返す物があり、そのため、普通はそのメソッドに連結されたメソッドが機能しなくなる。

特定のメソッドにはブロックを渡す事が出来る。
これは組込みかユーザー定義かを問わず、全てのイテレータに当てはまる。
ブロックは普通、do-endブロック、または中括弧で区切られたブロックとして渡される。
ブロックは先行する他のパラメータとは異なる扱いを受ける。
次の、得にFile.openの例を見てほしい。

  my_array.each do |x| do
    #... 何らかの処理
  end

  File.open(filename)
  do |f|
    #... 何らかの処理
  end

名前付きパラメータは今後サポートされるらしいが、現時点ではサポートされていない。
Pythonの世界では「キーワード引数」と呼ばれている。

メソッドは、この様に可変数の引数を取る事が出来る

receiver.method(arg1,*more_args)

この場合、メソッドの引数としてarg1、more_args[0]、more_args[1]、more_args[2]、more_args[3] ... more_args[n]が指定されたのと同じ意味となる。
実際、仮パラメータリストの(最後または唯一のパラメータの)「*」(アスタリスク)は一連の実パラメータを一つの配列にまとめる事が出来る。

def mymethod(a, b, *c)
  print a, b

  c.each do |x|
    print x
  end
end

Rubyには、メソッドを(クラスごとではなく)オブジェクトごとに定義する機能がある。
この様なメソッドを「特異メソッド」と呼ぶ。
特異メソッドはそのオブジェクトのみに属し、クラスやスーパークラスでは無効になる。
例として、特異メソッドはGUIのプログラミングで役に立つ事がある。
ボタンオブジェクトに特異メソッドを定義する事で、ウィジットのボタンのアクションを定義することが出来る。

特異メソッドを利用して、プロトタイプベースのオブジェクトシステムを作成する事も理論上は可能である。
これは、クラスの無い従来と異なる形式のOOPである。
基本的な構成の仕組みは、既存のオブジェクトを譲渡先として使い、新しいオブジェクトを作成する事である。
新しいオブジェクトは、オーバーライドされているアイテムを除いて、元のオブジェクトと全く同じになる。
これにより継承ベースではなく、プロトタイプ/上位ベースのシステムを構築することが出来る。

contentsへ