Jef*_*ong 2 ruby methods syntax class class-method
例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
Run Code Online (Sandbox Code Playgroud)
例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
Run Code Online (Sandbox Code Playgroud)
我可以知道在Ruby中编写类方法的哪种方式是首选的,为什么?是否存在一种优先于另一种情况的情况?
您询问了创建类方法的不同方法.这里有一些.
class A
def self.a
"A"
end
end
A.a #=> "A"
Run Code Online (Sandbox Code Playgroud)
class B
class << self
def b
"B"
end
end
end
B.b #=> "B"
Run Code Online (Sandbox Code Playgroud)
class C
singleton_class.class_eval do
def c
"C"
end
end
end
C.c #=> "C"
Run Code Online (Sandbox Code Playgroud)
module M
def m
"M"
end
end
class D
extend M
end
D.m #=> "M"
Run Code Online (Sandbox Code Playgroud)
class E
class << self
include M
end
end
E.m #=> "M"
Run Code Online (Sandbox Code Playgroud)
class F
singleton_class.instance_eval do
define_method(:f) do
"F"
end
end
end
F.f #=> "F"
Run Code Online (Sandbox Code Playgroud)
如果:f要动态创建,
class F
end
F.singleton_class.instance_eval do
define_method(:f) do
"F"
end
end
Run Code Online (Sandbox Code Playgroud)
或变体:
F.singleton_class.instance_eval "define_method(:f) { 'F' }"
F.f #=> "F"
Run Code Online (Sandbox Code Playgroud)
class Class
def k
"K"
end
end
class G
end
G.k #=> "K"
Run Code Online (Sandbox Code Playgroud)
这里的问题是所有类的所有实例方法Class(包括:k)都可以被所有类用作(类)方法,因为类是Class(H.class#=>Class)的实例.
class Object
def o
"O"
end
end
class H
end
H.o #=> "O"
H.new.o #=> "O"
Run Code Online (Sandbox Code Playgroud)
这个很有意思.Object是Class(Class.ancestors #=> [Class, Module, Object, Kernel, BasicObject])的祖先,所以从中Class继承实例方法.因此(从前一种情况),是一种类方法.但是,也是()的子类,所以继承实例方法.:oObject:oHHObjectH.superclass #=> ObjectHObject#:o
至于哪个是"最好的",这取决于.如果要创建几个类方法,大多数都会使用A.如果需要大量的话,我会使用D或B.如果要动态创建类方法F,或某些变体.我无法想象的情况,但是,在这里我会用G或H.