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 => lambda { %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
.
Class Method Summary collapse
-
.eval(obj, val, overrides = nil) ⇒ Object
Lazily evaluates
val
in the context ofobj
, with possibility ofoverrides
.
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
.
44 45 46 |
# File 'lib/bindata/lazy.rb', line 44 def initialize(obj) @obj = obj end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args) ⇒ Object
85 86 87 88 89 90 91 92 93 |
# File 'lib/bindata/lazy.rb', line 85 def method_missing(symbol, *args) return @overrides[symbol] if @overrides and @overrides.has_key?(symbol) if @obj.parent eval_symbol_in_parent_context(symbol, args) else super end end |
Class Method Details
.eval(obj, val, overrides = nil) ⇒ Object
Lazily evaluates val
in the context of obj
, with possibility of overrides
.
25 26 27 28 29 30 31 32 |
# File 'lib/bindata/lazy.rb', line 25 def eval(obj, val, overrides = nil) if can_eval?(val) env = self.new(obj) env.lazy_eval(val, overrides) else val end end |
Instance Method Details
#index ⇒ Object
Returns the index of this data object inside it’s nearest container array.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/bindata/lazy.rb', line 70 def index return @overrides[:index] if @overrides and @overrides.has_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
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/bindata/lazy.rb', line 48 def lazy_eval(val, overrides = nil) @overrides = overrides if overrides if val.is_a? Symbol __send__(val) elsif val.respond_to? :arity instance_exec(&val) else val end end |
#parent ⇒ Object
Returns a LazyEvaluator for the parent of this data object.
60 61 62 63 64 65 66 |
# File 'lib/bindata/lazy.rb', line 60 def parent if @obj.parent LazyEvaluator.new(@obj.parent) else nil end end |