时间:2021-09-26 22:28:27

This Ruby Style Guide tells that is better using self.method_name instead of class method_name. But Why?

这个Ruby风格指南告诉我们使用self会更好。method_name而不是类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

Are there performance issues?

有性能问题?

6 个解决方案

#1


76  

class << self is good at keeping all of your class methods in the same block. If methods are being added in def self.method from then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.

类<< self善于将所有类方法保存在同一个块中。如果方法是在def self中添加的。方法从此以后,就不能保证(除了约定和一厢情愿的想法)文件中不会隐藏额外的类方法。

def self.method is good at explicitly stating that a method is a class method, whereas with class << self you have to go and find the container yourself.

def自我。方法擅长明确地声明方法是类方法,而对于类<< < self,您必须自己找到容器。

Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.

这些对你来说更重要的是一个主观的决定,也取决于其他的人在做什么,以及他们的偏好是什么。

#2


28  

Generally, class << self is used in metaprogramming to set the class as self for a prolonged period of time. If I'm trying to write 10 methods, I would use it like so:

通常,元编程中使用类<< self,将类设置为self,持续一段时间。如果我想写10种方法,我会这样使用:

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

This would create 10 methods (method1, method2, method3, etc.) that would just return the number. I would use class << self for clarity in this case because in metaprogramming self is crucial. Littering self. inside there would actually make things less readable.

这将创建10个方法(method1、method2、method3等等),这些方法只返回数字。在这种情况下,我将使用类<< self,因为在元编程中self是至关重要的。乱扔垃圾的自我。里面的东西会让人看不懂。

If you're just defining class methods normally, stick to self.class_method_name because more people are likely to understand it. No need to bring in meta-syntax unless you expect your audience to understand it.

如果你只是通常地定义类方法,那就坚持使用self。class_method_name因为更多的人可能理解它。没有必要引入元语法,除非您希望您的读者理解它。

#3


19  

As noted above, both styles seem to be equivalent, however using class << self allows one to mark class methods as private or protected. For example:

如上所述,这两种样式似乎是等价的,但是使用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 only affects instance methods. Using the singleton class, we are defining instance methods of that class, which turn into class methods of the containing class!

private只影响实例方法。使用singleton类,我们定义了该类的实例方法,该实例方法转化为包含类的类方法!

We can also mark class methods as private with def self:

我们也可以用def self将类方法标记为private:

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

But we cannot mark them as protected, there is no protected_class_method. (However, since class is the only instance of its singletonclass, private class method and protected class methods are almost the same except their calling syntax is different.)

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

Also it is less easier than using class << self to mark private class methods, since you have to list all method names in private_class_method or prefix private_class_method to every private class method definition.

它也比使用类<< self来标记私有类方法要简单,因为您必须将private_class_method中的所有方法名或前缀private_class_class_method列到每个私有类方法定义中。

#4


5  

I assume that they think self.* is better because you can say for sure, it's a class or instance method, without having to scroll up and seaching this class << self string.

我假设他们认为自己。*更好,因为您可以肯定地说,它是一个类或实例方法,而不必向上滚动并分离这个类< self string。

#5


3  

Whichever you want. Both are very clear for what you do. But I think of some recommendations for this.

不论你想要的。两者都很清楚你在做什么。但是我想到了一些建议。

When there're only one class method to define, Use def self.xxx. Because for defining only one method, increasing indent level probably become cluttering.

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

When there're more than one class method to define, Use class << self. Because writing def self.xxx, def self.yyy and def self.zzz is certainly repetition. Create a section for these methods.

当有多个类方法需要定义时,使用类<< self。因为写作def自我。xxx,def自我。多和def自我。打鼾声肯定是重复。为这些方法创建一个部分。

When all methods in a class are class method, you can use module with module_function instead of class. This let you define module functions just use def xxx.

当类中的所有方法都是类方法时,可以使用带有module_function的模块而不是类。这使您可以使用def xxx定义模块函数。

#6


-1  

So far the question and answers only discuss these two options:

到目前为止,问题和答案只讨论这两种选择:

class MyClass
  def self.method_name
    ..
  end
end

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

But here's another option to consider for class methods / singleton methods / static methods / methods that operate on the class level (or whatever else you want to call them):

但是,这里还有一个选项可以考虑类方法/单例方法/静态方法/方法,这些方法在类级别上操作(或者其他您想调用它们的方法):

class MyClass
  def MyClass.method_name
    ..
  end
end

I prefer this option because it's more obvious what it does. The method definition looks just like how it would be called in your code, and it's clear it operates on the class level.

我更喜欢这个选项,因为它的功能更明显。方法定义看起来就像如何在代码中调用它一样,很明显它是在类级别上操作的。

I also come from a Python background where self is used for instance methods, whereas in Ruby, self is used for class methods. This often confuses me, so to avoid thinking "is a self method in Ruby a class or instance method?" I use def ClassName.methodname.

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

#1


76  

class << self is good at keeping all of your class methods in the same block. If methods are being added in def self.method from then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.

类<< self善于将所有类方法保存在同一个块中。如果方法是在def self中添加的。方法从此以后,就不能保证(除了约定和一厢情愿的想法)文件中不会隐藏额外的类方法。

def self.method is good at explicitly stating that a method is a class method, whereas with class << self you have to go and find the container yourself.

def自我。方法擅长明确地声明方法是类方法,而对于类<< < self,您必须自己找到容器。

Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.

这些对你来说更重要的是一个主观的决定,也取决于其他的人在做什么,以及他们的偏好是什么。

#2


28  

Generally, class << self is used in metaprogramming to set the class as self for a prolonged period of time. If I'm trying to write 10 methods, I would use it like so:

通常,元编程中使用类<< self,将类设置为self,持续一段时间。如果我想写10种方法,我会这样使用:

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

This would create 10 methods (method1, method2, method3, etc.) that would just return the number. I would use class << self for clarity in this case because in metaprogramming self is crucial. Littering self. inside there would actually make things less readable.

这将创建10个方法(method1、method2、method3等等),这些方法只返回数字。在这种情况下,我将使用类<< self,因为在元编程中self是至关重要的。乱扔垃圾的自我。里面的东西会让人看不懂。

If you're just defining class methods normally, stick to self.class_method_name because more people are likely to understand it. No need to bring in meta-syntax unless you expect your audience to understand it.

如果你只是通常地定义类方法,那就坚持使用self。class_method_name因为更多的人可能理解它。没有必要引入元语法,除非您希望您的读者理解它。

#3


19  

As noted above, both styles seem to be equivalent, however using class << self allows one to mark class methods as private or protected. For example:

如上所述,这两种样式似乎是等价的,但是使用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 only affects instance methods. Using the singleton class, we are defining instance methods of that class, which turn into class methods of the containing class!

private只影响实例方法。使用singleton类,我们定义了该类的实例方法,该实例方法转化为包含类的类方法!

We can also mark class methods as private with def self:

我们也可以用def self将类方法标记为private:

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

But we cannot mark them as protected, there is no protected_class_method. (However, since class is the only instance of its singletonclass, private class method and protected class methods are almost the same except their calling syntax is different.)

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

Also it is less easier than using class << self to mark private class methods, since you have to list all method names in private_class_method or prefix private_class_method to every private class method definition.

它也比使用类<< self来标记私有类方法要简单,因为您必须将private_class_method中的所有方法名或前缀private_class_class_method列到每个私有类方法定义中。

#4


5  

I assume that they think self.* is better because you can say for sure, it's a class or instance method, without having to scroll up and seaching this class << self string.

我假设他们认为自己。*更好,因为您可以肯定地说,它是一个类或实例方法,而不必向上滚动并分离这个类< self string。

#5


3  

Whichever you want. Both are very clear for what you do. But I think of some recommendations for this.

不论你想要的。两者都很清楚你在做什么。但是我想到了一些建议。

When there're only one class method to define, Use def self.xxx. Because for defining only one method, increasing indent level probably become cluttering.

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

When there're more than one class method to define, Use class << self. Because writing def self.xxx, def self.yyy and def self.zzz is certainly repetition. Create a section for these methods.

当有多个类方法需要定义时,使用类<< self。因为写作def自我。xxx,def自我。多和def自我。打鼾声肯定是重复。为这些方法创建一个部分。

When all methods in a class are class method, you can use module with module_function instead of class. This let you define module functions just use def xxx.

当类中的所有方法都是类方法时,可以使用带有module_function的模块而不是类。这使您可以使用def xxx定义模块函数。

#6


-1  

So far the question and answers only discuss these two options:

到目前为止,问题和答案只讨论这两种选择:

class MyClass
  def self.method_name
    ..
  end
end

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

But here's another option to consider for class methods / singleton methods / static methods / methods that operate on the class level (or whatever else you want to call them):

但是,这里还有一个选项可以考虑类方法/单例方法/静态方法/方法,这些方法在类级别上操作(或者其他您想调用它们的方法):

class MyClass
  def MyClass.method_name
    ..
  end
end

I prefer this option because it's more obvious what it does. The method definition looks just like how it would be called in your code, and it's clear it operates on the class level.

我更喜欢这个选项,因为它的功能更明显。方法定义看起来就像如何在代码中调用它一样,很明显它是在类级别上操作的。

I also come from a Python background where self is used for instance methods, whereas in Ruby, self is used for class methods. This often confuses me, so to avoid thinking "is a self method in Ruby a class or instance method?" I use def ClassName.methodname.

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