类与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
允许将类方法标记为private
或protected
。 例如:
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级方法标记为private
和def 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.xxx
, def self.yyy
和def 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
。