Dangers and reservations of Kernel :: eval in Ruby?

I am using Ruby 1.9.2 p180.

I am writing a continuous evaluation tool for Rubyvis (to be part of SciRuby ). Basically you install Rubyvis::Panelin your input file (for example, test.rb), and this SciRuby (Plotter) class observes test.rbthe changes. When there are changes, SciRuby runs the script through eval.

The script works if I run it from the command line, but when executed through eval, the schedule is wrong - a straight line, as if all the data is gone, instead of what you see here . Note. It was said earlier that SVG was different, but it turns out that it was the result of loading REXML instead of nokogiri.

Here are test scripts and eval code. In most cases, a straight line is obtained (with the exceptions described in the editing section below).

I am not very weak how this happens.

I have a few ideas as to why this might happen, but I have no idea about the mechanism.

Hypotheses:

  • evaldoes not allow making deep copies. Objects that are taken from evalare missing in some contexts, especially when lambda is used to process data in the correct format for the chart.
  • For some reason, it evaldoesn’t follow the list of folded dips when called require- is it possible that the wrong version of nokogiri is used in my binding?
  • Some other required library (perhaps RSVG?) Overloaded some method used by Rubyvis.

- - ? - , .

9/15/11:

, OpenStruct.new .

, data = pv.range(0,10,0.1).map { |d| [d,Math.sin(d)+2+rand()] }, .

OpenStructs, :

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)

, , ,

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) ( script).

, , , {:x => x, :y => Math.sin(x)}, . Hash.new({:x => x, :y => Math.sin(x)}), , , vis.data:

rubyvis/lib/rubyvis/internals.rb:184:in `each': comparison of Hash with Hash failed (ArgumentError)

, , . : ?

.. .

+5
2

, , , {: x = > x,: y = > Math.sin(x)}, . Hash.new({: x = > x,: y = > Math.sin(x)}), , , call vis.data:

, Hash.new . Hash.new , .

+1

, ;

load eval?

0
source

All Articles