Class: Keisan::Context
- Inherits:
-
Object
- Object
- Keisan::Context
- Defined in:
- lib/keisan/context.rb
Instance Attribute Summary collapse
-
#allow_recursive ⇒ Object
readonly
Returns the value of attribute allow_recursive.
-
#function_registry ⇒ Object
readonly
Returns the value of attribute function_registry.
-
#variable_registry ⇒ Object
readonly
Returns the value of attribute variable_registry.
Instance Method Summary collapse
- #allow_recursive! ⇒ Object
- #freeze ⇒ Object
- #function(name) ⇒ Object
- #function_is_modifiable?(name) ⇒ Boolean
- #has_function?(name) ⇒ Boolean
- #has_variable?(name) ⇒ Boolean
-
#initialize(parent: nil, random: nil, allow_recursive: false, shadowed: []) ⇒ Context
constructor
A new instance of Context.
- #random ⇒ Object
- #register_function!(name, function, local: false) ⇒ Object
- #register_variable!(name, value, local: false) ⇒ Object
-
#spawn_child(definitions: {}, shadowed: [], transient: nil) ⇒ Object
A transient context does not persist variables and functions in this context, but rather store them one level higher in the parent context.
- #transient? ⇒ Boolean
- #transient_definitions ⇒ Object
- #variable(name) ⇒ Object
- #variable_is_modifiable?(name) ⇒ Boolean
Constructor Details
#initialize(parent: nil, random: nil, allow_recursive: false, shadowed: []) ⇒ Context
Returns a new instance of Context.
5 6 7 8 9 10 11 |
# File 'lib/keisan/context.rb', line 5 def initialize(parent: nil, random: nil, allow_recursive: false, 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 end |
Instance Attribute Details
#allow_recursive ⇒ Object (readonly)
Returns the value of attribute allow_recursive.
3 4 5 |
# File 'lib/keisan/context.rb', line 3 def allow_recursive @allow_recursive end |
#function_registry ⇒ Object (readonly)
Returns the value of attribute function_registry.
3 4 5 |
# File 'lib/keisan/context.rb', line 3 def function_registry @function_registry end |
#variable_registry ⇒ Object (readonly)
Returns the value of attribute variable_registry.
3 4 5 |
# File 'lib/keisan/context.rb', line 3 def variable_registry @variable_registry end |
Instance Method Details
#allow_recursive! ⇒ Object
13 14 15 |
# File 'lib/keisan/context.rb', line 13 def allow_recursive! @allow_recursive = true end |
#freeze ⇒ Object
17 18 19 20 21 |
# File 'lib/keisan/context.rb', line 17 def freeze super @function_registry.freeze @variable_registry.freeze end |
#function(name) ⇒ Object
82 83 84 |
# File 'lib/keisan/context.rb', line 82 def function(name) @function_registry[name.to_s] end |
#function_is_modifiable?(name) ⇒ Boolean
90 91 92 |
# File 'lib/keisan/context.rb', line 90 def function_is_modifiable?(name) @function_registry.modifiable?(name) end |
#has_function?(name) ⇒ Boolean
86 87 88 |
# File 'lib/keisan/context.rb', line 86 def has_function?(name) @function_registry.has?(name) end |
#has_variable?(name) ⇒ Boolean
66 67 68 |
# File 'lib/keisan/context.rb', line 66 def has_variable?(name) @variable_registry.has?(name) end |
#random ⇒ Object
102 103 104 |
# File 'lib/keisan/context.rb', line 102 def random @random || @parent&.random || Random.new end |
#register_function!(name, function, local: false) ⇒ Object
94 95 96 97 98 99 100 |
# File 'lib/keisan/context.rb', line 94 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) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/keisan/context.rb', line 74 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 |
#spawn_child(definitions: {}, shadowed: [], transient: nil) ⇒ Object
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.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/keisan/context.rb', line 28 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? ⇒ Boolean
58 59 60 |
# File 'lib/keisan/context.rb', line 58 def transient? !!@transient end |
#transient_definitions ⇒ Object
48 49 50 51 52 53 54 55 56 |
# File 'lib/keisan/context.rb', line 48 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) ⇒ Object
62 63 64 |
# File 'lib/keisan/context.rb', line 62 def variable(name) @variable_registry[name.to_s] end |
#variable_is_modifiable?(name) ⇒ Boolean
70 71 72 |
# File 'lib/keisan/context.rb', line 70 def variable_is_modifiable?(name) @variable_registry.modifiable?(name) end |