Например:
class Animal
def make_noise
print NOISE
end
end
class Dog < Animal
NOISE = "bark"
end
d = Dog.new
d.make_noise # I want this to print "bark"
Как мне выполнить вышеуказанное? В настоящее время написано
uninitialized constant Animal::NOISE
Я думаю, что вы действительно не хотите постоянную; Я думаю, что вы хотите переменную экземпляра для класса:
class Animal
@noise = "whaargarble"
class << self
attr_accessor :noise
end
def make_noise
puts self.class.noise
end
end
class Dog < Animal
@noise = "bark"
end
a = Animal.new
d = Dog.new
a.make_noise #=> "whaargarble"
d.make_noise #=> "bark"
Dog.noise = "WOOF"
d.make_noise #=> "WOOF"
a.make_noise #=> "whaargarble"
Однако, если вы уверены, что хотите постоянную:
class Animal
def make_noise
puts self.class::NOISE
# or self.class.const_get(:NOISE)
end
end
Я думаю, у вас неправильная концепция. Классы в Ruby похожи на классы в Java, Smalltalk, C #, ... и все являются шаблонами для своих экземпляров. Таким образом, класс определяет структуру и поведение его экземпляров, а также части структуры и поведения экземпляров его подклассов , но не наоборот .
Так что прямой доступ из суперкласса к константе в подклассе вообще невозможен, и это хорошо. Смотрите ниже, как это исправить. Для ваших классов определены следующие вещи:
class Animal
определяет метод make_noise
. class Animal
могут вызывать метод make_noise
. class Dog
определяет константу NOISE
с ее значением. Dog
и сам класс Dog
могут использовать константу NOISE
. Что невозможно:
Animal
или сам класс Animal
имеют доступ к константам класса Dog
. Вы можете исправить это следующим изменением:
class Animal
def make_noise
print Dog::NOISE
end
end
Но это плохой стиль, потому что теперь ваш суперкласс (который является абстракцией о Dog
и других животных) теперь знает то, что принадлежит Dog
.
Лучшим решением было бы:
Animal
, который определяет, что должно быть определено make_noise
. См. Ответ https://stackoverflow.com/a/6792499/41540 .