Как мне вызвать метод суперкласса - PullRequest
28 голосов
/ 02 апреля 2010

У меня есть два класса A и B. Класс B переопределяет метод foo класса A. Класс B имеет метод bar, в котором я хочу вызвать метод foo суперкласса. Каков синтаксис для такого вызова?

class A    
 def foo
   "hello"
 end    
end


class B < A
 def foo
  super + " world"
 end

 def bar
   # how to call the `foo` method of the super class?
   # something similar to
   super.foo
 end
end

Для методов класса я могу вызывать методы вверх по цепочке наследования путем явного префикса имени класса. Интересно, есть ли подобная идиома для методов экземпляра.

class P
 def self.x
   "x"
 end
end

class Q < P
 def self.x
   super + " x"
 end

 def self.y
   P.x
 end
end

Редактировать Мой вариант использования является общим. Я знаю, что для конкретного случая я могу использовать технику alias. Это обычная функция в Java или C ++, поэтому мне интересно знать, возможно ли это сделать без добавления дополнительного кода.

Ответы [ 5 ]

29 голосов
/ 10 февраля 2015

В Ruby 2.2 вы можете использовать Method#super_method сейчас

Например:

class B < A
  def foo
    super + " world"
  end

  def bar
    method(:foo).super_method.call
  end
end

Ссылка: https://bugs.ruby -lang.org / Issues / 9781 # Change-48164 и https://www.ruby -forum.com / topic / 5356938

23 голосов
/ 25 апреля 2011

Вы можете сделать:

 def bar
   self.class.superclass.instance_method(:foo).bind(self).call
 end
13 голосов
/ 02 апреля 2010

В этом конкретном случае вы можете просто alias :bar :foo до def foo в class B переименовать старую foo в bar, но, конечно, вы можете использовать псевдоним для любого имени, которое вам нравится, и вызывать его от этого. В этом вопросе есть несколько альтернативных способов сделать это дальше по дереву наследования.

5 голосов
/ 02 апреля 2010

Вы можете alias old_foo foo перед переопределением, чтобы сохранить старую реализацию под новым именем. (Технически возможно взять реализацию суперкласса и связать ее с экземпляром подкласса, но это хакерский, совсем не идиоматичный и, вероятно, довольно медленный процесс загрузки для большинства реализаций.)

0 голосов
/ 17 мая 2018

На основании ответа @ Sony.

В случае, если вы хотите вызвать метод method для некоторого my_object и он уже переопределен где-то на несколько классов выше (как для Net::HTTPRequest#method), вместо выполнения .superclass.superclass.superclass используйте:

Object.instance_method(:method).bind(my_object)

Как это:

p Object.instance_method(:method).bind(request).call(:basic_auth).source_location
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...