Ruby动态对象属性,发送vs实例变量集

标签 ruby metaprogramming

假设我有一个简单的对象。我有 attr_accessor 用于我想要接受的属性,我希望能够使用对象的哈希值进行初始化:

class Example
  attr_accessor :foo, :bar

  def initialize( attributes = {} )
    attributes.each do |k,v|
      ...
    end
  end
end

在上面的 attributes.each block 中,使用 send 会更好吗,如下所示:

send "#{k}=", v

或者使用instance_variable_set,像这样:

instance_variable_set "@#{k}".to_sym, v

... 还是完全做其他事情?

我能想到的区别是:

  • 如果我在某个时候用 setter 方法替换其中一个 attr_accessors,使用 send 会更加一致。

  • 如果传递了意外值,使用send 会引发NoMethodError

出于这些原因,我倾向于使用 send —— 我实际上有点喜欢 NoMethodError 被假初始化数据引发的可能性。但是,我在这里是否忽略了任何其他因素,尤其是性能和安全方面的考虑?

我很感激任何见解。谢谢!

最佳答案

我的答案是使用发送。

原因:即使访问器不存在,也会使用 instance_variable_set 创建一个实例变量。正如您所提到的,使用发送您将收到 NoMethodError。

关于Ruby动态对象属性,发送vs实例变量集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14696284/

相关文章:

ruby - 无法安装 Curb - native 扩展有问题。

ruby-on-rails - 没有路由匹配缺少必需的键 : [:locale]

ruby-on-rails - Elasticsearch结果到表

r - 修改函数以便控制流构造使用 `{...}` 并在正确的位置保留注释

ruby-on-rails - 为什么使用 send_data 发送的对象似乎保留在内存中?

c++ - 需要帮助来理解具有复杂类型名参数的模板函数

c++ - 本地实现的接口(interface)引用

programming-languages - 通用编程与元编程

c++ - 为什么使用 boost::ice_or 而不是 ||和 boost::ice_and 而不是 enable_if 中的 &&?

ruby-on-rails - 暂存环境 : Password protect everything except for webhook