Ограничить область действия до родителя после вызова super () - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть что-то похожее на следующее:

class A
  def foo
    bar
  end

  def bar
    puts "A"
  end
end

class B < A
  def foo
    super
  end

  def bar
    puts "B"
  end
end

Требуемый вывод должен быть в состоянии вызвать B.new.foo #=> "A".Можно ли ограничить область видимости для родителя при вызове super?Мне кажется, что это неправильно, так что, возможно, это показатель плохого дизайна, но мне любопытно, если бы это было возможно независимо.

Ответы [ 3 ]

0 голосов
/ 08 декабря 2018

Вот еще один способ сделать это, который я представляю только для образовательных целей.

class A
  def foo
    m = method(:bar)
    m = m.super_method until m.owner == A
    m.call
  end    
  def bar
    puts "A"
  end
end

class B < A
  def foo
    super
  end    
  def bar
    puts "B"
  end
end

class C < B
  def foo
    super
  end    
  def bar
    puts "C"
  end
end

B.new.foo
A
C.new.foo
A
A.new.foo
A

См. Object # method и Метод # super_method .

0 голосов
/ 08 декабря 2018

Вот другой способ.

Вы получаете A (экземпляр) метод экземпляра bar через:

um = A.instance_method(:bar)
#=> #<UnboundMethod: A#bar>

Этот метод может быть связан с текущим получателем через:

bm = um.bind(self)
#=> #<Method: A#bar>

Затем можно вызвать связанный метод:

bm.call
# "A"

В вашем коде:

class A
  def foo
    A.instance_method(:bar).bind(self).call
  end

  # ...
end
0 голосов
/ 07 декабря 2018

Проблема здесь в том, что B определяет новый bar метод, который вытесняет метод, определенный в A.Если вам нужно сохранить унаследованное поведение, вы должны создать псевдоним для этой цели:

class A
  def foo
    original_bar
  end

  def bar
    puts "A"
  end
  alias_method :original_bar, :bar
end

class B < A
  def foo
    super
  end

  def bar
    puts "B"
  end
end

Использование здесь alias_method сохраняет «копию» исходного метода, который подкласс не делает.не отменяйте.

Вы правы, хотя, это немного грязно.Вы можете объявить bar как private, чтобы его нельзя было так просто отменить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...