Class: BinData::LazyEvaluator
- Inherits:
-
Object
- Object
- BinData::LazyEvaluator
- Defined in:
- lib/bindata/lazy.rb
Overview
A LazyEvaluator is bound to a data object. The evaluator will evaluate lambdas in the context of this data object. These lambdas are those that are passed to data objects as parameters, e.g.:
BinData::String.new(value: -> { %w(a test message).join(" ") })
As a shortcut, :foo is the equivalent of lambda { foo }.
When evaluating lambdas, unknown methods are resolved in the context of the parent of the bound data object. Resolution is attempted firstly as keys in #parameters, and secondly as methods in this parent. This resolution propagates up the chain of parent data objects.
An evaluation will recurse until it returns a result that is not a lambda or a symbol.
This resolution process makes the lambda easier to read as we just write field
instead of obj.field
.
Instance Method Summary collapse
-
#index ⇒ Object
Returns the index of this data object inside it’s nearest container array.
-
#initialize(obj) ⇒ LazyEvaluator
constructor
Creates a new evaluator.
- #lazy_eval(val, overrides = nil) ⇒ Object
- #method_missing(symbol, *args) ⇒ Object
-
#parent ⇒ Object
Returns a LazyEvaluator for the parent of this data object.
Constructor Details
#initialize(obj) ⇒ LazyEvaluator
Creates a new evaluator. All lazy evaluation is performed in the context of obj
.
24 25 26 |
# File 'lib/bindata/lazy.rb', line 24 def initialize(obj) @obj = obj end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args) ⇒ Object
65 66 67 68 69 70 71 72 73 |
# File 'lib/bindata/lazy.rb', line 65 def method_missing(symbol, *args) return @overrides[symbol] if defined?(@overrides) && @overrides.key?(symbol) if @obj.parent eval_symbol_in_parent_context(symbol, args) else super end end |
Instance Method Details
#index ⇒ Object
Returns the index of this data object inside it’s nearest container array.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/bindata/lazy.rb', line 50 def index return @overrides[:index] if defined?(@overrides) && @overrides.key?(:index) child = @obj parent = @obj.parent while parent if parent.respond_to?(:find_index_of) return parent.find_index_of(child) end child = parent parent = parent.parent end raise NoMethodError, "no index found" end |
#lazy_eval(val, overrides = nil) ⇒ Object
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/bindata/lazy.rb', line 28 def lazy_eval(val, overrides = nil) @overrides = overrides if overrides if val.is_a? Symbol __send__(val) elsif callable?(val) instance_exec(&val) else val end end |
#parent ⇒ Object
Returns a LazyEvaluator for the parent of this data object.
40 41 42 43 44 45 46 |
# File 'lib/bindata/lazy.rb', line 40 def parent if @obj.parent @obj.parent.lazy_evaluator else nil end end |