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

时间:2009-07-07 20:30:36

标签: ruby class-method

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

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

  def self.baz
    # ...
  end
end

这两者有区别吗?比另一个更优选吗?

4 个答案:

答案 0 :(得分:3)

简而言之:不,不。

归结为个人偏好。如果您定义了许多类方法,则第一个版本会保存您的输入。如果你不喜欢第一个的模糊语法,那么第二个可能更好。

答案 1 :(得分:3)

只是为了澄清术语: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添加到本征类”。但是,正如我们之前建立的那样,对象的单例方法和对象的本征类的实例方法实际上是相同的。这就是为什么这两种符号表现不同的原因是没有意义的。

答案 2 :(得分:0)

正如莫尔夫所说,没有有效的区别。但IMO,第二个是更易于浏览的 - 很容易错过class<<self并认为你仍然在寻找实例方法。当我需要更多动态行为时,我倾向于使用class<<self路由,例如创建类本身的attr_accessor属性。

答案 3 :(得分:0)

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

选项2.对未经训练的Ruby-eye进行更多打字,更具表现力和更易理解。

他们已经指出了最终结果没有区别。