在Ruby中,eval的替代方案有哪些?

6
我编写了以下递归函数,以解析一些设置并正确填充我拥有的一些日志文件对象。
当我在Code Climate上运行此代码时,它告诉我不鼓励使用eval。是否有一种方法可以重写此方法,以便我不需要eval也不需要case语句?目前没有想到更好的方案。
def parse(settings, logfile = nil)
  settings.each do |key, value|
    if value.is_a?(Hash)
      logfile = Logmsg::LogFile.new
      parse(value, logfile)
    else
      eval("logfile.#{key} = value")
    end
  end
end

有什么想法吗?

我正在尝试使用元编程方法中的instance_variable_set,但是我仍然遇到了一些问题。由于某种原因,我的所有测试现在都失败了,原因是

Argument Error: comparison of Fixnum with String failed

我仍在努力弄清楚这个问题。

1个回答

11

由于给对象的属性赋值只是语法糖,实际上是调用方法(即 obj.foo = bar 与在 obj 上调用带参数 barfoo= 方法相同),因此应使用Object#public_send

logfile.public_send(:"#{key}=", value)

在老代码中,你经常会看到send而不是public_send,但是你应该使用后者,因为如果尝试调用私有方法,它会引发错误。

在旧代码中,通常会看到send而不是public_send,但是应该使用后者,因为它会在尝试调用私有方法时抛出错误。


哈!我希望在你编辑答案之后再看到它!我花了一段时间才发现我必须在方法名中加上'=',否则它将无法找到正确的访问器。不管怎样!那确实起作用了!非常感谢,我不知道这个public_send方法! - Egon Braun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接