Почему функция в том же модуле недоступна в ruby? - PullRequest
0 голосов
/ 23 марта 2012

Допустим, у нас есть код, похожий на этот

module TM
  def aa
    puts "aa"
  end

  def bb
    TM::aa
  end

  module_function :bb
end

TM.bb

Почему bb не может получить доступ к aa независимо от "TM :: aa", "self.aa" или "TM.aa"?Они находятся в одном модуле.Какая польза от установки такого ограничения и как мне решить ошибку «неопределенный метод»?

Ответы [ 4 ]

4 голосов
/ 23 марта 2012

Вы имели в виду что-то подобное?

module TM
  class << self
    def aa
      puts "aa"
    end

    def bb
      TM::aa
    end
  end
end

TM.bb

ОБНОВЛЕНИЕ: методы, как вы их определили, будут доступны как методы экземпляра, когда вы include будете использовать методы вашего модуля или класса, если вы extend ваш класс

module TM
  def aa
    puts "aa"
  end

  def bb
    aa
  end
end

class A
  include TM
end

class B
  extend TM
end

A.new.bb

B.bb
1 голос
/ 23 марта 2012

Я думаю, вы можете быть озадачены функциональностью вызова module_function, так как этот метод фактически создает копию метода и делает исходный метод частным, и смешивает копию с мета-классом (или собственным классом в любом случай на один шаг вверх по цепочке поиска метода). Это так, что его можно переопределить, не влияя на внутреннее использование метода, то есть сделать его безопасным для частного использования, а также быть общедоступным ИЛИ общедоступным. Только копия, которая смешана с мета-классом, не может получить доступ к aa, и это потому, что aa не существует над ним в цепочке поиска. Если оба метода были переданы в функцию модуля, вы не получите неопределенную ошибку метода.

1 голос
/ 23 марта 2012

Это не работает, потому что вы определяете метод экземпляра (def aa) вместо метода модуля (def self.aa).

Ознакомьтесь с документацией:

Модуль - это набор методов и констант. Методы в модуле могут быть методами экземпляра или методами модуля. Методы экземпляра отображаются как методы в классе, когда модуль включен, а методы модуля - нет. И наоборот, методы модуля могут вызываться без создания инкапсулирующего объекта, а методы экземпляра - нет. (См. Модуль # module_function)

Итак, что вы хотите:

module TM
  def self.aa
    puts "aa"
  end

  def bb
    TM::aa
  end

  module_function :bb
end

TM.bb

1 голос
/ 23 марта 2012

Потому что aa является функцией экземпляра. Если вы добавляете его в список module_function (или используете один из многих других способов объявления методов модуля), все работает. Лично я предпочитаю:

module TM
  def self.aa
    puts "aa"
  end

  def self.bb
    TM::aa
  end

end

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