在 Ruby 中创建 Class 方法的不同方式
Different Ways of Creating Class Method in Ruby
示例 1:
class Dog
def self.class_method
:another_way_to_write_class_methods
end
end
def test_you_can_use_self_instead_of_an_explicit_reference_to_dog
assert_equal :another_way_to_write_class_methods, Dog.class_method
end
示例 2:
class Dog
class << self
def another_class_method
:still_another_way
end
end
end
def test_heres_still_another_way_to_write_class_methods
assert_equal :still_another_way, Dog.another_class_method
end
我可以知道在 Ruby 中首选哪种编写 class 方法的方式吗?为什么?是否存在一种情况优于另一种情况?
this ruby style guide 表示 class << self
语法是 "possible and convenient when you have to define many class methods."
他们有使用这两个版本的代码示例,因此对于使用其中一个版本肯定没有广泛的社区共识。
我个人使用def self.my_method
来最小化缩进
您要求使用不同的方法来创建 class 方法。这里有一些。
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
)的所有实例方法都可用作所有 classes 的(class)方法,因为classes 是 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
继承了Object
的实例方法:o
。因此(从前面的例子来看),:o
是 H
的 class 方法。但是,H
也是Object
的subclass(H.superclass #=> Object
),所以H
继承了实例方法Object#:o
.
至于哪个是 "best",视情况而定。如果只创建几个 class 方法,大多数会使用 A
。如果需要大量,我会使用 D
或 B
。如果要动态创建 class 方法,F
或某些变体。但是,我无法想象我会使用 G
或 H
.
的情况
示例 1:
class Dog
def self.class_method
:another_way_to_write_class_methods
end
end
def test_you_can_use_self_instead_of_an_explicit_reference_to_dog
assert_equal :another_way_to_write_class_methods, Dog.class_method
end
示例 2:
class Dog
class << self
def another_class_method
:still_another_way
end
end
end
def test_heres_still_another_way_to_write_class_methods
assert_equal :still_another_way, Dog.another_class_method
end
我可以知道在 Ruby 中首选哪种编写 class 方法的方式吗?为什么?是否存在一种情况优于另一种情况?
this ruby style guide 表示 class << self
语法是 "possible and convenient when you have to define many class methods."
他们有使用这两个版本的代码示例,因此对于使用其中一个版本肯定没有广泛的社区共识。
我个人使用def self.my_method
来最小化缩进
您要求使用不同的方法来创建 class 方法。这里有一些。
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
)的所有实例方法都可用作所有 classes 的(class)方法,因为classes 是 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
继承了Object
的实例方法:o
。因此(从前面的例子来看),:o
是 H
的 class 方法。但是,H
也是Object
的subclass(H.superclass #=> Object
),所以H
继承了实例方法Object#:o
.
至于哪个是 "best",视情况而定。如果只创建几个 class 方法,大多数会使用 A
。如果需要大量,我会使用 D
或 B
。如果要动态创建 class 方法,F
或某些变体。但是,我无法想象我会使用 G
或 H
.