2009-04-29 16 views

答えて

40
def define_singleton_method_by_proc(obj, name, block) 
    metaclass = class << obj; self; end 
    metaclass.send(:define_method, name, block) 
end 
p = proc { "foobar!" } 
define_singleton_method_by_proc(y, :bar, p) 

か、あなたが作るために猿パッチオブジェクトにしたい場合は、それは簡単

class Object 
    # note that this method is already defined in Ruby 1.9 
    def define_singleton_method(name, callable = nil, &block) 
    block ||= callable 
    metaclass = class << self; self; end 
    metaclass.send(:define_method, name, block) 
    end 
end 

p = proc { "foobar!" } 
y.define_singleton_method(:bar, p) 
#or 
y.define_singleton_method(:bar) do 
    "foobar!" 
end 

や、あなたのPROCをインラインで定義する場合、これはより読みやすいかもしれ

class << y 
    define_method(:bar, proc { "foobar!" }) 
end 

または

class << y 
    define_method(:bar) { "foobar!" } 
end 

これはmoです。あなたは、オブジェクトの「シングルトンクラス」を取得するための構文class <<objectを使用することができますST読める、おそらくあなたのニーズに適合しない

def y.bar 
    "goodbye" 
end 

This question is highly related

15

(つまり、そのオブジェクトだけに属する特殊な親クラスだ)とそのインスタンスのメソッドだけを定義します。たとえば:あなたはstr1.to_spanishをすれば

str1 = "Hello" 
str2 = "Foo" 

class <<str1 
    def to_spanish 
    'Hola' 
    end 
end 

は今、それは「はいはい」を返しますが、str2.to_spanishはあなたにNoMethodFound例外を提供します。

+0

単純な変数に外部定義されたprocがある場合、グローバル変数またはインスタンス変数に頼らずにクラス<< str1によって作成された新しいスコープに取得することは難しい –

19

私はこれが(少なくとも1.8.7)で追加されたルビーのどのバージョンわからないんだけど、これを行うのも、簡単な方法があるように思われる:

str1 = "Hello" 
str2 = "Goodbye" 
def str1.to_spanish 
    "Hola" 
end 
puts str1 # => Hello 
puts str1.to_spanish # => Hola 
puts str2 # => Goodbye 
puts str2.to_spanish # => Throws a NoMethodError 
これについて学ぶ

読みながら、 Ruby Koans(about_class_methods.rbレッスン) 私にはちょっと危険なので、これの目的が何であるかはまだ完全にはわかりません。

+0

これを投稿していただきありがとう - 日付答え! –

+0

'str.to_spanish'が既に定義されていて、それを"再定義 "したかったとしたら、新しく定義されたstr.tospanishを元の" str.to_spanish "と呼びますか? –

+0

'str'があなたのインスタンスオブジェクトで、' String'があなたのクラスであれば、 'String.to_spanish'でメソッドのクラスのバージョンを呼び出すことができます – BRFennPocock

関連する問題