Я использую Ruby 1.9.2 p180.
Я пишу инструмент непрерывной оценки для Rubyvis (будет частью SciRuby ). По сути, вы устанавливаете Rubyvis::Panel
во входном файле (например, test.rb
), и этот класс SciRuby (Плоттер) следит за test.rb
на предмет изменений. Когда есть изменение, SciRuby запускает скрипт через eval
.
Сценарий работает, если я запускаю его из командной строки, но при выполнении через eval
график неверен - прямая линия, как будто все данные пропали, вместо , что вы видите здесь . Примечание: Раньше здесь говорилось, что SVG отличается, но оказывается, что это был результат загрузки REXML вместо нокогири.
Вот сценарии тестирования и eval-код. Большинство выводят прямую линию (с исключениями, описанными в разделе edit ниже).
Я не знаю, как это происходит.
У меня есть несколько идей относительно , почему это может происходить, но не имею понятия о механизме.
Гипотеза:
eval
не позволяет делать глубокие копии. Объекты, взятые из eval
, в определенных контекстах являются недостающими частями, особенно когда лямбда используется для обработки данных в правильном формате для графика.
- По какой-то причине
eval
не соблюдает связанный список депозита при вызове require
- может быть, в моей привязке используется неправильная версия nokogiri?
- Некоторая другая необходимая библиотека (возможно, RSVG?) Перегружена некоторым методом, который использует Rubyvis.
Кто-нибудь видел что-нибудь подобное раньше? Я как бы чувствую себя в темноте - совершенно не зная, с чего начать устранение неполадок.
Редактировать 15.09.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)
в источнике моего приложения (не в сценарии печати).
Оказывается, что если я просто использую хеш, например, {: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)
Так что разница в том, как мои данные назначены. Вопрос: почему?
Копии входов доступны в оригинальном списке . Спасибо за вашу помощь.