M
matt
I wonder if anyone has any suggestions for handling a design question
I have. I think I want introspection of Ruby Expressions, but my ruby
experience is limited and there may be an alternative approach that
I've missed...
I am using Ruby expressions to gate state transitions in a kind of
state machine. To prototype this I can use something like the
following Evaluator class:
class Evaluator
#add new data to evaluator
def add(var, obj)
# TODO?: I assume var is a string - enforce this?
instance_variable_set "@#{var}", obj
# dynamically add reader method, if not already present
if !methods.include?(var)
instance_eval("def #{var}; @#{var};end")
end
end
# test expression
def test(expression)
#TODO: handle NameError: undefined local variable or method errors
instance_eval(expression)
end
end # Evaluator
so that I can load data into my evaluator at runtime (with the add
method) and then test expressions based on that data with the test
call. An example irb session might be:
irb(main):002:0> e = Evaluator.new
=> #<Evaluator:0xb7c840d0>
irb(main):003:0> e.add("age", 20)
=> nil
irb(main):004:0> e.test("age>16")
=> true
irb(main):005:0> e.test("age>70")
=> false
In my program, the state machine will be defined declaratively and
loaded at runtime so an extended Evaluator object will have access to
a list of pre-defined expressions. As I will already know what the
expressions are I would like to be able to assist my users by warning
them when they present data that is incompatible with the current
expression list, so that for instance, if I knew that "age>16" was one
of my expressions then when someone added a value for "age" I could
test whether the presented object responded to the ">" call. To do
this I suppose I need to inspect the expressions and understand the
methods each variable requires (and thus whether the presented data
supports those methods) but I cannot see an easy way to do this. Can
I do this without building my own Ruby expression parser?
I have. I think I want introspection of Ruby Expressions, but my ruby
experience is limited and there may be an alternative approach that
I've missed...
I am using Ruby expressions to gate state transitions in a kind of
state machine. To prototype this I can use something like the
following Evaluator class:
class Evaluator
#add new data to evaluator
def add(var, obj)
# TODO?: I assume var is a string - enforce this?
instance_variable_set "@#{var}", obj
# dynamically add reader method, if not already present
if !methods.include?(var)
instance_eval("def #{var}; @#{var};end")
end
end
# test expression
def test(expression)
#TODO: handle NameError: undefined local variable or method errors
instance_eval(expression)
end
end # Evaluator
so that I can load data into my evaluator at runtime (with the add
method) and then test expressions based on that data with the test
call. An example irb session might be:
irb(main):002:0> e = Evaluator.new
=> #<Evaluator:0xb7c840d0>
irb(main):003:0> e.add("age", 20)
=> nil
irb(main):004:0> e.test("age>16")
=> true
irb(main):005:0> e.test("age>70")
=> false
In my program, the state machine will be defined declaratively and
loaded at runtime so an extended Evaluator object will have access to
a list of pre-defined expressions. As I will already know what the
expressions are I would like to be able to assist my users by warning
them when they present data that is incompatible with the current
expression list, so that for instance, if I knew that "age>16" was one
of my expressions then when someone added a value for "age" I could
test whether the presented object responded to the ">" call. To do
this I suppose I need to inspect the expressions and understand the
methods each variable requires (and thus whether the presented data
supports those methods) but I cannot see an easy way to do this. Can
I do this without building my own Ruby expression parser?