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_random ⇒ Object
readonly
Returns the value of attribute allow_random.
-
#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, allow_random: 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
- #set_random(random) ⇒ 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, allow_random: true, shadowed: []) ⇒ Context
Returns a new instance of Context.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 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 |
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_random ⇒ Object (readonly)
Returns the value of attribute allow_random.
3 4 5 |
# File 'lib/keisan/context.rb', line 3 def allow_random @allow_random 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
27 28 29 |
# File 'lib/keisan/context.rb', line 27 def allow_recursive! @allow_recursive = true end |
#freeze ⇒ Object
31 32 33 34 35 |
# File 'lib/keisan/context.rb', line 31 def freeze super @function_registry.freeze @variable_registry.freeze end |
#function(name) ⇒ Object
96 97 98 |
# File 'lib/keisan/context.rb', line 96 def function(name) @function_registry[name.to_s] end |
#function_is_modifiable?(name) ⇒ Boolean
104 105 106 |
# File 'lib/keisan/context.rb', line 104 def function_is_modifiable?(name) @function_registry.modifiable?(name) end |
#has_function?(name) ⇒ Boolean
100 101 102 |
# File 'lib/keisan/context.rb', line 100 def has_function?(name) @function_registry.has?(name) end |
#has_variable?(name) ⇒ Boolean
80 81 82 |
# File 'lib/keisan/context.rb', line 80 def has_variable?(name) @variable_registry.has?(name) end |
#random ⇒ Object
116 117 118 119 |
# 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) ⇒ Object
108 109 110 111 112 113 114 |
# 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) ⇒ Object
88 89 90 91 92 93 94 |
# 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) ⇒ Object
121 122 123 124 |
# 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) ⇒ 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.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# 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? ⇒ Boolean
72 73 74 |
# File 'lib/keisan/context.rb', line 72 def transient? !!@transient end |
#transient_definitions ⇒ Object
62 63 64 65 66 67 68 69 70 |
# 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) ⇒ Object
76 77 78 |
# File 'lib/keisan/context.rb', line 76 def variable(name) @variable_registry[name.to_s] end |
#variable_is_modifiable?(name) ⇒ Boolean
84 85 86 |
# File 'lib/keisan/context.rb', line 84 def variable_is_modifiable?(name) @variable_registry.modifiable?(name) end |