1
class A
  def self.a
    puts "self: #{self}; superclass: #{superclass}"
  end
end

class B < A
  class << self; undef_method(:a); end  # I'm not allowed to use B.a
  def self.b
    # here I want to call A.a with B as self.
  end
end  

A.a  #=> self: A; superclass: Object
B.b  #=> self: B; superclass: A (expected)

解決策は必要ありませんalias_method。私はこのようなものを探しています。

アップデート

ソリューションは、上記のリンクと同様である必要はありません。それは単なる提案です。たとえば、私は次のことを試みました。

class B < A
  def self.b
    instance_eval(&A.method(:a).to_proc)
  end
end

しかし、このようにして、Ruby1.8.7ArgumentErrorで奇妙なことが起こります。

4

3 に答える 3

2

リンクしたSuperProxyアプローチを使用して実行できるとは思いません。

この場合、A.method(:a)はシングルトンメソッドです。シングルトンメソッドは、それが作成されたオブジェクトにのみバインドできます。特に、にリバウンドすることはできませんB

これが私が試した最初の機能しないアプローチです:

class B < A
  def self.b
    A.method(:a).unbind.bind(self).call
  end
end

2番目の非機能的アプローチ:

class B < A
  class << self
    define_method :b, A.method(:a)
  end
end

どちらも「TypeError:別のオブジェクトにバインドされたシングルトンメソッド」例外を生成します。

于 2011-04-25T04:43:59.457 に答える
2

派生クラスBのメソッドを呼び出す場合、派生クラスのインスタンスに関しては、AインスタンスオブジェクトとBインスタンスオブジェクトの間にまったく違いはありません。それらはまったく同じオブジェクトです。

したがって、インスタンスメソッドを検討する場合、オブジェクトは1つだけです。ご存知のように、少し注意が必要な場合は、親クラスで定義されているメソッドを呼び出すことは概念的に可能ですが、もちろん、派生クラスを自己インスタンスとして使用します。「A」オブジェクトと「B」オブジェクトを区別する方法はありません。インスタンスは1つだけで、AとBは「同じ」です。ただし、クラスメソッドの場合、リバウンドインスタンスメソッドと並行して単に言及されたものは存在しません。

今、あなたはクラスメソッドについて話している。クラスメソッドの場合、ご存知のように、selfはクラスです。インスタンスは無意味です。クラスAまたはそのメタクラスがselfでないと、クラスメソッドAを呼び出すことはできません。

つまり、参照されたトリックが機能する理由は、オブジェクトが1つしかないためであり、派生インスタンスの場合は、派生クラスから名前が付けられます。派生していない親クラスの2番目のインスタンスを作成せずに、反対のことを行う方法はありません。しかし、クラスメソッドを呼び出しているので、それらは..まあ..クラスメソッドであるため、派生クラスを参照することはできません。正確には、あなたが望むものをどのように定義することができますか?

于 2011-04-25T04:51:29.370 に答える
1

ここでの唯一の解決策は、を使用することB.aです。

class B < A
  def self.b
    a #=> self: B; superclass: A
  end
end  
于 2011-08-18T06:12:20.533 に答える