1

Here is the string spec:

  "state :initial_state do
      event :submit, :transitions_to => :acct_init_reviewing
    end
    state :paid
    state :rejected"

We need to convert it into plain ruby code inside a workflow loop:

 workflow do
    state :initial_state do
      event :submit, :transitions_to => :acct_init_reviewing
    end
    state :paid
    state :rejected
 end 

We tried eval without luck:

 workflow do
   eval(spec)
 end

eval(spec) returns nil. How to convert a string into plain ruby code for execution?

1 Answer 1

2

The eval function returns the result of evaluating your code. That it's nil in this case is not surprising, as state probably returns nil.

You could just construct the whole thing and evaluate that:

eval("workflow { %s }" % code)

The workflow method might alter the binding on the block given that makes it behave in an unusual way, so expanding the code to include that could help.

It's worth noting that using eval to evaluate arbitrary code can be very risky so be absolutely sure that you have control over what's going into this thing.

Sign up to request clarification or add additional context in comments.

5 Comments

Thought about eval the whole thing and it may work. spec is by developer and safe. eval("Workflow::ClassMethods.workflow {%s}" % spec) returns undefined method workflow' for Workflow::ClassMethods:Module. If changed to eval("Workflow::ClassMethods.workflow {%s}" + spec), then it returns (eval):1: unterminated string meets end of file (eval):1: syntax error, unexpected end-of-input, expecting '}' state :rejected ^. Not sure what is still missing.
Calling anything inside of ClassMethods directly seems broken and wrong. Shouldn't that be something another class imports with include? What context are you calling workflow on? You may need to call eval with a binding option to set the proper context.
module ClassMethods is inside module Workflow, method is inside module ClassMethods. It is kind of odd. I probably will post for the problem if can't figure it out.
What's the %s for within {}?
That's an easy way of substituting code, but you could also use #{code} instead. I just thought seeing { #{code} } would look confusing since the two sets of brackets mean entirely different things.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.