类与Ruby的self和self.method:有什么更好的?

这个Ruby风格指南告诉我们,使用self.method_name而不是class method_name会更好。 但为什么?

 class TestClass # bad class << self def first_method # body omitted end def second_method_etc # body omitted end end # good def self.first_method # body omitted end def self.second_method_etc # body omitted end end 

有没有性能问题?

class << self很擅长将所有的类方法放在同一个块中。 如果方法被添加到def self.method ,那么没有任何保证(除了惯例和一厢情愿的想法),在文件中稍后将不会有额外的类方法。

def self.method擅长明确指出一个方法是一个类方法,而对于class << self你必须自己去找容器。

其中哪一个对你来说更重要是一个主观的决定,也取决于其他人有多less工作在代码上,以及他们的偏好是什么。

一般来说,在元编程中使用class << self ”类将自己的类设置为长时间。 如果我想写10个方法,我会这样使用它:

 METHOD_APPENDICES = [1...10] class << self METHOD_APPENDICES.each do |n| define_method("method#{n}") { n } end end 

这将创build10个方法(方法1,方法2,方法3等),只会返回数字。 在这种情况下,我会使用class << self来清晰,因为在元编程中, self是至关重要的。 乱丢self. 里面实际上会让事情变得不可读。

如果你只是定义类方法,坚持self.class_method_name因为更多的人可能会理解它。 除非您希望听众理解它,否则不需要引入元语法。

如上所述,这两种风格似乎是等价的,但是使用class << self允许将类方法标记为privateprotected 。 例如:

 class UsingDefSelf def self.a; 'public class method'; end private def self.b; 'public class method!'; end end class UsingSingletonClass class << self def a; 'public class method'; end private def b; 'private class method'; end end end 

private只影响实例方法。 使用单例类,我们正在定义那个类的实例方法,它变成了包含类的类方法!

我们也可以把class级方法标记为privatedef self

 class UsingDefSelf def self.a; 'private class method'; end def self.b; 'private class method!'; end private_class_method :a, :b # In Ruby 2.1 there is an alternative syntax private_class_method def self.c; 'private class method!'; end end 

但是我们不能将它们标记为protected ,没有protected_class_method 。 (但是,由于类是它的单例类的唯一实例,私有类方法和受保护的类方法几乎是相同的,除了它们的调用语法不同之外)。

同样,使用class << self来标记private类方法也不那么容易,因为您必须将private_class_method中的所有方法名称或private_class_method前缀列出给每个私有类方法定义。

我认为他们认为self.*更好,因为你可以肯定地说,这是一个类或实例方法,而不必向上滚动和seaching这个class << self string。

无论你想要什么。 两者对于你所做的都很清楚。 但是我想到了一些build议。

当只有一个类方法定义时,使用def self.xxx 。 因为只定义一个方法,增加缩进级别可能会变得混乱。

当有多个类的方法定义时,使用class << self 。 因为编写def self.xxxdef self.yyydef self.zzz肯定是重复的。 为这些方法创build一个部分。

当一个类中的所有方法都是类方法时,可以使用module_function而不是class 。 这可以让你定义模块function,只需使用def xxx

问题到目前为止只是讨论这两个选项:

 class MyClass def self.method_name .. end end class MyClass class << self def method_name .. end end end 

但是,对于在类级别上操作的类方法/单例方法/静态方法/方法(或任何其他你想调用它们的方法),还有另一种select:

 class MyClass def MyClass.method_name .. end end 

我更喜欢这个选项,因为它更明显。 方法定义看起来就像在你的代码中调用它的方式,很明显它在类的层次上运行。

我也来自Python背景,其中self用于实例方法,而在Ruby中, self用于类方法。 这经常让我感到困惑,所以为了避免思考“在Ruby中是一种自我方法的类还是实例方法? 我使用def ClassName.methodname