Class: Arrow::Template::RenderingScope

Inherits:
Object
  • 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 collapse

Methods inherited from Object

deprecate_class_method, deprecate_method, inherited

Constructor Details

#initialize(defs = {}) ⇒ RenderingScope

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

#add_definition_set(defs) ⇒ Object

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

#get_bindingObject

Fetch the Binding object for the RenderingScope.



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

def get_binding; binding; end

#override(defs) ⇒ Object

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

#remove_definition_setObject

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