トップ «前の日記(2006年08月03日) 最新 次の日記(2006年08月06日)» 編集

ohai日誌

2003|12|
2004|01|02|03|04|05|06|07|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|06|08|10|11|
2008|01|02|03|04|05|07|09|
2009|01|02|
2013|06|12|
2014|01|02|03|04|06|09|10|12|
2015|04|
2016|09|
2018|02|

2006年08月04日

_ __send__ と Methodクラス

今回は __send__ と Method クラスについてです。 senf、__send__はメソッド名を表す文字列もしくはシンボルで、任意のメソッドを 起動するメソッドです。 sendは例えばメールクラスを作ったときなどに使いたい名前でしょうから、 基本的には __send__ を使ったほうが良いでしょう。

"foo,bar,baz".__send__(:split, /,/) # => ["foo", "bar", "baz"]

などとして利用します。 このメソッドは「メソッド」もしくは「メソッド名」を抽象するために使えます。 利用法は多岐に渡りますが、ここでは例えばSymbol#to_procなどが挙げられるでしょう。

class Symbol
  def to_proc
    proc{|*args| reciever = args.shift; reciever.__send__(*args)}
  end
end

以前この日記で書いたSymbol#[]というかbindも 一つの例として挙げられます。 他にも例えばdrubyなどで使われます。他の利用方として、 次回にはdefine_methodと組み合わせる例も出す予定です。

またこれと関連するものにMethodクラスがあります。 これはC#のdelegateみたいなものです。メソッドとレシーバの組を持つ オブジェクトで、callメソッドでそのメソッドの呼出しができます。

m = "foo, bar, baz".method(:split)
m.call(/,/) # => ["foo", " bar", " baz"]
m.call(/ /) # => ["foo,", "bar,", "baz"]

とこのように利用できます。 手続きオブジェクトのほうが汎用的に利用できるため、こちらはあまり利用されません。 ただ、環境を保存しなくてよい分だけ手続きオブジェクトより生成に必要なコストは 小さいという利点があります。 また、to_procメソッドを持っているため、

filenames.all?{|filename| valid?(filename)}

filenames.all?(&method(:valid?))

などと書くこともできます。

他にもUnboundMethodというのがあるのですが、正直使ったことがありません。 メソッドを「名前」ではなく「実体」で持ち運びたいときに利用するのでしょう。

次回はdefine_method、Rubyの世界を大きく広げてくれるこのメソッドについて 書こうかと思います。

本日のツッコミ(全2件) [ツッコミを入れる]
_ babie (2006年08月05日 11:37)

面白いです。勉強会でやってみませんか?

_ ohai (2006年08月06日 22:33)

じゃあそのうちにでも


トップ «前の日記(2006年08月03日) 最新 次の日記(2006年08月06日)» 編集