Как получить доступ к (теневой) глобальной функции в ruby - PullRequest
14 голосов
/ 21 апреля 2010

Мне было интересно, как получить доступ к глобальной функции fn в ruby ​​из класса, который также определил метод 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 ++ для доступа к глобальной области видимости, но не могу найти какую-либо информацию об этом. Наверное, я не знаю, что конкретно ищу.

1 Ответ

16 голосов
/ 21 апреля 2010

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

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

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

Object.send(:fn)

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

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

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

class Bar
  def fn
    super
  end
end

UPDATE:

Поскольку решение (2) является предпочтительным (на мой взгляд), мы можем попытаться улучшить синтаксис, определив вспомогательный метод для Object, называемый 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, второй аргумент - метод, который вы хотите вызвать, и все оставшиеся аргументы (если они есть) передаются в качестве параметров выбранному методу. 1037 *

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