(В Ruby), позволяющий методам смешанного класса получить доступ к константам класса
У меня есть класс с константой, определенной для него. Затем я определяю метод класса, который обращается к этой константе класса. Это прекрасно работает. Пример:
#! /usr/bin/env ruby
class NonInstantiableClass
Const = "hello, world!"
class << self
def shout_my_constant
puts Const.upcase
end
end
end
NonInstantiableClass.shout_my_constant
Моя проблема возникает при попытке переместить этот метод класса во внешний модуль, например:
#! /usr/bin/env ruby
module CommonMethods
def shout_my_constant
puts Const.upcase
end
end
class NonInstantiableClass
Const = "hello, world!"
class << self
include CommonMethods
end
end
NonInstantiableClass.shout_my_constant
Ruby интерпретирует метод как запрашивающий константу из модуля, а не класс:
line 5:in `shout_my_constant': uninitialized constant CommonMethods::Const (NameError)
Итак, какие волшебные трюки вам нравятся, чтобы позволить методу получить доступ к константе класса? Большое спасибо.
Ответы
Ответ 1
Это работает:
#! /usr/bin/env ruby
module CommonMethods
def shout_my_constant
puts self::Const.upcase
end
end
class NonInstantiableClass
Const = "hello, world!"
class << self
include CommonMethods
end
end
NonInstantiableClass.shout_my_constant
НТН
Ответ 2
Вероятно, стоит отметить, что вам не нужно включать модули в метакласс.
class NonInstantiableClass
Const = "hello, world!"
class << self
include CommonMethods
end
end
Ruby имеет ключевое слово extend
, которое эффективно добавляет интерфейс модулей к классу, например.
class NonInstantiableClass
Const = "hello, world!"
extend CommonMethods
end
Вам все равно нужно убедиться, что вы ссылаетесь на правую константу, используя self::Const
или const_get
, но extend <module>
- лучший способ добавить эти методы в класс.
Ответ 3
Проблема заключается в том, что если вы просто пишете Const
, ее оценивают по времени создания модуля. Вы должны использовать Module#const_get
вместо этого следующим образом: const_get(:Const)
. Это оценивается во время выполнения, когда метод выполняется. Так что это происходит в вашем классе, а не в вашем модуле.