2
class Invoice
  def Invoice.generate(order_id, charge_amount, credited_amount = 0.0)
    Invoice.new(:order_id => order_id, :amount => charge_amount, :invoice_type => PURCHASE, :credited_amount => credited_amount)
  end
end

你为什么要创建Invoice.generate内部Invoice类而不是self.generate

4

3 回答 3

5

self.generate更容易使用,而Invoice.generate可以说更明确。除此之外,两者没有区别。

解释

您可以使用此表单在任何实例上定义方法

def receiver.method(args) 
end

看一下这个

class Foo
end

def Foo.bar
  "bar"
end

Foo.bar # => "bar"

是的,我的意思是任何实例。绝对有可能一个实例有某种方法,而另一个没有

f = Foo.new

def f.quux
  'quux'
end

f2 = Foo.new

f.quux # => "quux"
f2.quux # => # ~> -:20:in `<main>': undefined method `quux' for #<Foo:0x007fe4e904a6c0> (NoMethodError)

提醒:类定义内部(但方法定义外部)self指向该类。

class Foo
  # self is Foo
end

因此,有了这些知识, 和 之间的区别self.generate应该Invoice.generate是显而易见的。

于 2012-11-19T05:37:26.700 回答
1

在正常情况下,它实际上与def self.generate.

我能想到的唯一边缘情况是,如果您有一个同名的嵌套类,那么显式版本将仅适用于嵌套类。

class A
  def self.x
    name
  end

  def A.y
    name
  end

  class A 
    # nested class A::A
  end

  def self.p
    name
  end

  def A.q
    name
  end
end

> A.x # => "A"
> A.y # => "A"
> A.p # => "A"
> A.q # => NoMethodError: undefined method `q' for A:Class
> A::A.q # => "A::A"

如你所见,同名嵌套类定义后,后续使用该类名的显式类方法定义引用嵌套类,而事先显式定义引用原始类。

隐式定义self总是引用基类。

于 2012-11-19T05:57:34.280 回答
0

您有两种定义类方法的方法。

1)可以直接使用类名

class Test #Test is now an instance of a built-in class named Class
  def Test.class_method
    "I'm a class method."
  end
end

2)你可以使用self变量,它总是指向当前对象

class Test
  def self.class_method
    "I'm a class method."
  end
end

一旦你理解了类是对象,这种使用 self 变量来定义类方法的方法终于有意义了。

自我的价值

毫不奇怪,当您在类方法中时, self 的值指的是保存类结构的对象(类 Class 的实例)。这意味着 :

class Test
  def self.class_method
    self.x
  end
end

相当于:

class Test
  def self.class_method
    Test.x
  end
end

当您在实例方法中时, self 的值仍然引用当前对象。然而,这一次,当前对象是 Test 类的实例,而不是 Class 类的实例。

更多信息。http ://www.jimmycuadra.com/posts/self-in-ruby

于 2012-11-19T05:42:41.043 回答