Ravn::Actor::
Statefulness
module
A mixin that adds persistent state managed by the StateManager to a Ravn::Actor
.
- DEFAULT_VARIABLE_OPTIONS
The default optiosn for variables
Extension callback – install instance methods in the extended object
.
def self::extended( object )
super
object.instance_variable_set( :@stateful_variables, {} )
object.singleton_class.attr_reader( :stateful_variables )
object.prepend( InstanceMethods )
end
Inheritance hook – give subclasses their own stateful variables.
def inherited( subclass )
super
subclass.instance_variable_set( :@stateful_variables, {} )
subclass.define_singleton_method( :stateful_variables ) do
inherited_vars = superclass.stateful_variables
self.log.warn "Returning stateful_variables merged into %p" % [ inherited_vars ]
return inherited_vars.merge( @stateful_variables )
end
end
make_stateful_variable_predicate( name, **options )
Return a lambda for the method body of a instance predicate for the variable named name
. The options
control specialized behavior of the method.
def make_stateful_variable_predicate( name, **options )
default = Ravn::DataUtilities.deep_copy( options[:default] )
return lambda do
self.state_proxy.fetch( name, default ) ? true : false
end
end
make_stateful_variable_reader( name, **options )
Return a lambda for the method body of a instance reader for the variable named name
. The options
control specialized behavior of the method.
def make_stateful_variable_reader( name, **options )
default = Ravn::DataUtilities.deep_copy( options[:default] )
return lambda do
self.state_proxy.fetch( name, default )
end
end
make_stateful_variable_writer( name, **options )
Return a lambda for the method body of a instance writer for the variable named name
. The options
control specialized behavior of the method.
def make_stateful_variable_writer( name, **options )
return lambda do |new_value|
self.state_proxy.store( name, new_value )
end
end
stateful_variable( name, **options )
Declare a stateful variable that will be associated with the Bolt.
def stateful_variable( name, **options )
self.log.debug "Adding a %p stateful variable: %p" % [ name, options ]
options = DEFAULT_VARIABLE_OPTIONS.merge( options )
if self.instance_methods.include?( name.to_sym )
raise ScriptError,
"%p stateful variable collides with existing instance method." % [ name ]
end
@stateful_variables[ name ] = options
if options[:predicate]
predicate = self.make_stateful_variable_predicate( name, **options )
define_method( "#{name}?", &predicate )
else
reader = self.make_stateful_variable_reader( name, **options )
define_method( name, &reader )
end
writer = self.make_stateful_variable_writer( name, **options )
define_method( "#{name}=", &writer )
end
stateful_variable_defaults()
Return a hash of declared variables and their default values.
def stateful_variable_defaults
return self.stateful_variables.each_with_object( {} ) do |(var, opts), acc|
default = opts[ :default ]
acc[ var ] = default
end
end