Class: BinData::LazyEvalEnv
- Inherits:
-
Object
- Object
- BinData::LazyEvalEnv
- Defined in:
- lib/bindata/lazy.rb
Overview
The enviroment in which a lazily evaluated lamba is called. These lambdas are those that are passed to data objects as parameters. Each lambda has access to the following:
- parent
-
the environment of the parent data object
- params
-
any extra parameters that have been passed to the data object. The value of a parameter is either a lambda, a symbol or a literal value (such as a Fixnum).
Unknown methods are resolved in the context of the parent environment, first as keys in the extra parameters, and secondly as methods in the parent data object. This makes the lambda easier to read as we just write field
instead of obj.field
.
Instance Attribute Summary collapse
-
#data_object ⇒ Object
writeonly
Sets the attribute data_object.
-
#params ⇒ Object
Returns the value of attribute params.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
Instance Method Summary collapse
-
#add_variable(sym, value) ⇒ Object
Add a variable with a pre-assigned value to this environment.
-
#initialize(parent = nil) ⇒ LazyEvalEnv
constructor
Creates a new environment.
-
#lazy_eval(obj, overrides = {}) ⇒ Object
Evaluates
obj
in the context of this environment. - #method_missing(symbol, *args) ⇒ Object
-
#offset_of(sym) ⇒ Object
TODO: offset_of needs to be better thought out.
-
#parent_data_object ⇒ Object
Returns the data_object for the parent environment.
Constructor Details
#initialize(parent = nil) ⇒ LazyEvalEnv
Creates a new environment. parent
is the environment of the parent data object.
18 19 20 21 22 |
# File 'lib/bindata/lazy.rb', line 18 def initialize(parent = nil) @parent = parent @variables = {} @overrides = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/bindata/lazy.rb', line 62 def method_missing(symbol, *args) if @overrides.include?(symbol) @overrides[symbol] elsif @variables.include?(symbol) @variables[symbol] elsif @parent obj = symbol if @parent.params and @parent.params.has_key?(symbol) obj = @parent.params[symbol] elsif @parent.data_object and @parent.data_object.respond_to?(symbol) obj = @parent.data_object.__send__(symbol, *args) end @parent.lazy_eval(obj) else super end end |
Instance Attribute Details
#data_object=(value) ⇒ Object
Sets the attribute data_object
24 25 26 |
# File 'lib/bindata/lazy.rb', line 24 def data_object=(value) @data_object = value end |
#params ⇒ Object
Returns the value of attribute params.
24 25 26 |
# File 'lib/bindata/lazy.rb', line 24 def params @params end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
23 24 25 |
# File 'lib/bindata/lazy.rb', line 23 def parent @parent end |
Instance Method Details
#add_variable(sym, value) ⇒ Object
Add a variable with a pre-assigned value to this environment. sym
will be accessible as a variable for any lambda evaluated with #lazy_eval.
32 33 34 |
# File 'lib/bindata/lazy.rb', line 32 def add_variable(sym, value) @variables[sym.to_sym] = value end |
#lazy_eval(obj, overrides = {}) ⇒ Object
Evaluates obj
in the context of this environment. Evaluation recurses until it yields a value that is not a symbol or lambda.
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/bindata/lazy.rb', line 50 def lazy_eval(obj, overrides = {}) @overrides = overrides if obj.is_a? Symbol # treat :foo as lambda { foo } obj = __send__(obj) elsif obj.respond_to? :arity obj = instance_eval(&obj) end @overrides = {} obj end |
#offset_of(sym) ⇒ Object
TODO: offset_of needs to be better thought out
37 38 39 40 41 |
# File 'lib/bindata/lazy.rb', line 37 def offset_of(sym) @parent.data_object.offset_of(sym) rescue nil end |
#parent_data_object ⇒ Object
Returns the data_object for the parent environment.
44 45 46 |
# File 'lib/bindata/lazy.rb', line 44 def parent_data_object @parent.nil? ? nil : @parent.data_object end |