Module: JSI::Base::ArrayNode

Includes:
Enumerable, 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

Methods included from Enumerable

#to_a

Instance Method Details

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



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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/jsi/base/node.rb', line 208

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



290
291
292
# File 'lib/jsi/base/node.rb', line 290

def as_json(options = {})
  each_index.map { |i| jsi_child(i, as_jsi: true).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



275
276
277
278
279
# File 'lib/jsi/base/node.rb', line 275

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)


180
181
182
# File 'lib/jsi/base/node.rb', line 180

def jsi_array?
  true
end

#jsi_child_token_in_range?(token) ⇒ Boolean

Returns:

  • (Boolean)


192
193
194
# File 'lib/jsi/base/node.rb', line 192

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



185
186
187
188
189
# File 'lib/jsi/base/node.rb', line 185

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



302
303
304
305
306
307
308
# File 'lib/jsi/base/node.rb', line 302

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



197
198
199
200
201
202
203
204
205
# File 'lib/jsi/base/node.rb', line 197

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)


285
286
287
# File 'lib/jsi/base/node.rb', line 285

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