Ruby - Как имитировать супер для метода класса? - PullRequest
0 голосов
/ 25 апреля 2011

В (авто) образовательных целях я пытаюсь имитировать поведение super, чтобы узнать, как оно работает.

Я мог бы имитировать super для методов экземпляра, но я не мог сделать это для методов класса.

Вот мой код:

class A
  def aa
    @msg ||= 'Original...: '
    puts "#{@msg}#{self}.aa: #{self.class} < #{self.class.superclass}"
  end
  def self.ab
    @msg ||= 'Original...: '
    puts "#{@msg}#{self}.ab: #{self} < #{self.superclass}"
  end
end

class B < A
  def aa
    @msg = "Real super.: "
    super
  end
  def self.ab
    @msg = "Real super.: "
    super
  end
  def mimic_aa
    @msg = "Mimic super: "
    self.class.superclass.instance_method(:aa).bind(self).call
  end
  def self.mimic_ab
    @msg = "Mimic super: "
    #superclass.method(:ab).unbind.bind(self).call
      #=> Error: singleton method only works in original object

    #superclass.ab
      #=> self is A; I want self to be B

    proc = superclass.method(:ab).to_proc

    #self.instance_eval(&proc)
      #=> ArgumentError: instance_eval seems to call aa(some_unwanted_param)
      # Note: Ruby 1.8.7

    #eval('proc.call', binding)
      #=> self is A; I want self to be B

  end
end

a = A.new
b = B.new

a.aa         #=> Original...: #<A:0xb77c66ec>.aa: A < Object
b.aa         #=> Real super.: #<B:0xb77c6624>.aa: B < A
b.mimic_aa   #=> Mimic super: #<B:0xb77c6624>.aa: B < A

puts ''

A.ab         #=> Original...: A.ab: A < Object
B.ab         #=> Real super.: B.ab: B < A
B.mimic_ab   #=> (expected the same as above)

Есть идеи?

1 Ответ

1 голос
/ 13 декабря 2011

Что ж, проблема, вероятно, в версии Ruby, которую вы используете. Я бегу 1.9.2, и программа работает, как ожидалось. Я думаю (из комментария в вашем коде), что проблема в том, что вы используете Ruby v1.8.7. Также не мешало бы снова запустить ваш код.

...