I have a class with two states, "state1" and "state2" (there can be only two states, and it never changes since instance's creation) and following code
class MyClass
attr_accessor :myvar1, :myvar2, :state
include Extension1
include Extension2
def func1
send("#{self.state}_func1")
end
def otherfunc
send("#{self.state}_otherfunc")
end
def anotherfunc
send("#{self.state}_anotherfunc")
end
end
module Extension1 #handles state1 functions
def state1_func1
#do something using MyClass instance vars
end
def state1_otherfunc
#do something using MyClass instance vars
end
def state1_anotherfunc
#do something using MyClass instance vars
end
end
module Extension2 #handles state2 functions
def state2_func1
#do something using MyClass instance vars
end
def state2_otherfunc
#do something using MyClass instance vars
end
def state2_anotherfunc
#do something using MyClass instance vars
end
end
How this code can be improved? (this example is very basic, actual object has two state attributes at once, and i need to override first state's state_machine events based on the second state)
In response to toro2k's comment, I'm taking the freedom of showing how I do things at home in cases like this one:
module Ext1
def f
puts "state a action"
end
end
module Ext2
def f
puts "state b action"
end
end
class X
attr_reader :state
def initialize( state=:a )
@state = state
extend case state
when :a then Ext1
when :b then Ext2
end
end
end
a, b = [ :a, :b ].map &X.method( :new )
a.f # ...
b.f # ...
But this is quite different from the line of thinking that Pavel has asked about in his question.
Note: Pavel's instance "state" never changes, so there are no transitions. Should there be multiple states and transitions between them, you would have a place/transition net, aka. Petri net sensu lato, embedded in the instance. This would be handled by my y_petri
gem, in which places and transitions are objects on their own right and belong to a Net
object, which would be an attribute of the MyClass
instance, and whose state vector would govern its behavior in the way similar to the one that you or Pavel suggested. Another gem that can be considered is the state machine
gem.