Class: Markbridge::Parsers::BBCode::PeekableEnumerator
- Inherits:
-
Object
- Object
- Markbridge::Parsers::BBCode::PeekableEnumerator
- Defined in:
- lib/markbridge/parsers/bbcode/peekable_enumerator.rb
Overview
Wrapper around a scanner that allows peeking at upcoming tokens without consuming them.
This class buffers tokens pulled from a scanner (which must implement ‘next_token`) so callers can:
-
inspect the next token with #peek without advancing the scanner
-
inspect several upcoming tokens with #peek_ahead
-
consume tokens with #next
The enumerator is lazy: tokens are only requested from the scanner when needed. Once the underlying scanner returns ‘nil`, the enumerator is marked finished and further peeks return `nil` (for single peeks) or an empty array (for multi-peeks).
Instance Method Summary collapse
-
#has_next? ⇒ Boolean
Return whether more tokens are available.
-
#initialize(scanner) ⇒ PeekableEnumerator
constructor
Initialize a new PeekableEnumerator.
-
#next ⇒ Object?
(also: #next_token)
Consume and return the next token.
-
#peek ⇒ Object?
Peek at the next single token without consuming it.
-
#peek_ahead(count) ⇒ Array<Object>
Peek ahead at up to ‘count` upcoming tokens without consuming them.
Constructor Details
#initialize(scanner) ⇒ PeekableEnumerator
Initialize a new PeekableEnumerator.
32 33 34 35 36 |
# File 'lib/markbridge/parsers/bbcode/peekable_enumerator.rb', line 32 def initialize(scanner) @scanner = scanner @peeked = [] @finished = false end |
Instance Method Details
#has_next? ⇒ Boolean
Return whether more tokens are available.
This will attempt to fetch one token from the scanner if necessary to determine whether more tokens remain.
60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/markbridge/parsers/bbcode/peekable_enumerator.rb', line 60 def has_next? return true if @peeked.any? return false if @finished value = @scanner.next_token if value.nil? @finished = true false else @peeked << value true end end |
#next ⇒ Object? Also known as: next_token
Consume and return the next token.
If there are tokens in the internal buffer (from prior peeks) the buffered token is returned. Otherwise, the next token is requested from the underlying scanner via ‘next_token`.
45 46 47 48 49 50 51 52 |
# File 'lib/markbridge/parsers/bbcode/peekable_enumerator.rb', line 45 def next return @peeked.shift if @peeked.any? return nil if @finished value = @scanner.next_token @finished = true if value.nil? value end |
#peek ⇒ Object?
Peek at the next single token without consuming it.
If the enumerator has been exhausted this returns ‘nil`.
79 80 81 82 83 84 85 |
# File 'lib/markbridge/parsers/bbcode/peekable_enumerator.rb', line 79 def peek return @peeked.first if @peeked.any? return nil if @finished ensure_peeked(1) @peeked.first end |
#peek_ahead(count) ⇒ Array<Object>
Peek ahead at up to ‘count` upcoming tokens without consuming them.
The method will return an array with at most ‘count` elements. If fewer tokens remain, a shorter array is returned. When the enumerator is exhausted an empty array is returned.
95 96 97 98 99 100 |
# File 'lib/markbridge/parsers/bbcode/peekable_enumerator.rb', line 95 def peek_ahead(count) return [] if count <= 0 ensure_peeked(count) @peeked.take(count) end |