【发布时间】:2017-08-19 00:57:20
【问题描述】:
我有以下代码:
class A
attr_reader :x, :y
private_class_method :new
def self.with_data
a = new
a.x = 2
a.y = 'sid'
a
end
end
目的是在通过工厂方法with_data 初始化类后限制x 和y 变量的值变化。但是,我希望在从类中初始化对象时允许这样做,如上面的代码所示。
但是当我调用obj = A.with_data 时出现以下错误:
NoMethodError: 未定义的方法`x='
这不应该在课堂上允许吗?我需要为此定义attr_writer 吗?这会危及封装。
另外,我不想为类中的每个属性定义一个私有 setter 方法,因为它可能会遇到多达 30 个实例级变量。 ruby 是否提供任何功能来解决这个问题?
版本: 红宝石 1.9.3
【问题讨论】:
-
为什么不直接在
initialize方法中设置实例变量呢?为什么要使用额外的with_data工厂方法?你试图达到什么在initialize中无法做到的事情?如果initialize是为变量赋值的唯一方法,那么它们以后就不能轻易更改。我错过了什么吗? -
@spickermann 我在这里只放了最低要求的代码。我的实际课程中将有多个工厂方法。因此,工厂方法。
-
@Sid:你说你不想“危及封装”。但是您还想从
A操纵a的内部状态。现在,a和A是两个完全不同的 对象,它们没有相同的类,a是A的一个实例,@ 987654337@ 是Class的一个实例!所以,你说你想从A设置a的内部状态,这是一个完全不同的对象。但是,从 不同的 对象设置对象的内部状态几乎是违反封装的定义。你不能同时拥有它:要么你允许a的内部状态从一个… -
…第三方对象(例如
A),或者您不这样做。 (从技术上讲,您可以总是使用反射方法,例如send、instance_variable_set和朋友来违反封装。)
标签: ruby oop constructor encapsulation nomethoderror