MyClass对象有a,b和c实例变量(原谅我模糊的抽象)。另外,在编写这些类时,我希望能够设置a
,b
和c
,但我不希望我的用户能够这样做。
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
并在f
和b
中获取MyClass的实例。 f
和b
在实例化后无法区分,但当然是以不同的方式创建的。完成这些调用后,f
和b
都有a
,b
和c
。
我不希望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=
私有化,因为我不希望我的用户更改此内容。 (这会破坏我的现实世界的例子)。但是,在定义类方法时,我是一个用户。所以,这就是我正在使用的。如何在类方法中创建“限制性”类的实例?
答案 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
,那么它会正常工作。