Class: Arrow::Template::Iterator
- Inherits:
-
Arrow::Object
- Object
- Arrow::Object
- Arrow::Template::Iterator
- Includes:
- Enumerable
- Defined in:
- lib/arrow/template/iterator.rb
Overview
The Arrow::Template::Iterator class, instances of which can be used to provide an iteration context to nodes in an Arrow template.
Lots of the ideas for this class were stolen/influenced in no small way by Hal Fulton’s “super-iterator” post to the Ruby-talk ML [ruby-talk: 46337].
Examples
### Render the directive's bracketed nodes once for each item in the ### iterated content. def render_subnodes( attribute, template, scope ) res = [] iterator = Arrow::Template::Iterator.new( attribute ) iterator.each {|iter,*blockArgs| # Process the nodes template.with_overridden_attributes( scope, 'iterator' => iter ) {|template| res << template.render( @subnodes, scope ) } } return *res end
Authors
Michael Granger
Please see the file LICENSE in the top-level directory for licensing details.
Instance Attribute Summary
-
- (Object) items
The list of items in this iteration.
-
- (Object) iteration
The index of the current iteration.
-
- (Object) lastItem
readonly
The item previous to the currently iterated one.
-
- (Object) nextItem
readonly
The item which succeeds the currently iterated one.
Instance Method Summary
-
- (Object) break
Cause iteration to immediately terminate, ala the ‘break’ keyword.
-
- (Object) each
The primary iteration interface.
-
- (Boolean) even?
Return true if the current iteration is an even-numbered iteration.
-
- (Object) even_or_odd
Returns either “even” if the iteration is in even-numbered iteration, or “odd”.
-
- (Boolean) first?
Returns true if the current iteration is the first one.
-
- (Iterator) initialize(*items)
constructor
Create a new Arrow::Template::Iterator object for the given items.
-
- (Boolean) last?
Returns true if the current iteration is the last one.
-
- (Boolean) odd?
Returns true if the current iteration is an odd-numbered iteration.
-
- (Object) redo
Redo the current iteration.
-
- (Object) restart
Cause iteration to begin over again.
-
- (Object) skip(n = 1)
Cause the next n items to be skipped.
-
- (Boolean) skipped?
Returns true if the last iteration skipped one or more items.
Methods inherited from Arrow::Object
deprecate_class_method, deprecate_method, inherited
Methods included from Arrow::Loggable
Constructor Details
- (Iterator) initialize(*items)
Create a new Arrow::Template::Iterator object for the given items.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/arrow/template/iterator.rb', line 48 def initialize( *items ) if items.length == 1 && items[0].is_a?( Enumerable ) @items = items[0] else @items = items end @iteration = nil @lastItem = nil @item = nil @nextItem = nil = false @skipped = false @marker = nil end |
Instance Attribute Details
- (Object) items
The list of items in this iteration
70 71 72 |
# File 'lib/arrow/template/iterator.rb', line 70 def items @items end |
- (Object) iteration
The index of the current iteration
73 74 75 |
# File 'lib/arrow/template/iterator.rb', line 73 def iteration @iteration end |
- (Object) lastItem (readonly)
The item previous to the currently iterated one. If this is the first iteration, this will be nil.
77 78 79 |
# File 'lib/arrow/template/iterator.rb', line 77 def lastItem @lastItem end |
- (Object) nextItem (readonly)
The item which succeeds the currently iterated one. If this is the last iteration, this will be nil.
81 82 83 |
# File 'lib/arrow/template/iterator.rb', line 81 def nextItem @nextItem end |
Instance Method Details
- (Object) break
Cause iteration to immediately terminate, ala the ‘break’ keyword
155 156 157 158 |
# File 'lib/arrow/template/iterator.rb', line 155 def break # Jump back into the outer loop of #each throw( :break ) if end |
- (Object) each
The primary iteration interface.
85 86 87 88 89 90 91 92 93 94 95 96 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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/arrow/template/iterator.rb', line 85 def each items = @items.dup @items = @items.entries raise LocalJumpError, "no block given" unless block_given? #self.log.debug "Iterating over @items = %p" % [ @items ] # Save this point so #restart can jump back here later. This is in a # loop because it needs to be remade after it's used the first time. until @marker @marker = callcc {|cc| cc} end = true @iteration = 0 # Mark the outer loop for #break catch( :break ) { until @iteration >= @items.length # Catch a skip with the number of items to skip. Unskipped # iterations "skip" 0 items. n = catch( :skip ) { @lastItem = self.first? ? nil : @items[ @iteration - 1 ] @item = @items[ @iteration ] @nextItem = self.last? ? nil : @items[ @iteration + 1 ] if @item.is_a?( Array ) yield( self, *@item ) else yield( self, @item ) end 0 } # Set the skipped flag for next iteration if we're skipping @skipped = n.nonzero? @iteration += n + 1 end } #self.log.debug "Returning from Iterator#each" return @items ensure @items = items @iteration = nil @lastItem = nil @item = nil @nextItem = nil = false @skipped = false @marker = nil end |
- (Boolean) even?
Return true if the current iteration is an even-numbered iteration.
196 197 198 |
# File 'lib/arrow/template/iterator.rb', line 196 def even? return !self.odd? end |
- (Object) even_or_odd
Returns either “even” if the iteration is in even-numbered iteration, or “odd”.
182 183 184 |
# File 'lib/arrow/template/iterator.rb', line 182 def even_or_odd return self.odd? ? "odd" : "even" end |
- (Boolean) first?
Returns true if the current iteration is the first one.
176 177 178 |
# File 'lib/arrow/template/iterator.rb', line 176 def first? return @iteration == 0 end |
- (Boolean) last?
Returns true if the current iteration is the last one.
202 203 204 |
# File 'lib/arrow/template/iterator.rb', line 202 def last? return @iteration == @items.length - 1 end |
- (Boolean) odd?
Returns true if the current iteration is an odd-numbered iteration.
189 190 191 |
# File 'lib/arrow/template/iterator.rb', line 189 def odd? return && ( @iteration % 2 ).nonzero? end |
- (Object) redo
Redo the current iteration
149 150 151 |
# File 'lib/arrow/template/iterator.rb', line 149 def redo throw( :skip, -1 ) if end |
- (Object) restart
Cause iteration to begin over again
162 163 164 165 166 |
# File 'lib/arrow/template/iterator.rb', line 162 def restart # Call back into the continuation that was saved at the beginning of # #each @marker.call if end |
- (Object) skip(n = 1)
Cause the next n items to be skipped
142 143 144 145 |
# File 'lib/arrow/template/iterator.rb', line 142 def skip( n=1 ) # Jump back into #each with the number of iterations to skip throw( :skip, n ) if end |
- (Boolean) skipped?
Returns true if the last iteration skipped one or more items.
170 171 172 |
# File 'lib/arrow/template/iterator.rb', line 170 def skipped? @skipped end |