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 = {}) ⇒ 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, overrides = {}) ⇒ LazyEvaluator
constructor
Creates a new evaluator.
- #lazy_eval(val) ⇒ Object
- #method_missing(symbol, *args) ⇒ Object
-
#parent ⇒ Object
Returns a LazyEvaluator for the parent of this data object.
Constructor Details
#initialize(obj, overrides = {}) ⇒ LazyEvaluator
Creates a new evaluator. All lazy evaluation is performed in the context of obj
. overrides
is an optional obj.parameters
like hash.
45 46 47 48 |
# File 'lib/bindata/lazy.rb', line 45 def initialize(obj, overrides = {}) @obj = obj @overrides = overrides end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args) ⇒ Object
86 87 88 89 90 91 92 93 94 |
# File 'lib/bindata/lazy.rb', line 86 def method_missing(symbol, *args) return @overrides[symbol] if @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 = {}) ⇒ 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 = {}) if can_eval?(val) env = self.new(obj, overrides) env.lazy_eval(val) else val end end |
Instance Method Details
#index ⇒ Object
Returns the index of this data object inside it’s nearest container array.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/bindata/lazy.rb', line 71 def index return @overrides[:index] if @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) ⇒ Object
50 51 52 53 54 55 56 57 58 |
# File 'lib/bindata/lazy.rb', line 50 def lazy_eval(val) if val.is_a? Symbol __send__(val) elsif val.respond_to? :arity instance_eval(&val) else val end end |
#parent ⇒ Object
Returns a LazyEvaluator for the parent of this data object.
61 62 63 64 65 66 67 |
# File 'lib/bindata/lazy.rb', line 61 def parent if @obj.parent LazyEvaluator.new(@obj.parent) else nil end end |