Как получить доступ к (затененной) глобальной функции в рубине

Я задавался вопросом, как получить доступ к глобальной функции fn в рубине от класса, который также определил метод fn. Я сделал обходное решение путем искажения функции как так:

def fn
end

class Bar
    alias global_fn fn
    def fn
        # how to access the global fn here without the alias
        global_fn
    end
end

Я ищу что-то вроде C++:: к глобальной области видимости доступа, но я, может казаться, не определяю местоположение никакой информации об этом. Я предполагаю, что не знаю конкретно, что я ищу.

15
задан Yngve Hammersland 21 April 2010 в 10:02
поделиться

1 ответ

На верхнем уровне a def добавляет частный метод к Object .

Я могу придумать три способа получить функцию верхнего уровня:

(1) Используйте send , чтобы вызвать закрытый метод для самого объекта (работает только в том случае, если метод не является мутатором, поскольку Object будет получателем)

Object.send(:fn)

(2) Получить экземпляр Method метода верхнего уровня и привязать его к экземпляру, который вы хотите вызвать это на:

class Bar
  def fn
    Object.instance_method(:fn).bind(self).call
  end
end

(3) Используйте super (предполагается отсутствие суперклассов Bar ниже Объект , переопределите функцию)

class Bar
  def fn
    super
  end
end

ОБНОВЛЕНИЕ:

Поскольку решение (2) является предпочтительным (на мой взгляд), мы можем попытаться улучшить синтаксис, определив служебный метод для объекта под названием super_method :

class Object
  def super_method(base, meth, *args, &block)
    if !self.kind_of?(base) 
      raise ArgumentError, "#{base} is not a superclass of #{self}" 
    end

    base.instance_method(meth).bind(self).call(*args, &block)
  end
end

Используйте следующий метод :

class Bar
  def fn
    super_method Object, :fn
  end
end

Где первый аргумент super_method должен быть допустимым суперклассом Bar , второй аргумент - это метод, который вы хотите вызвать, и все остальные аргументы (если есть). вместе с параметрами для выбора cted метод.

17
ответ дан 1 December 2019 в 04:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: