Module: JSI::Base::ArrayNode

Includes:
Util::Arraylike
Defined in:
lib/jsi/base/node.rb

Overview

module extending a JSI::Base object when its instance (its #jsi_node_content) is an Array (or responds to #to_ary)

Constant Summary

Constants included from Util::Arraylike

Util::Arraylike::DESTRUCTIVE_METHODS, Util::Arraylike::SAFE_INDEX_ELEMENT_METHODS, Util::Arraylike::SAFE_INDEX_ONLY_METHODS, Util::Arraylike::SAFE_METHODS

Instance Method Summary collapse

Methods included from Util::Arraylike

#assoc, #inspect, #pretty_print, #rassoc, #to_s

Instance Method Details

#[](token, as_jsi: jsi_child_as_jsi_default, use_default: jsi_child_use_default_default) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/jsi/base/node.rb', line 183

def [](token, as_jsi: jsi_child_as_jsi_default, use_default: jsi_child_use_default_default)
  size = jsi_node_content_ary_pubsend(:size)
  if token.is_a?(Integer)
    if token < 0
      if token < -size
        nil
      else
        jsi_child(token + size, as_jsi: as_jsi)
      end
    else
      if token < size
        jsi_child(token, as_jsi: as_jsi)
      else
        if use_default
          jsi_default_child(token, as_jsi: as_jsi)
        else
          nil
        end
      end
    end
  elsif token.is_a?(Range)
    type_err = proc do
      raise(TypeError, [
        "given range does not contain Integers",
        "range: #{token.inspect}",
      ].join("\n"))
    end

    start_idx = token.begin
    if start_idx.is_a?(Integer)
      start_idx += size if start_idx < 0
      return Util::EMPTY_ARY if start_idx == size
      return nil if start_idx < 0 || start_idx > size
    elsif start_idx.nil?
      start_idx = 0
    else
      type_err.call
    end

    end_idx = token.end
    if end_idx.is_a?(Integer)
      end_idx += size if end_idx < 0
      end_idx += 1 unless token.exclude_end?
      end_idx = size if end_idx > size
      return Util::EMPTY_ARY if start_idx >= end_idx
    elsif end_idx.nil?
      end_idx = size
    else
      type_err.call
    end

    (start_idx...end_idx).map { |i| jsi_child(i, as_jsi: as_jsi) }.freeze
  else
    raise(TypeError, [
      "expected `token` param to be an Integer or Range",
      "token: #{token.inspect}",
    ].join("\n"))
  end
end

#as_json(options = {}) ⇒ Object



265
266
267
# File 'lib/jsi/base/node.rb', line 265

def as_json(options = {})
  each_index.map { |i| jsi_child_node(i).as_json(**options) }
end

#each(**kw) {|Object| ... } ⇒ self, Enumerator

yields each array element of this node.

each yielded element is the result of JSI::Base#[] for each index of the instance array.

Parameters:

Yields:

  • (Object)

    each element of this array node

Returns:

  • (self, Enumerator)

    an Enumerator if invoked without a block; otherwise self



250
251
252
253
254
# File 'lib/jsi/base/node.rb', line 250

def each(**kw, &block)
  return to_enum(__method__, **kw) { jsi_node_content_ary_pubsend(:size) } unless block
  jsi_node_content_ary_pubsend(:each_index) { |i| yield(self[i, **kw]) }
  self
end

#jsi_array?Boolean

See JSI::Base#jsi_array?. Always true for ArrayNode.

Returns:

  • (Boolean)


155
156
157
# File 'lib/jsi/base/node.rb', line 155

def jsi_array?
  true
end

#jsi_child_token_in_range?(token) ⇒ Boolean

Returns:

  • (Boolean)


167
168
169
# File 'lib/jsi/base/node.rb', line 167

def jsi_child_token_in_range?(token)
  token.is_a?(Integer) && token >= 0 && token < jsi_node_content_ary_pubsend(:size)
end

#jsi_each_child_token(&block) ⇒ Object

Yields each index - see JSI::Base#jsi_each_child_token



160
161
162
163
164
# File 'lib/jsi/base/node.rb', line 160

def jsi_each_child_token(&block)
  return to_enum(__method__) { jsi_node_content_ary_pubsend(:size) } unless block
  jsi_node_content_ary_pubsend(:each_index, &block)
  nil
end

#jsi_node_content_ary_pubsend(method_name, *a, **kw, &b) ⇒ Object

invokes the method with the given name on the jsi_node_content (if defined) or its #to_ary

Parameters:

  • method_name (String, Symbol)
  • a

    positional arguments are passed to the invocation of method_name

  • kw

    keyword arguments are passed to the invocation of method_name

  • b

    block is passed to the invocation of method_name

Returns:

  • (Object)

    the result of calling method method_name on the jsi_node_content or its #to_ary



277
278
279
280
281
282
283
# File 'lib/jsi/base/node.rb', line 277

def jsi_node_content_ary_pubsend(method_name, *a, &b)
  if jsi_node_content.respond_to?(method_name)
    jsi_node_content.public_send(method_name, *a, &b)
  else
    jsi_node_content.to_ary.public_send(method_name, *a, &b)
  end
end

#jsi_node_content_child(token) ⇒ Object



172
173
174
175
176
177
178
179
180
# File 'lib/jsi/base/node.rb', line 172

def jsi_node_content_child(token)
  # we check token_in_range? here (unlike HashNode) because we do not want to pass
  # negative indices, Ranges, or non-Integers to Array#[]
  if jsi_child_token_in_range?(token)
    jsi_node_content_ary_pubsend(:[], token)
  else
    nil
  end
end

#to_ary(**kw) ⇒ Array

an array, the same size as the instance array, in which the element at each index is the result of JSI::Base#[].

Parameters:

Returns:

  • (Array)


260
261
262
# File 'lib/jsi/base/node.rb', line 260

def to_ary(**kw)
  to_a(**kw)
end