Class: Keisan::Context
- Inherits:
-
Object
- Object
- Keisan::Context
- Defined in:
- lib/keisan/context.rb
Instance Attribute Summary collapse
-
#allow_blocks ⇒ Object
readonly
Returns the value of attribute allow_blocks.
-
#allow_multiline ⇒ Object
readonly
Returns the value of attribute allow_multiline.
-
#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, allow_multiline: true, allow_blocks: true, 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, allow_multiline: true, allow_blocks: true, shadowed: []) ⇒ Context
Returns a new instance of Context.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/keisan/context.rb', line 9 def initialize(parent: nil, random: nil, allow_recursive: false, allow_multiline: true, allow_blocks: 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 end |
Instance Attribute Details
#allow_blocks ⇒ Object (readonly)
Returns the value of attribute allow_blocks.
3 4 5 |
# File 'lib/keisan/context.rb', line 3 def allow_blocks @allow_blocks end |
#allow_multiline ⇒ Object (readonly)
Returns the value of attribute allow_multiline.
3 4 5 |
# File 'lib/keisan/context.rb', line 3 def allow_multiline @allow_multiline end |
#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
24 25 26 |
# File 'lib/keisan/context.rb', line 24 def allow_recursive! @allow_recursive = true end |
#freeze ⇒ Object
28 29 30 31 32 |
# File 'lib/keisan/context.rb', line 28 def freeze super @function_registry.freeze @variable_registry.freeze end |
#function(name) ⇒ Object
93 94 95 |
# File 'lib/keisan/context.rb', line 93 def function(name) @function_registry[name.to_s] end |
#function_is_modifiable?(name) ⇒ Boolean
101 102 103 |
# File 'lib/keisan/context.rb', line 101 def function_is_modifiable?(name) @function_registry.modifiable?(name) end |
#has_function?(name) ⇒ Boolean
97 98 99 |
# File 'lib/keisan/context.rb', line 97 def has_function?(name) @function_registry.has?(name) end |
#has_variable?(name) ⇒ Boolean
77 78 79 |
# File 'lib/keisan/context.rb', line 77 def has_variable?(name) @variable_registry.has?(name) end |
#random ⇒ Object
113 114 115 |
# File 'lib/keisan/context.rb', line 113 def random @random || @parent&.random || Random.new end |
#register_function!(name, function, local: false) ⇒ Object
105 106 107 108 109 110 111 |
# File 'lib/keisan/context.rb', line 105 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
85 86 87 88 89 90 91 |
# File 'lib/keisan/context.rb', line 85 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.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/keisan/context.rb', line 39 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
69 70 71 |
# File 'lib/keisan/context.rb', line 69 def transient? !!@transient end |
#transient_definitions ⇒ Object
59 60 61 62 63 64 65 66 67 |
# File 'lib/keisan/context.rb', line 59 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
73 74 75 |
# File 'lib/keisan/context.rb', line 73 def variable(name) @variable_registry[name.to_s] end |
#variable_is_modifiable?(name) ⇒ Boolean
81 82 83 |
# File 'lib/keisan/context.rb', line 81 def variable_is_modifiable?(name) @variable_registry.modifiable?(name) end |