首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内核的危险和警告::在Ruby中的eval?

内核的危险和警告::在Ruby中的eval?
EN

Stack Overflow用户
提问于 2011-09-14 22:09:24
回答 2查看 347关注 0票数 5

我使用的是Ruby1.9.2 p180。

我正在为鲁比维斯编写一个持续评估工具(作为SciRuby的一部分)。基本上,您在输入文件中设置了Rubyvis::Panel (例如,test.rb),并且这个SciRuby类(Plotter)监视test.rb进行修改。当发生更改时,SciRuby通过eval运行脚本。

如果我从命令行运行脚本,那么脚本就能工作,但是当通过eval执行时,情节是错误的--一条直线,好像所有的数据都没有了,而不是你在这里看到的。注意:以前,它在这里说SVG是不同的--但结果发现这是REXML被加载而不是nokogiri的结果。

下面是测试脚本和eval代码。大多数生成直线(除了下面编辑部分中描述的例外情况)。

我一点也不清楚这是怎么回事。

对于为何会发生这种情况,我有一些想法,但对机制却毫无头绪。

假设:

  1. eval不允许制作深拷贝。从eval获取的对象在某些上下文中会丢失部分,特别是当使用lambda将数据处理为正确的绘图格式时。
  2. 出于某种原因,当调用eval时,require没有遵守捆绑的dep列表--也许在我的绑定中使用了nokogiri的错误版本?
  3. 其他一些必需的库(也许是RSVG?)重载了Rubyvis使用的一些方法。

以前有人见过这样的东西吗?我在黑暗中感觉到了--完全不知所措,不知从哪里开始故障排除。

编辑9/15/11:新信息

OpenStruct.new的调用似乎导致了这个问题。

如果我将数据定义为列表列表( data = pv.range(0,10,0.1).map { |d| [d,Math.sin(d)+2+rand()] } ),它会运行得很好。

但是,当数据被定义为OpenStructs列表时,下面的代码提供了不正确的输出:

代码语言:javascript
复制
data = pv.range(0, 10, 0.1).map {|x|
  o = OpenStruct.new({:x=> x, :y=> Math.sin(x) + 2+rand()})
  STDERR.puts o.inspect # Output is correct.
  o
}
STDERR.puts "size of data: #{data.size}"
STDERR.puts "first x = #{data.first.x}" # Output is first x = 0.0
STDERR.puts "first y = #{data.first.y}" # Output is first y =     (WRONG)

如果在分配数据时使用收集,甚至会导致错误,例如,

代码语言:javascript
复制
vis.add(pv.Line).data(data.collect { |d| [d.x,d.y] }

plotter.rb:88:in `block in <main>': undefined method `x' for [0.0, nil]:Array (NoMethodError)

相对于vis.add(pv.Line).data(data)没有错误。这个错误似乎起源于我的应用程序源代码中对eval("vis.render()", bind)的调用(而不是在绘图脚本中)。

事实证明,如果我只使用散列(例如,{:x => x, :y => Math.sin(x)} ),那就很好了。但是,当我明确地说Hash.new({:x => x, :y => Math.sin(x)})时,无论我如何调用vis.data,都会产生一个错误:

代码语言:javascript
复制
rubyvis/lib/rubyvis/internals.rb:184:in `each': comparison of Hash with Hash failed (ArgumentError)

因此,区别在于我的数据是如何分配的。问题是:为什么?

输入的副本可以在原始要旨中获得。谢谢你的帮助。

EN

回答 2

Stack Overflow用户

发布于 2011-09-16 06:02:05

结果表明,如果我只使用一个散列,例如{:x => x,:y => Math.sin(x)},那就很好了。但是,当我明确地说Hash.new({:x => x,:y => Math.sin(x)})时,无论我如何调用vis.data,都会产生错误:

首先,你打给Hash.new的电话是错误的。Hash.new接受一个参数,该参数是哈希的默认值。

票数 1
EN

Stack Overflow用户

发布于 2011-09-29 23:08:33

我想把这作为一种评论,而不是回答;

你试过load而不是eval吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7423585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档