Класс Метод "Знать" имя класса в Ruby?
Я хочу, чтобы унаследованный класс ruby "знал" его имя класса с помощью метода класса. Это лучше всего иллюстрируется надуманным примером:
class Parent
def self.whoami
??
end
end
class Child < Parent
#No code should be needed.
end
Итак, я должен был бы позвонить:
Parent.whomai
и ожидаем возврата "Родительского", я должен был бы позвонить:
Child.whoami
и ожидайте возвращения "Ребенка". У меня такое ощущение, что на обычных языках это может быть невозможно. Но модель метапрограммирования Ruby поразила меня раньше. Есть предположения? Спасибо заранее.
Ответы
Ответ 1
Метод класса - это метод, в котором КЛАСС является приемником, поэтому, чтобы найти объект, на который вызывается метод (что вы пытаетесь сделать здесь), просто проверьте значение self
.
class Parent
def self.whoami
self
end
end
class Child < Parent
end
puts Parent.whoami #=> Parent
puts Child.whoami #=> Child
Ответ 2
Метод получения имени класса (фактически, модуль) - это Module#name
. Нет необходимости писать самостоятельно:
Parent.name # => 'Parent'
Child.name # => 'Child'
Однако в Ruby действительно нет такой вещи, как "имя класса", как на некоторых других языках. В Ruby класс - это просто объект, как любой другой объект, который присваивается переменной, как и любая другая переменная.
Весь метод Module#name
выполняет цикл через все константы в системе и проверяет, был ли модуль назначен кому-либо из них, и возвращает это имя константы или nil
, если оно не может найти.
Итак, как и любой другой объект, "имя" класса действительно не что иное, как любая переменная, которую вы используете для ссылки на него.
Пример:
foo = Class.new
foo.name # => nil
Теперь "имя" класса foo
. Однако Module#name
возвращает nil
, потому что foo
не является константой.
bar = foo
bar.name # => nil
Теперь "имя" класса равно как foo
и bar
, но Module#name
явно все еще возвращает nil
.
BAZ = foo
foo.name # => 'BAZ'
Теперь, поскольку класс был назначен константе, это имя константы будет считаться именем класса & hellip;
BAZ = nil
foo.name # => 'BAZ'
& hellip; даже после того, как константа была назначена на что-то другое и & hellip;
QUX = foo
QUX.name # => 'BAZ'
& hellip; даже после того, как класс был назначен другой константе.
Module#to_s
использует Module#name
, если это не nil
, поэтому, чтобы напечатать имя класса, вы просто выполняете
puts Parent
На самом деле нет абсолютно никакой потребности во всех сложных пухах в других ответах.
Ответ 3
Не то, что вам скажет Parent.class
?
class Parent
def self.whoami
self.to_s
end
end
class Child < Parent
end
> Parent.whoami
=> "Parent"
> Child.whoami
=> "Child"
Ответ 4
Предположим, вы класс:
class ABC
def self.some_method
self.name #it will return 'ABC'
self.name.constantize #it will return ABC
end
end