2017-11-04 5 views
0

私のコードにいくつかのスコープの問題があります。私は実際にそれらを解決する方法を知らないです。ルビーのdefine_singleton_methodの内側の外側のメソッドを参照します。

私はそれを実行し、このコード

class MainClass 

    def methodOfMainClass 
     #do something 
    end 

    def test obj 
     obj.instance_variables.map do |attribute| 
      obj.define_singleton_method(:something) do |arg| 
      self.methodOfMainClass() 
     end 
    end 
end 

を持っているが、NoMethodError提起:

#<Obj:0x0035f6274c9g12> 

のために未定義のメソッド `methodOfMainClassをはmethodOfMainClassがobjからのものではない、MainClassからです。 define_singleton_methodメソッドの中で正しいクラスを参照するにはどうすればよいですか?

はルビーself

+0

あなたはそれをどのように実行する必要があるかを示す必要があります。問題の余りに多くは残っている。レプリケートするために実行できる最小限の例を提供してください。 – Tom

+0

'MainClass'型の' obj'でも、それは別の型ですか?そうであれば、なぜそれを議論として渡していますか? – Tom

+0

thats私の問題、objは別のクラスのものです –

答えて

1

は方法ではなく、参照ですありがとうございました。 selfを呼び出すオブジェクトにシングルトンメソッドを作成して実行すると、メソッドを作成したオブジェクトではなく、実行時にそのオブジェクトが参照されます。

ここでは、あなたが尋ねていることをするものがありますが、私はそれを使用するケースを想像することはできません。 MainClassで呼び出すメソッドをクラスのシングルトンメソッド(クラスメソッド)にしてから、そのクラスの名前を他のオブジェクトのシングルトンメソッドから呼び出す。

class OtherClass 
    def initialize(ivar1: nil, ivar2: nil) 
    @ivar1 = ivar1 
    @ivar2 = ivar2 
    end 
end 


class MainClass 

    def self.methodOfMainClass 
    puts "method #{__method__} called" 
    end 

    def test(obj) 
    obj.instance_variables.map do |attribute| 
     method_name = attribute.to_s.gsub(/@/,'') 
     obj.define_singleton_method(method_name) do |arg| 
     puts "#{__method__} called with #{arg}" 
     MainClass.methodOfMainClass 
     end 
    end 
    end 

end 

my_instance = MainClass.new 
other = OtherClass.new(ivar1: 'hello', ivar2: 'world') 

my_instance.test(other) 
other.ivar1('something') 
other.ivar2('else') 

出力:また

ivar1 called with something 
method methodOfMainClass called 
ivar2 called with else 
method methodOfMainClass called 

、あなたには、いくつかの理由でクラスメソッドを作成したくない場合は、あなたがシングルトンメソッド定義の外の自己への参照を作成し、内部にそれを使用することができます。

class OtherClass 
    def initialize(ivar1: nil, ivar2: nil) 
    @ivar1 = ivar1 
    @ivar2 = ivar2 
    end 
end 


class MainClass 

    def methodOfMainClass 
    puts "method #{__method__} called" 
    end 

    def test(obj) 
    ref = self 
    obj.instance_variables.map do |attribute| 
     method_name = attribute.to_s.gsub(/@/,'') 
     obj.define_singleton_method(method_name) do |arg| 
     puts "#{__method__} called with #{arg}" 
     ref.methodOfMainClass 
     end 
    end 
    end 

end 

my_instance = MainClass.new 
other = OtherClass.new(ivar1: 'hello', ivar2: 'world') 

my_instance.test(other) 
other.ivar1('something') 
other.ivar2('else') 

出力は以前と同じですが、MainClassのインスタンスが有効範囲外になるとすぐに失敗します。

関連する問題