Ruby:从类方法生成实例对象

时间:2012-02-13 01:23:31

标签: ruby

MyClass对象有a,b和c实例变量(原谅我模糊的抽象)。另外,在编写这些类时,我希望能够设置abc,但我不希望我的用户能够这样做。

class MyClass
  attr_accessor :a, :b, :c
  private :a=, :b=, :c=
end

我希望通过以下两种方式之一来实例化MyClass,以便我能够调用以下内容:

f = MyClass.create_from_foo foo_data
b = MyClass.create_from_bar bar_data

并在fb中获取MyClass的实例。 fb在实例化后无法区分,但当然是以不同的方式创建的。完成这些调用后,fb都有abc

我不希望MyClass通过new进行实例化。由于这两种创建方式同样有效,我觉得“更喜欢”foo_data而不是bar_data,反之亦然,这并不是我想要的含义。因此,我觉得我应该私有化new并且只允许通过这些类方法创建MyClass的实例来尝试平衡游戏领域。换句话说,我正试图避免这个:

#don't want this
f = MyClass.new foo_data
b = MyClass.create_from_bar bar_data #not quite "fair" to bar_data

所以,让我开始编写这些create_from_<type>类方法:

class MyClass

  #from earlier
  attr_accessor :a, :b, :c
  private :a=, :b=, :c=

  private_class_method :new

  def MyClass.create_from_foo foo_data
    #some parsing of foo_data and computation of a, b, and c
    myclass = MyClass.new
    myclass.a = a
    myclass.b = b
    #...
  end

  def MyClass.create_from_bar bar_data
    #again, computation of bar_data
    myclass.a = a
    myclass.b = b
    #...
  end
end

现在,如果你一直在跟随,你会注意到我不能这样做!我把自己封锁了!

  • 我私有化new,因为我不希望我的用户以这种方式制作MyClass对象。我希望他们使用类方法。在类方法定义空间中,我基本上是一个用户。
  • 我将a=b=c=私有化,因为我不希望我的用户更改此内容。 (这会破坏我的现实世界的例子)。但是,在定义类方法时,我是一个用户。

所以,这就是我正在使用的。如何在类方法中创建“限制性”类的实例?

2 个答案:

答案 0 :(得分:4)

你有点纠结,你可以做一点简单。

class MyClass
  attr_reader :a, :b, :c

  private_class_method :new

  def initialize(a,b)
    @a = a
    @b = b
  end

  def self.create_from_foo foo_data
    #some parsing of foo_data and computation of a, b, and c
    myclass = new(a,b)
    #...
  end

  def self.create_from_bar bar_data
    #again, computation of bar_data
    myclass = new(a,b)
    #...
  end
end

答案 1 :(得分:3)

完全可以从其他类方法中调用私有类方法。但是在Ruby中,你不能使用显式接收器调用私有方法(除了setter)。

因此,如果你只是写new而不是MyClass.new,那么它会正常工作。