在Ruby中,有几种方法可以声明一个类方法。
我们有这两种形式......
class Dog
def self.species
puts "I'm a dog."
end
def Dog.species_rly?
puts "Still a dog."
end
end
而另一个,更长的形式......
class Dog
class << self
def species_srsly?
puts "OK, fine. I'm a cat."
end
end
end
为什么使用最后一种形式?它比这更好吗?
class Dog
def Dog.some_method
# ...
end
end
答案 0 :(得分:3)
This wonderful book说三种语法是相同的。选择哪一个是个人偏好的问题。它还说Ruby社区不赞成类名语法(def Dog.some_method
)。我可以理解为什么:你没有理由重复信息。如果您重命名您的类,您还必须更新所有方法定义。
因此,您可以自由选择其余两种语法:)
答案 1 :(得分:2)
当你处理少量方法时,你会发现class << self
形式只会更长。如果你打算写15种方法,那么突然它会更清晰,重复性更低。
在一天结束时,您使用的是个人风格或个人风格。
答案 2 :(得分:1)
绝对没有区别,这最终是一个偏好问题。有些人喜欢后者,因为它将所有“类”方法都集成到一个块中,避免了在每个方法定义中编写self.
。
前者使每个方法在每个定义中都是明确的“类”方法。
我认为我不会使用Dog.some_method
,因为它使重构比self.some_method
更难。
答案 3 :(得分:1)
技术没有区别(至少我不知道)。
我避免
class Dog
def Dog.species_rly?
puts "Still a dog."
end
end
如果我更改了类名,我必须在每个方法定义中更改它。 同样,如果我将一个方法从一个类复制到另一个类(如果你这样做,首先考虑一下,如果你应该定义一个模块并包含它)。
如果我使用一种或两种方法:
class Dog
def self.species
puts "I'm a dog."
end
end
如果我有更多的课程方法,那么我首先想到为什么。 类方法通常只是一个糟糕设计的暗示 - 也许你需要另一个(单身?)类。
如果我决定定义多个类方法,我会使用:
class Dog
class << self
def species_srsly?
puts "OK, fine. I'm a cat."
end
end
end
有时我将源文件中的类方法分开,并将实例方法放在另一个源文件中。
答案 4 :(得分:1)
class << self
是最不重复的。 def Dog.meth
在整个班级重复“狗”,def self.meth
重复“自我”。
额外缩进也可能是一个可视指示器,表示您使用的是单例类方法而不是常规实例化方法。
答案 5 :(得分:0)
在类Dog中,self是'Dog'类(每个类都有一个'class'对象,有时称为meta-class或eigenclass)。
以一种棘手的方式,ruby中的所有方法都是实例方法。
def self.species
在'class class'上声明了一个物种方法,这使它(表现得像)一个类方法。
类似地,
d = Dog.new
def d.bark; puts "woof"; end
为'd'实例添加方法
至于
之间的区别class << self
def species
和
def self.species
他们在功能上完成同样的事情。如其他人所述,选择一种格式而不是另一种格式是风格的。 def self.species是宣布'class'方法的常用方法。
我大多会使用
class << self
attr_accessor :species
end
如果我想让属性访问器在类级别而不是实例上运行。
了解这一点对于使用包含模块的钩子非常重要
module Sound
def self.included(host_class)
def host_class.speak(sound)
define_method(:bark) do
sound
end
end
end
end
class Dog
include Sound
speak "woof"
end
Dog.new.bark
另外,为了完整性
class Dog
def self.species
puts self.to_s
end
def Dog.bark
puts self.to_s
end
end
class Spaniel < Dog; end
物种方法是在任何子类的self上定义的,而:bark方法总是在Dog上定义(除非被覆盖)