The configuration file can be plain ruby!
You can define your own DSL to manage the formulars.
So you can load the file once and the formulars do not have to be
evaled…
The configuration file can be plain ruby!
You can define your own DSL to manage the formulars.
So you can load the file once and the formulars do not have to be
evaled…
Nice catch. Actually I did try to implement it as DSL at the beginning,
but finally I realized it is difficult to implement such a DSL in my
problem. So at last I went to the XML format configuration way.
module Yourlib
class << self
def define_processor(key,&block)
processors << [key,&block]
end
def processors
@processors ||= []
end
def run(row) # row should be an hash
processors.each do |key,block|
input[key]=block.call(row)
end
end
end
end
settings.rb
require ‘yourlib’
Yourlib.define_processor :outcome_a do |current|
current[:event_a] * current[:event_b]
end
Yourlib.define_processor :outcome_b do |current|
current[:outcome_b] = current[:event_b] * current[:outcome_a]
end
File.readlines(somepath) do |row|
out = Yourlib.run(preprocess(row))
do_something_fancy(out)
end
As long as your users do not use outcomes before they are produced you
can do calculations based on the outcomes…
If you need namespacing etc you can simply make an convention about the
output key names… and maybe about the input keys too… or try to add
(nested) namespacing.
I new this DSL is messy and redundant in usage, but a better approach
than using eval
make it faster?
Can you eval your formulas into methods, and call the methods on the
data samples?
No. I need flexibility, i.e., allow users to define their own formulas
in the configuration file.
I believe you did not fully understand what Joel suggested. You do
have that flexibility and you need to invoke eval only once per
formula (for the initial compilation of the formula) but not for every
evaluation. Example:
really too simplistic!
formulas = Hash.new do |h, form|
expr = form.sub(/\A.?=\s/, ‘’)
vars = expr.scan(/[a-z]\w*/i).uniq
code = “lambda do |#{vars.join(', ')}| #{expr} end”
p vars, code
h[form] = eval(code)
end
test
[
‘x = y * 2 + z’,
‘z = y * x’,
].each do |f|
puts f
10.times do |i|
printf “%s: %d %d => %f\n”, f, i, i*2, formulas[f][i, i*2]
end
end
I’d prefer the DSL approach though.
Kind regards
robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.