定义 Ruby 类方法的方式有区别吗?

发布于 2024-07-26 03:59:57 字数 194 浏览 3 评论 0 原文

给出以下两种在 Ruby 中定义类方法的方法:

class Foo
  class << self
    def bar
      # ...
    end
  end

  def self.baz
    # ...
  end
end

两者之间有区别吗? 一个比另一个更可取吗?

Given the following two ways of defining a class method in Ruby:

class Foo
  class << self
    def bar
      # ...
    end
  end

  def self.baz
    # ...
  end
end

Is there a difference between the two? Is one more preferable than the other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笑忘罢 2024-08-02 03:59:57

简而言之:不,不。

这取决于个人喜好。 如果您定义了许多类方法,第一个版本可以节省您的打字时间。 如果您不喜欢第一个的模糊语法,则第二个可能更可取。

In short: no and no.

It comes down to personal preference. The first version saves you typing if you define many class methods. The second one may be preferable if you dislike the obscurer syntax of the first.

残花月 2024-08-02 03:59:57

只是澄清一下术语:Ruby 中不存在“类方法”这样的东西。 您要做的就是在对象上定义一个单例方法,即Foo类(记住,类也是对象,就像任何其他)。 反过来,单例方法也不真正存在,它们只是对象的特征类(通常称为Foo')上的普通实例方法,其中这个例子也是Foo类的元类。

还困惑吗? :-)

没有区别

foo = Object.new
class << foo
  def bar
    # ...
  end
end

def foo.baz
  # ...
end

基本上,这样做:和这样做

class Foo
  class << self
    def bar
      # ...
    end
  end

  def self.baz
    # ...
  end
end

:因为在类定义中,self 绑定到类对象(在本例中为 Foo),这相当于:

class Foo
  class << Foo
    def bar
      # ...
    end
  end

  def Foo.baz
    # ...
  end
end

这又相当于:

Foo = Class.new
class << Foo
  def bar
    # ...
  end
end

def Foo.baz
  # ...
end

正如您所看到的,这与我的第一个示例几乎完全相同。 这表明类方法上的单例方法和任何其他类型对象上的单例方法之间确实没有区别,因此在 Ruby 中谈论“类方法”是没有意义的。

您还可以看到这两个符号如何与单例方法和特征类的概念相关:

def foo.baz
  # ...
end

表示“将单例方法 baz 添加到对象 foo”和

class << foo
  def bar
    # ...
  end
end

“打开特征类”对象 foo 的实例方法,然后将实例方法 bar 添加到特征类中”。 但是,正如我们之前所建立的,对象的单例方法和对象的特征类的实例方法实际上是同一件事。 这就是为什么这两个符号表现不同是没有意义的。

Just to clarify the terminology: there is no such thing as a "class method" in Ruby. What you are doing is to define a singleton method on the object that is the class Foo (remember, classes are objects, too, just like any other). In turn, singleton methods don't really exist, either, they are just normal instance methods on the eigenclass (commonly referred to as Foo′) of the object, which in this case is also the metaclass of the class Foo.

Confused yet? :-)

Basically, there is no difference between doing this:

foo = Object.new
class << foo
  def bar
    # ...
  end
end

def foo.baz
  # ...
end

and this:

class Foo
  class << self
    def bar
      # ...
    end
  end

  def self.baz
    # ...
  end
end

Because inside a class definition, self is bound to the class object (in this case Foo), that is equivalent to:

class Foo
  class << Foo
    def bar
      # ...
    end
  end

  def Foo.baz
    # ...
  end
end

Which is in turn equivalent to:

Foo = Class.new
class << Foo
  def bar
    # ...
  end
end

def Foo.baz
  # ...
end

Which as you can see is pretty much exactly the same as my first example. This shows that there really is no difference between a singleton method on a class method and a singleton method on any other kind of object, therefore it doesn't make sense to talk about "class methods" in Ruby.

You can also see how these two notations relate to the notion of singleton methods and eigenclasses:

def foo.baz
  # ...
end

says "add the singleton method baz to the object foo" and

class << foo
  def bar
    # ...
  end
end

"open up the eigenclass of object foo and then add instance method bar to the eigenclass". But, as we established earlier, a singleton method of the object and an instance method of the object's eigenclass are really the same thing. That's why it wouldn't make sense for those two notations to behave differently.

撩动你心 2024-08-02 03:59:57

正如莫尔夫所说,没有任何有效的区别。 但在我看来,第二个更容易浏览——很容易错过 class< 并认为您仍在查看实例方法。 我只倾向于在需要更多动态行为时使用 class< 路由,例如为类本身创建 attr_accessor 属性。

As molf said, there's no effective difference. But IMO, the second is so much more skimmable -- it's too easy to miss the class<<self and think you're still looking at instance methods. I only tend to use the class<<self route when I need more dynamic behavior, such as making attr_accessor properties of the class itself.

枕头说它不想醒 2024-08-02 03:59:57

如果您在 class << 之间有很多代码行,选项 1. 会给您带来麻烦。 self 和相应的 end。 如果您没有注意到类中已经定义了一个方法<< self 块,您可能认为它只是一个实例方法。

选项 2. 对于未经训练的 Ruby-eye 来说,输入更多、更具表现力并且更容易理解。

正如其他人已经指出的那样,它们的最终结果没有区别。

Option 1. will get you into trouble if you've got a lots of lines of code between class << self and the corresponding end. If you don't notic that a method has been defined inside the class << self block, you might think its just an instance method.

Option 2. is more typing, more expressive and more understandable to the untrained Ruby-eye.

Theyre's no difference in the end-result as others have pointed already.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文