Class: Liquid2::LoopExpression

Inherits:
Expression show all
Defined in:
lib/liquid2/expressions/loop.rb

Overview

An expression used by the standard for and tablerow tags.

Constant Summary collapse

EMPTY_ENUM =

steep:ignore

[].freeze

Instance Attribute Summary collapse

Attributes inherited from Expression

#token

Instance Method Summary collapse

Methods inherited from Expression

#scope

Constructor Details

#initialize(token, identifier, enum, limit: nil, offset: nil, reversed: false, cols: nil) ⇒ LoopExpression

Returns a new instance of LoopExpression.



12
13
14
15
16
17
18
19
20
21
# File 'lib/liquid2/expressions/loop.rb', line 12

def initialize(token, identifier, enum, limit: nil, offset: nil, reversed: false, cols: nil)
  super(token)
  @identifier = identifier
  @enum = enum
  @limit = limit
  @offset = offset
  @reversed = reversed
  @cols = cols
  @name = "#{@identifier.name}-#{@enum}"
end

Instance Attribute Details

#colsObject (readonly)

Returns the value of attribute cols.



8
9
10
# File 'lib/liquid2/expressions/loop.rb', line 8

def cols
  @cols
end

#enumObject (readonly)

Returns the value of attribute enum.



8
9
10
# File 'lib/liquid2/expressions/loop.rb', line 8

def enum
  @enum
end

#identifierObject (readonly)

Returns the value of attribute identifier.



8
9
10
# File 'lib/liquid2/expressions/loop.rb', line 8

def identifier
  @identifier
end

#limitObject (readonly)

Returns the value of attribute limit.



8
9
10
# File 'lib/liquid2/expressions/loop.rb', line 8

def limit
  @limit
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/liquid2/expressions/loop.rb', line 8

def name
  @name
end

#offsetObject (readonly)

Returns the value of attribute offset.



8
9
10
# File 'lib/liquid2/expressions/loop.rb', line 8

def offset
  @offset
end

#reversedObject (readonly)

Returns the value of attribute reversed.



8
9
10
# File 'lib/liquid2/expressions/loop.rb', line 8

def reversed
  @reversed
end

Instance Method Details

#childrenObject



73
74
75
76
77
78
79
# File 'lib/liquid2/expressions/loop.rb', line 73

def children
  expressions = [@enum]
  expressions << @limit if @limit
  expressions << @offset if @offset
  expressions << @cols if @cols
  expressions
end

#evaluate(context) ⇒ Array[untyped]

Returns:

  • (Array[untyped])


24
25
26
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
68
69
70
71
# File 'lib/liquid2/expressions/loop.rb', line 24

def evaluate(context)
  obj = context.evaluate(@enum)

  # @type var array: Array[untyped]
  array = if obj.is_a?(Array)
            obj
          elsif obj.is_a?(Hash) || obj.is_a?(Range)
            # TODO: special big range slicing
            obj.to_a
          elsif obj.is_a?(String)
            # TODO: optionally enable/disable string iteration
            obj.each_char.to_a
          elsif obj.respond_to?(:slice)
            # Special lazy drop slicing
            return obj.slice(context.evaluate(@offset),
                             context.evaluate(@limit),
                             @reversed) || EMPTY_ENUM
          elsif obj.is_a?(Enumerable) # rubocop:disable Lint/DuplicateBranch
            obj.to_a
          else
            EMPTY_ENUM
          end

  length = array.length

  # No slicing required
  if @offset.nil? && @limit.nil?
    context.stop_index(@name, index: length)
    return @reversed ? array.reverse : array
  end

  start = if @offset
            offset = context.evaluate(@offset)
            if offset == "continue"
              context.stop_index(@name)
            else
              Liquid2.to_i(offset)
            end
          else
            0
          end

  stop = @limit ? Liquid2.to_i(context.evaluate(@limit)) + start : length
  context.stop_index(@name, index: stop)

  array = (stop ? array.slice(start...stop) : array.slice(start..)) || EMPTY_ENUM # steep:ignore
  @reversed ? array.reverse! : array
end