Class: LtdTemplate::Proxy::Array

Inherits:
LtdTemplate::Proxy show all
Includes:
XKeys::Hash
Defined in:
lib/ltdtemplate/proxy/array.rb

Instance Attribute Summary

Attributes included from Value

#runtime_methods

Instance Method Summary collapse

Methods inherited from LtdTemplate::Proxy

#initialize, #rubyverse_original, #rubyversed

Methods included from Value

#do_methods, #do_run_method, included, #initialize, #inspect, #rubyversed, #tpl_boolean

Constructor Details

This class inherits a constructor from LtdTemplate::Proxy

Instance Method Details

#do_each(opts) ⇒ Object

Loop over each key, value



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/ltdtemplate/proxy/array.rb', line 143

def do_each (opts)
	results = @template.factory :array
	if params = opts[:parameters] and params.size(:seq) > 0
 body = params[0]
 if opts[:method] != 'each_rnd'
		(seq = self.positional).each_index do |idx|
  @template.use :iterations
  each_params = @template.factory(:array).
    push idx, self[idx]
  results.push body.evaluate(:method => 'each_seq',
    :parameters => each_params)
  @template.using :array_size, results.size
		end
 end
 if opts[:method] != 'each_seq'
		(rnd = self.named).each do |key, val|
  @template.use :iterations
  each_params = @template.factory(:array).
    push key, val
  results.push body.evaluate(:method => 'each_rnd',
    :parameters => each_params)
  @template.using :array_size, results.size
		end
 end
	end
	results
end

#do_join(opts) ⇒ Object

Combine sequential array element values into a string



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/ltdtemplate/proxy/array.rb', line 172

def do_join (opts)
	two = first = middle = last = ''
	if params = opts[:parameters]
 if params.size(:seq) > 3
		two, first, middle, last = params[0..3].values
 elsif params.size(:seq) > 0
		two = first = middle = last = params[0]
 end
	end

	text = self.positional.map { |val| rubyversed(val).tpl_text }
	case text.size
	when 0 then ''
	when 1 then text[0]
	when 2 then "#{text[0]}#{two}#{text[1]}"
	else "#{text[0]}#{first}" + text[1..-2].join(middle) +
	  "#{last}#{text[-1]}"
	end.tap do |str|
 # RESOURCE string_total: Combined length of computed strings
 @template.use :string_total, str.size
 # RESOURCE string_length: Length of longest modified string
 @template.using :string_length, str.size
	end
end

#do_pop(opts) ⇒ Object

Pop a value off the right end of the array.



198
199
200
201
202
203
204
# File 'lib/ltdtemplate/proxy/array.rb', line 198

def do_pop (opts)
	if @original.respond_to? :pop
 @template.use :array_growth, -1
 @original.pop
	else nil
	end
end

#do_push(opts) ⇒ Object

Push values onto the right end of the array.



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/ltdtemplate/proxy/array.rb', line 207

def do_push (opts)
	if params = opts[:parameters]
 case @original
 when ::Array
		@template.use :array_growth, params.size(:seq)
		@original.push *params.values(:seq)
 when Sarah
		# Assume worst-case growth, then "push"
		@template.use :array_growth, params.size
		adjust = @original.size + params.size
		@original.append! params

		# Adjust actual growth if needed
		adjust = @original.size - adjust
		@template.use :array_growth, adjust if adjust < 0
 end
 @template.using :array_size, @original.size
	end
	nil
end

#do_shift(opts) ⇒ Object

Shift a value off the left end of the array.



229
230
231
232
233
234
235
# File 'lib/ltdtemplate/proxy/array.rb', line 229

def do_shift (opts)
	if @original.respond_to? :shift
 @template.use :array_growth, -1
 @original.shift
	else nil
	end
end

#do_unshift(opts) ⇒ Object

Unshift values onto the left end of the array.



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/ltdtemplate/proxy/array.rb', line 238

def do_unshift (opts)
	if params = opts[:parameters]
 case @original
 when ::Array
		@template.use :array_growth, params.size(:seq)
		@original.unshift *params.values(:seq)
 when Sarah
		@template.use :array_growth, params.size
		adjust = @original.size + params.size
		@original.insert! params
		adjust = @original.size - adjust
		@template.use :array_growth, adjust if adjust < 0
 end
 @template.using :array_size, @original.size
	end
	nil
end

#evaluate(opts = {}) ⇒ Object

Evaluate supported array methods.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ltdtemplate/proxy/array.rb', line 27

def evaluate (opts = {})
	# Methods supported for all proxied types.
	case opts[:method]
	when nil, 'call' then return @original
	when 'class' then return 'Array'
	when 'each', 'each_rnd', 'each_seq' then return do_each opts
	when 'rnd_size' then return self.named.size
	when 'seq_size' then return self.positional.size
	when 'size' then return @original.size
	when 'type' then return 'array'
	when '/' 
	  return @template.factory(:array_splat, self.positional,
 self.named.to_a.flatten(1)).tap do |splat|
 size = splat.positional.size + splat.named.size
 # RESOURCE array_growth: Increases in array sizes
 @template.use :array_growth, size
 # RESOURCE array_size: Size of largest modified array
 @template.using :array_size, size
 end
	when '%' 
	  return @template.factory(:array_splat, [],
 self.positional).tap do |splat|
 @template.use :array_growth, splat.named.size
 @template.using :array_size, splat.named.size
 end
	end

	# Methods supported by Array and Sarah objects.
	case @original
	when ::Array, Sarah
 case opts[:method]
 when 'join' then return do_join opts
 when 'pop', '->' then return do_pop opts
 when 'push', '+>' then return do_push opts
 when 'shift', '<-' then return do_shift opts
 when 'unshift', '<+' then return do_unshift opts
 end
	end

	super opts
end

#meter(node, key) ⇒ Object

Meter usage when modifying the array.

Parameters:

  • node (Array, Hash, Sarah)

    The array being updated.

  • key (Object)

    The index/key being added/updated.



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/ltdtemplate/proxy/array.rb', line 73

def meter (node, key)
	case node
	when ::Array
 if key == :[] then growth = 1	# (push)
 elsif key > node.size then growth = key - node.size
 else growth = 0			# existing index
 end
	when Hash, Sarah
 growth = node.has_key?(key) ? 0 : 1
	end
	@template.use :array_growth, growth if growth > 0
	@template.using :array_size, node.size + growth
end

#namedObject

Access named (random-access) parts of the data structure.



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ltdtemplate/proxy/array.rb', line 88

def named
	case @original
	when Hash then @original
	when Sarah
 # RESOURCE array: Total number of arrays created
 @template.use :array
 size = @original.size :nsq
 @template.use :array_growth, size
 @template.using :array_size, size
 @original.to_h :nsq
	else {}
	end
end

#positionalObject

Access positional (sequential) parts of the data structure.



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/ltdtemplate/proxy/array.rb', line 103

def positional
	case @original
	when ::Array then @original
	when Sarah
 @template.use :array
 size = @original.size :seq
 @template.use :array_growth, size
 @template.using :array_size, size
 @original.values :seq
	else []
	end
end

#respond_to?(method) ⇒ Boolean

Reflect original respond_to? :push, etc. for XKeys.

Returns:



117
118
119
120
121
122
# File 'lib/ltdtemplate/proxy/array.rb', line 117

def respond_to? (method)
	case method
	when :[], :[]=, :fetch, :push then @original.respond_to? method
	else super method
	end
end

#tpl_textObject

The template text value is the concatenation of sequential text values.



125
126
127
# File 'lib/ltdtemplate/proxy/array.rb', line 125

def tpl_text
	self.positional.map { |val| rubyversed(val).tpl_text }.join ''
end

#xkeys_new(k2, info, opts) ⇒ Object

Return a new array (Sarah) for auto-vivification.



130
131
132
133
# File 'lib/ltdtemplate/proxy/array.rb', line 130

def xkeys_new (k2, info, opts)
	meter info[:node], info[:key1]
	@template.factory :array
end

#xkeys_on_final(node, key, value) ⇒ Object

Check array growth on final assignment



136
137
138
# File 'lib/ltdtemplate/proxy/array.rb', line 136

def xkeys_on_final (node, key, value)
	meter node, key
end