Class: BinData::LazyEvalEnv

Inherits:
Object
  • Object
show all
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).

value

the value of the data object if it is single

index

the index of the data object if it is in an array

offset

the current offset of the IO object when reading

Unknown methods are resolved in the context of the parent data object, 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

Instance Method Summary collapse

Constructor Details

#initialize(parent = nil) ⇒ LazyEvalEnv

Creates a new environment. parent is the environment of the parent data object.



21
22
23
# File 'lib/bindata/lazy.rb', line 21

def initialize(parent = nil)
  @parent = parent
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/bindata/lazy.rb', line 63

def method_missing(symbol, *args)
  if @parent and @parent.params and @parent.params.has_key?(symbol)
    # is there a param with this name?
    @parent.lazy_eval(@parent.params[symbol])
  elsif @parent and @parent.data_object and
          @parent.data_object.respond_to?(symbol)
    # how about a field or method in the parent?
    @parent.data_object.__send__(symbol, *args)
  else
    super
  end
end

Instance Attribute Details

#data_object=(value) ⇒ Object

Sets the attribute data_object

Parameters:

  • value

    the value to set the attribute data_object to.



25
26
27
# File 'lib/bindata/lazy.rb', line 25

def data_object=(value)
  @data_object = value
end

#indexObject

Returns the value of attribute index.



25
26
27
# File 'lib/bindata/lazy.rb', line 25

def index
  @index
end

#offsetObject

Returns the value of attribute offset.



25
26
27
# File 'lib/bindata/lazy.rb', line 25

def offset
  @offset
end

#paramsObject

Returns the value of attribute params.



25
26
27
# File 'lib/bindata/lazy.rb', line 25

def params
  @params
end

#parentObject (readonly)

Returns the value of attribute parent.



24
25
26
# File 'lib/bindata/lazy.rb', line 24

def parent
  @parent
end

Instance Method Details

#lazy_eval(obj) ⇒ Object

Evaluates obj in the context of this environment. Evaluation recurses until it yields a value that is not a symbol or lambda.



52
53
54
55
56
57
58
59
60
61
# File 'lib/bindata/lazy.rb', line 52

def lazy_eval(obj)
  if obj.is_a? Symbol
    # treat :foo as lambda { foo }
    lazy_eval(__send__(obj))
  elsif obj.respond_to? :arity
    instance_eval(&obj)
  else
    obj
  end
end

#offset_of(sym) ⇒ Object

TODO: offset_of needs to be better thought out



31
32
33
34
35
36
37
38
# File 'lib/bindata/lazy.rb', line 31

def offset_of(sym)
  if @parent and @parent.data_object and
          @parent.data_object.respond_to?(:offset_of)
    @parent.data_object.offset_of(sym)
  else
    nil
  end
end

#parent_data_objectObject

Returns the data_object for the parent environment.



41
42
43
# File 'lib/bindata/lazy.rb', line 41

def parent_data_object
  @parent.nil? ? nil : @parent.data_object
end

#valueObject

Returns the value of the data object wrapped by this environment.



46
47
48
# File 'lib/bindata/lazy.rb', line 46

def value
  @data_object.respond_to?(:value) ? @data_object.value : nil
end