Вы просили различные способы создания методов класса. Вот некоторые.
class A
def self.a
"A"
end
end
A.a #=> "A"
class B
class << self
def b
"B"
end
end
end
B.b #=> "B"
class C
singleton_class.class_eval do
def c
"C"
end
end
end
C.C#=> "C"
module M
def m
"M"
end
end
class D
extend M
end
D.m #=> "M"
class E
class << self
include M
end
end
E.m #=> "M"
class F
singleton_class.instance_eval do
define_method(:f) do
"F"
end
end
end
F.f #=> "F"
Если :f
будет создаваться динамически,
class F
end
F.singleton_class.instance_eval do
define_method(:f) do
"F"
end
end
или вариант:
F.singleton_class.instance_eval "define_method(:f) { 'F' }"
F.f #=> "F"
class Class
def k
"K"
end
end
class G
end
G.k #=> "K"
Проблема здесь состоит в том, что все методы экземпляра из Class
(включая :k
) доступны для использования в качестве (класса) методов всеми класами ses, поскольку классы являются экземплярами Class
(H.class#=>Class
).
class Object
def o
"O"
end
end
class H
end
H.o #=> "O"
H.new.o #=> "O"
Это одна интересная. Object
является предком Class
(Class.ancestors #=> [Class, Module, Object, Kernel, BasicObject]
), поэтому Class
наследует метод экземпляра :o
от Object
. Следовательно (из предыдущего случая) :o
- метод класса H
. Однако H
также является подклассом Object
(H.superclass #=> Object
), поэтому H
наследует метод экземпляра Object#:o
.
Что касается "наилучшего", это зависит. Если нужно создать несколько методов класса, большинство из них будет использовать A
.Если понадобилось большое количество, я бы использовал D
или B
. Если методы класса должны были создаваться динамически, F
или какой-либо вариант. Однако я не могу представить ситуацию, когда буду использовать G
или H
.
вы также можете написать 'def Dog.class_method; end', который вы также можете написать вне класса. –