ruby - 启用标记为 'attr_reader' 的类实例属性的更改值

标签 ruby oop constructor encapsulation nomethoderror

我有以下代码:

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 初始化类后,限制 xy 变量值的更改。但是,我希望在从类内部初始化对象时允许这样做,如上面的代码所示。

但是当我调用 obj = A.with_data 时出现以下错误:

NoMethodError: undefined method `x='

这不应该在类里面被允许吗?我需要为此定义 attr_writer 吗?这会危及封装。

此外,我不想为类中的每个属性定义一个私有(private) setter 方法,因为它可能会遇到多达 30 个实例级变量。 ruby 是否提供任何功能来解决这个问题?

版本: ruby 1.9.3

最佳答案

所以你需要的是 Object#instance_variable_set :

class A
  attr_reader :x, :y

  private_class_method :new

  def self.with_data
    a = new
    a.instance_variable_set(:@x, 2)
    a.instance_variable_set(:@y, 'sid')
    a
  end
end

用法:

a = A.with_data
#=> #<A:0x007ff37c979d30 @x=2, @y="sid">
a.x
#=> 2
a.x = 3
#=> NoMethodError: undefined method `x=' for #<A:0x007ff37c979d30 @x=2, @y="sid">

关于ruby - 启用标记为 'attr_reader' 的类实例属性的更改值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43027418/

相关文章:

design-patterns - 工厂对象的目的/使用相同实例返回类型的好处

java - 子类构造函数中的重写函数 (JAVA)

c++ - 具有可变构造函数的类模板;将参数存储到 std::vector< std::shared_ptr<>>

ruby - Capistrano 3 在任务中更改 ssh_options

ruby - 如何为 MITM 攻击提供有效的 SSL 证书?

Java纸牌游戏: Deck Class help needed

java - Android/Java - 覆盖

c++复制初始化和直接初始化,奇怪的情况

javascript - Jquery切换菜单问题

ruby - 在 Rail 3 中的自定义 label_tag 助手中跳过 HTML 转义