class << self vs self.method with Ruby:哪个更好?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10964081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
class << self vs self.method with Ruby: what's better?
提问by Mich Dart
This Ruby Style Guidetells that is better using self.method_nameinstead of class method_name. But Why?
这红宝石风格指南告诉更好用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
Are there performance issues?
是否存在性能问题?
回答by Gareth
class << selfis good at keeping all of your class methods in the same block. If methods are being added in def self.methodform 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.
class << self擅长将所有类方法保存在同一个块中。如果在def self.method表单中添加方法,则不能保证(除了约定和一厢情愿)不会在文件的后面隐藏额外的类方法。
def self.methodis good at explicitly stating that a method is a class method, whereas with class << selfyou have to go and find the container yourself.
def self.method擅长明确说明一个方法是一个类方法,而class << 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.
其中哪一个对您更重要是一个主观决定,还取决于其他人在编写代码以及他们的偏好等因素。
回答by Chris
Generally, class << selfis 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:
通常,class << 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 << selffor clarity in this case because in metaprogramming selfis crucial. Littering self.inside there would actually make things lessreadable.
这将创建 10 个仅返回数字的方法(method1、method2、method3 等)。class << self在这种情况下,为了清楚起见,我会使用它,因为在元编程self中至关重要。self.在里面乱扔垃圾实际上会让事情变得不那么可读。
If you're just defining class methods normally, stick to self.class_method_namebecause 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因为更多人可能会理解它。除非您希望您的听众理解它,否则无需引入元语法。
回答by Jonathan O'Connor
As noted above, both styles seem to be equivalent, however using class << selfallows one to mark class methods as privateor protected. For example:
如上所述,两种样式似乎是等效的,但是 usingclass << 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
privateonly 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只影响实例方法。使用单例类,我们定义了该类的实例方法,这些方法变成了包含类的类方法!
We can also mark class methods as privatewith def self:
我们还可以标记类的方法是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
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。(但是,由于 class 是其单例类的唯一实例,因此私有类方法和受保护类方法几乎相同,只是它们的调用语法不同。)
Also it is less easier than using class << selfto mark privateclass methods, since you have to list all method names in private_class_methodor prefix private_class_methodto every private class method definition.
此外,它不如class << self用于标记private类方法容易,因为您必须在每个私有类方法定义中列出所有方法名称private_class_method或前缀private_class_method。
回答by nonowarn
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.yyyand def self.zzzis certainly repetition. Create a section for these methods.
当需要定义多个类方法时,使用class << self. 因为写作def self.xxx,def self.yyy而且def self.zzz肯定是重复的。为这些方法创建一个部分。
When all methods in a class are class method,you can use modulewith module_functioninstead of class. This let you define module functions just use def xxx.
当一个类中的所有方法都是类方法时,您可以使用modulewithmodule_function代替class。这让您可以定义模块函数,只需使用def xxx.
回答by Flexoid
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 << selfstring.
我认为他们认为self.*更好,因为您可以肯定地说,它是一个类或实例方法,而不必向上滚动并搜索此class << self字符串。
回答by Dennis
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
There's a third option to consider for class methods:
对于类方法,还有第三种选择要考虑:
class MyClass
def MyClass.method_name
..
end
end
It's not popular and is more verbose, but it's the most explicit option.
它不流行而且更冗长,但它是最明确的选项。
It's also less confusing if you mix up selfbehaviour between Python and Ruby.
如果您self在 Python 和 Ruby 之间混合行为,也不会那么混乱。

