Closed shioyama closed 5 years ago
Hi Chris,
What you described seems like a sensible request. The reason I designed FiniteMachine
this way is to ensure separation and as little coupling as possible. The danger with including/inheriting from the machine and being able to add your methods is as with any inheritance really, you can overwrite interface that otherwise shouldn't be tinkered with.
You have to also recognise the ambiguity of your request. In the past I had some lookup rules when a method didn't exist on machine itself, then methods on target would be checked. Bear in mind that all events are also methods that can be called and in a way pollute the machine namespace. By always being explicit that we call a method on the target, we remove any ambiguity.
Having said that, I would be happy to consider an alternative implementation to FiniteMachine::Definition
that allows extending finite machine with custom methods outside of target context. Do you have anything in mind, can you work up a PR?
Thanks for the thoughtful reply!
Bear in mind that all events are also methods that can be called and in a way pollute the machine namespace. By always being explicit that we call a method on the target, we remove any ambiguity.
Yes I've noticed this issue, and in the end I feel that the immediate scope is probably not the best place to define helper methods.
I'm going to close this for now and see if I can work within the existing constraints.
Thanks again!
Great gem! Really nicely designed with the level of customization I was looking for. :smile:
Now to my one little problem...
Problem
I have a lot of custom methods which I use in
if
conditionals, etc. which do not belong in thetarget
and which in any case ideally I'd like to access directly in transition blocks. In the readme the recommendation is to write code like this:But as complexity is added to the machine, I would really prefer to just call
turn_engine_on
etc. here and define that method on the machine itself. Especially if (as in my case)turn_engine_on
is not a method that only relates to the state machine logic and does not belong on the target.I can do this by subclassing
FiniteMachine::StateMachine
, which works more or less, but it means that to define the machine itself I need to overrideinitialize
and define the block in there, which doesn't seem right. The recommended way is to useFiniteMachine::Definition
, but doing that means that you can't define these local methods on the finite machine itself, since internallyFiniteMachine::Definition.new
hard-codesFiniteMachine
here:https://github.com/piotrmurach/finite_machine/blob/b956cf3b50870734c6a350e65141208e96a8c1b9/lib/finite_machine/definition.rb#L39-L44
What would be the recommended way to define methods for the machine which are locally accessible in block contexts? I feel this is an important issue when thinking about encapsulating machine-specific logic within the machine itself rather than in the target.
Thanks for reading :smile: And keep up the great work on the gem.