Class: Reduxco::Context::CallableTable
- Inherits:
-
Object
- Object
- Reduxco::Context::CallableTable
- Defined in:
- lib/reduxco/context/callable_table.rb
Overview
CallableTable is a ‘private’ helper class to Context which handles resolving CallableRef instances to their appropriate callables. This should not be used directly.
Constant Summary collapse
- RESOLUTION_FAILURE =
The constant returned by
resolve
when resolution failure occurs. This constant can be multiply assigned to the same pattern as a normal resolution, but will assign nil into each value. [nil,nil]
Instance Method Summary collapse
-
#include?(callref) ⇒ Boolean
Returns true if the call with teh given callref exists.
-
#initialize(callable_map_list) ⇒ CallableTable
constructor
Instantiate with list of callable maps.
-
#resolve(callref) ⇒ Object
(also: #[])
Resolves the given callref.
-
#resolve_super(callref) ⇒ Object
Given a static callref, resolves the next available shadowed callable above it.
Constructor Details
#initialize(callable_map_list) ⇒ CallableTable
Instantiate with list of callable maps.
16 17 18 |
# File 'lib/reduxco/context/callable_table.rb', line 16 def initialize(callable_map_list) @table = Hash[flatten(callable_map_list).sort.reverse] end |
Instance Method Details
#include?(callref) ⇒ Boolean
Returns true if the call with teh given callref exists.
37 38 39 |
# File 'lib/reduxco/context/callable_table.rb', line 37 def include?(callref) !resolve(callref).last.nil? end |
#resolve(callref) ⇒ Object Also known as: []
Resolves the given callref. The return value usually takes advantage of multiple assignment to dissect the return into the matching callref and found callable. however one can check for failed resolution simply by comparing the result to RESOLUTION_FAILURE.
Note that if resolution fails, each value in the multiple assignment is given the value nil.
27 28 29 30 31 32 33 |
# File 'lib/reduxco/context/callable_table.rb', line 27 def resolve(callref) if( callref.static? ) @table.include?(callref) ? [callref, @table[callref]] : RESOLUTION_FAILURE else @table.find(->{RESOLUTION_FAILURE}) {|refkey, callable| callref.include?(refkey)} end end |
#resolve_super(callref) ⇒ Object
Given a static callref, resolves the next available shadowed callable above it. If the callref is dynamic, then an exception is thrown.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/reduxco/context/callable_table.rb', line 43 def resolve_super(callref) if( callref.dynamic? ) raise ArgumentError, "Cannot resolve the 'super' of a dyanmic CallableReference.", caller else # This is really nice, but runs in O(n): # @table.find(->{RESOLUTION_FAILURE}) {|refkey, callable| refkey.name == callref.name && refkey.depth < callref.depth} # This is more performant on large tables O(1) but has the potential for a lot of recursion depth: # if( callref.depth <= CallableRef::MIN_DEPTH ) # RESOLUTION_FAILURE # else # resolution = resolve(callref.pred) # resolution == RESOLUTION_FAILURE ? resolve_super(callref.pred) : resolution # end # So we go for this imperative C-style flat iteration for O(1) and no recursion. ref = callref while( ref.depth > CallableRef::MIN_DEPTH ) ref = ref.pred resolution = resolve(ref) return resolution if(resolution != RESOLUTION_FAILURE) end RESOLUTION_FAILURE end end |