Class: Arrow::Template::RenderingScope

Inherits:
Arrow::Object show all
Defined in:
lib/arrow/template.rb

Overview

A class for objects which contain the execution space of all the code in a single rendering of a template.

Instance Method Summary

Methods inherited from Arrow::Object

deprecate_class_method, deprecate_method, inherited

Methods included from Arrow::Loggable

#log

Constructor Details

- (RenderingScope) initialize(defs = {})

Create a new RenderingScope object with the specified definitions defs. Each key => value pair in defs will become singleton accessors on the resulting object.



78
79
80
81
# File 'lib/arrow/template.rb', line 78

def initialize( defs={} )
  @definitions = []
  self.add_definition_set( defs )
end

Instance Method Details

- (Object) add_definition_set(defs)

Add the specified definitions defs to the object.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/arrow/template.rb', line 97

def add_definition_set( defs )
  # self.log.debug "adding definition set: %p" % [ defs ]
  @definitions.push( defs )

  defs.each do |name,val|
    raise Arrow::ScopeError, "Cannot add a definition with a blank key" if
      name.to_s.empty?
    raise Arrow::ScopeError, "Cannot override @definitions" if
      name == 'definitions'
    @definitions.last[ name ] = val

    # Add accessor and ivar for the definition if it doesn't
    # already have one.
    unless self.respond_to?( name.to_s.to_sym )
      #self.log.debug "Adding accessor for %s" % name
      (class << self; self; end).instance_eval {
        attr_accessor name.to_s.to_sym
      }
    else
      #self.log.debug "Already have an accessor for '#{name}'"
    end

    self.instance_variable_set( "@#{name}", defs[name] )
  end
end

- (Object) get_binding

Fetch the Binding object for the RenderingScope.



93
# File 'lib/arrow/template.rb', line 93

def get_binding; binding end

- (Object) override(defs)

Override the given definitions defs for the duration of the given block. After the block exits, the original definitions will be restored.



164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/arrow/template.rb', line 164

def override( defs ) # :yields: receiver
  begin
    #self.log.debug "Before adding definitions: %d scope frame/s. Last: %p" %
    # [ @definitions.nitems, @definitions.last.keys ]
    self.add_definition_set( defs )
    #self.log.debug "After adding definitions: %d scope frame/s. Last: %p" % 
    # [ @definitions.nitems, @definitions.last.keys ]
    yield( self )
  ensure
    self.remove_definition_set
  end
end

- (Object) remove_definition_set

Remove the specified definitions defs from the object. Using a definition so removed after this point will raise an error.



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/arrow/template.rb', line 126

def remove_definition_set
  #self.log.debug "Removing definition set from stack of %d frames" %
  #  @definitions.nitems
  defs = @definitions.pop
  #self.log.debug "Removing defs: %p, %d frames left" % 
  #  [ defs, @definitions.nitems ]

  defs.keys.each do |name|
    next if name == 'definitions'

    # If there was already a definition in effect with the same
    # name in a previous scope, fetch it so we can play with it.
    previousSet = @definitions.reverse.find {|set| set.key?(name)}
    #self.log.debug "Found previousSet %p for %s in scope stack of %d frames" %
    # [ previousSet, name, @definitions.nitems ]

    # If none of the previous definition sets had a definition
    # with the same name, remove the accessor and the ivar
    unless previousSet
      #self.log.debug "Removing definition '%s' entirely" % name
      (class << self; self; end).module_eval {
        remove_method name.to_s.to_sym
      }
      remove_instance_variable( "@#{name}" )

    # Otherwise just reset the ivar to the previous value
    else
      #self.log.debug "Restoring previous def for '%s'" % name
      self.instance_variable_set( "@#{name}", previousSet[name] )
    end
  end

end