willnetの日記

2009-09-30

Proc#arity

20:52 | Proc#arity - willnetの日記 を含むブックマーク はてなブックマーク - Proc#arity - willnetの日記

Proc オブジェクトが受け付ける引数の数を返します。

ただし、可変長引数を受け付ける場合、負の整数-(必要とされる引数の数 + 1)を返します。

2009-09-20

フックメソッド

21:53 | フックメソッド - willnetの日記 を含むブックマーク はてなブックマーク - フックメソッド - willnetの日記

たくさんある

  • inherited
  • included
  • method_added
  • singleton_method_added
  • method_removed
  • method_undefined
  • singleton_method_removed
  • singleton_method_undefined

define_methodの欠点

21:50 | define_methodの欠点 - willnetの日記 を含むブックマーク はてなブックマーク - define_methodの欠点 - willnetの日記

define_methodには、ブロックを前提とするメソッド本体を指定できないという欠点がある。ブロックを受け付けるメソッドを動的に作るためには、class_evalとともにdef文を使わなければならない。

キーワードと同じ働きをするメソッドたち

21:49 | キーワードと同じ働きをするメソッドたち - willnetの日記 を含むブックマーク はてなブックマーク - キーワードと同じ働きをするメソッドたち - willnetの日記

キーワード対応するメソッド
defdefind_method
aliasalias_method
undefremove_method or undef_method

remove_methodとundef_methodの違い

  • remove_method 親クラスからメソッドを継承していればそれが使われるようになる
  • undef_method 親クラスからメソッドを継承していても使えなくなる(undefはこっち)

2009-09-15

respond_to?とmethod_defined?

19:01 | respond_to?とmethod_defined? - willnetの日記 を含むブックマーク はてなブックマーク - respond_to?とmethod_defined? - willnetの日記

2009-09-13

send

18:56 | send - willnetの日記 を含むブックマーク はてなブックマーク - send - willnetの日記

publicだけでなく、protectedやprivateなメソッドも呼び出せる

オーバーライドされた時用に、同義語として__send__が定義されている。削除したり再定義すると警告が表示される。

UnboundMethodオブジェクト

18:46 | UnboundMethodオブジェクト - willnetの日記 を含むブックマーク はてなブックマーク - UnboundMethodオブジェクト - willnetの日記

束縛情報のないMethodオブジェクト。メソッドを利用するためには、オブジェクトに束縛してMethodオブジェクトにしてからcallする必要がある。

unbound_plus = Fixnum.instance_method("+")

上記のようにして取得。

plus_2 = unbound_plus.bind(2)

上記のようにして束縛。

plus_2.call(2) #=> 4

上記のようにしてメソッドを起動する。

plus_3 = plus_2.unbind.bind(3)

Methodクラスのunbindメソッドを使ってもUnboudMethodオブジェクトを取得できる。

Methodオブジェクト

18:37 | Methodオブジェクト - willnetの日記 を含むブックマーク はてなブックマーク - Methodオブジェクト - willnetの日記

Procがブロックをオブジェクトにしたようなものだとしたら、Methodはメソッドをオブジェクトにしたようなもの。

o.method(:succ)

のようにして生成する。両者はほぼ同じ(callメソッドで呼び出せる)機能を持っており、両者間の変換もできるが、クロージャの有無が異なる。Methodはクロージャではない。

定義済みのメソッドの名前を返すメソッドとメソッドの有無を調べるメソッド

17:57 | 定義済みのメソッドの名前を返すメソッドとメソッドの有無を調べるメソッド - willnetの日記 を含むブックマーク はてなブックマーク - 定義済みのメソッドの名前を返すメソッドとメソッドの有無を調べるメソッド - willnetの日記

o.methods # publicメソッドの名前を返す
o.public_methods # methodsと同じ
o.public_methods(false) # 継承したメソッドを除外
o.protected_methods
o.private_methods
o.private_methods(false) # 継承したメソッドを除外
o.singleton_methods # 特異メソッドの名前を返す
Object.instance_methods
Object.instance_mehtods(false)
Object.public_instance_methods
Object.protected_instance_methods
Object.private_instance_methods(false)
Object.singleton_methods # クラスメソッドの名前を返す
Object.public_method_defined? :hoge
Object.protected_method_defined? :hoge
Object.private_method_defined? :hoge
Object.method_defined? :hoge # protectedかpublicなメソッドであればtrue

1.8では文字列配列、1.9ではシンボル配列が返る

変数の取得、設定をするメソッド

17:25 | 変数の取得、設定をするメソッド - willnetの日記 を含むブックマーク はてなブックマーク - 変数の取得、設定をするメソッド - willnetの日記

これも名前の通り

o.instance_variable_set(:@x, 0)
o.instance_variable_get(:@x)
o.instance_variable_defined?(:@x)
Object.class_variable_set(:@@x, 1) # ruby1.8だとprivate
Object.class_variable_get(:@@x) # ruby1.8だとprivate
Object.class_variable_defined?(:@@x) # ruby1.9以降
Object.const_set(:HOGE, "hoge")
Object.const_get(:HOGE)
Object.const_defined?(:HOGE)

class_variable_set, class_variable_getはruby1.8だとprivateなので

Object.class_eval do 
  class_variable_get(:@@x)
end

のような感じで使う。

ローカル変数やグローバル変数用のメソッドはないのでevalで代用する。

定義済みの変数や定数を返すメソッド

17:13 | 定義済みの変数や定数を返すメソッド - willnetの日記 を含むブックマーク はてなブックマーク - 定義済みの変数や定数を返すメソッド - willnetの日記

名前の通りに動作する。

1.8では文字列配列、1.9ではシンボル配列が返る

Object#instance_exec

17:09 | Object#instance_exec - willnetの日記 を含むブックマーク はてなブックマーク - Object#instance_exec - willnetの日記

Object#instance_execはObject#instance_evalにブロック引数が渡せるやつ。

http://d.hatena.ne.jp/rubikitch/20080507/1210149729

ブロック引数を渡せるとうれしい場面ってどんなだろうなー

Module#include

13:35 | Module#include - willnetの日記 を含むブックマーク はてなブックマーク - Module#include - willnetの日記

privateメソッドなので、selfから暗黙のうちに呼び出すことしかできない→classmodule定義の本体部でしか使えない。

クラスの判別メソッド

13:30 | クラスの判別メソッド - willnetの日記 を含むブックマーク はてなブックマーク - クラスの判別メソッド - willnetの日記

o.instance_of? c
o.class == cかどうかを判定する
o.is_a? c
oがcまたはそのサブクラスのインスタンスかどうかを判定する。cがモジュールなら、このメソッドは、o.class(あるいはその祖先)がモジュールをインクルードしているかをチェックする。
o.kind_of? c
is_a?と同じ
c === o
o.is_a? cと同じ。右側の引数がレシーバになるのは気をつけていないと忘れそう

Object#respond_to

13:23 | Object#respond_to - willnetの日記 を含むブックマーク はてなブックマーク - Object#respond_to - willnetの日記

レシーバオブジェクトが、第一引数で指定された名前のpublic, protectedメソッドを持つかどうかを判定する。第二引数にtrueを指定すると、privateメソッドもチェックする

2009-09-08

Struct::xxx#==

13:16 | Struct::xxx#== - willnetの日記 を含むブックマーク はてなブックマーク - Struct::xxx#== - willnetの日記

マニュアルにないからないのかなーと思ったけどあった。

多分それぞれのメンバで==やってるのだと思う