class Keisan::Context
Attributes
allow_blocks[R]
allow_multiline[R]
allow_random[R]
allow_recursive[R]
function_registry[R]
variable_registry[R]
Public Class Methods
new(parent: nil, random: nil, allow_recursive: false, allow_multiline: true, allow_blocks: true, allow_random: true, shadowed: [])
click to toggle source
# File lib/keisan/context.rb, line 10 def initialize(parent: nil, random: nil, allow_recursive: false, allow_multiline: true, allow_blocks: true, allow_random: true, shadowed: []) @parent = parent @function_registry = Functions::Registry.new(parent: @parent&.function_registry) @variable_registry = Variables::Registry.new(parent: @parent&.variable_registry, shadowed: shadowed) @random = random @allow_recursive = allow_recursive @allow_multiline = allow_multiline @allow_blocks = allow_blocks @allow_random = allow_random end
Public Instance Methods
allow_recursive!()
click to toggle source
# File lib/keisan/context.rb, line 27 def allow_recursive! @allow_recursive = true end
freeze()
click to toggle source
Calls superclass method
# File lib/keisan/context.rb, line 31 def freeze super @function_registry.freeze @variable_registry.freeze end
function(name)
click to toggle source
# File lib/keisan/context.rb, line 96 def function(name) @function_registry[name.to_s] end
function_is_modifiable?(name)
click to toggle source
# File lib/keisan/context.rb, line 104 def function_is_modifiable?(name) @function_registry.modifiable?(name) end
has_function?(name)
click to toggle source
# File lib/keisan/context.rb, line 100 def has_function?(name) @function_registry.has?(name) end
has_variable?(name)
click to toggle source
# File lib/keisan/context.rb, line 80 def has_variable?(name) @variable_registry.has?(name) end
random()
click to toggle source
# File lib/keisan/context.rb, line 116 def random raise Keisan::Exceptions::InvalidExpression.new("Context does not permit expressions with randomness") unless allow_random @random ||= @parent&.random || Random.new end
register_function!(name, function, local: false)
click to toggle source
# File lib/keisan/context.rb, line 108 def register_function!(name, function, local: false) if transient? || !local && @parent&.function_is_modifiable?(name) @parent.register_function!(name, function, local: local) else @function_registry.register!(name.to_s, function) end end
register_variable!(name, value, local: false)
click to toggle source
# File lib/keisan/context.rb, line 88 def register_variable!(name, value, local: false) if !@variable_registry.shadowed.member?(name) && (transient? || !local && @parent&.variable_is_modifiable?(name)) @parent.register_variable!(name, value, local: local) else @variable_registry.register!(name, value) end end
set_random(random)
click to toggle source
# File lib/keisan/context.rb, line 121 def set_random(random) raise Keisan::Exceptions::InvalidExpression.new("Context does not permit expressions with randomness") unless allow_random @random = random end
spawn_child(definitions: {}, shadowed: [], transient: nil)
click to toggle source
A transient context does not persist variables and functions in this context, but rather store them one level higher in the parent context. When evaluating a string, the entire operation is done in a transient context that is unique from the calculators current context, but such that variable/function definitions can be persisted in the calculator.
# File lib/keisan/context.rb, line 42 def spawn_child(definitions: {}, shadowed: [], transient: nil) child = pure_child(shadowed: shadowed) definitions.each do |name, value| case value when Proc child.register_function!(name, value) when Functions::ProcFunction child.register_function!(name, value.function_proc) else child.register_variable!(name, value) end end if transient.nil? && self.transient? || transient == true child.set_transient! end child end
transient?()
click to toggle source
# File lib/keisan/context.rb, line 72 def transient? !!@transient end
transient_definitions()
click to toggle source
# File lib/keisan/context.rb, line 62 def transient_definitions return {} unless @transient parent_definitions = @parent.nil? ? {} : @parent.transient_definitions parent_definitions.merge( @variable_registry.locals ).merge( @function_registry.locals ) end
variable(name)
click to toggle source
# File lib/keisan/context.rb, line 76 def variable(name) @variable_registry[name.to_s] end
variable_is_modifiable?(name)
click to toggle source
# File lib/keisan/context.rb, line 84 def variable_is_modifiable?(name) @variable_registry.modifiable?(name) end
Protected Instance Methods
pure_child(shadowed: [])
click to toggle source
# File lib/keisan/context.rb, line 132 def pure_child(shadowed: []) self.class.new( parent: self, shadowed: shadowed, allow_recursive: allow_recursive, allow_multiline: allow_multiline, allow_blocks: allow_blocks ) end
set_transient!()
click to toggle source
# File lib/keisan/context.rb, line 128 def set_transient! @transient = true end