Module: JSI::Base::HashNode

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

Overview

Included on JSI::Base subclasses for instances that are Hash or #to_hash.

Dynamically defines most methods of Hash to make the JSI duck-type like a Hash.

Constant Summary

Constants included from Util::Hashlike

Util::Hashlike::DESTRUCTIVE_METHODS, Util::Hashlike::SAFE_KEY_ONLY_METHODS, Util::Hashlike::SAFE_KEY_VALUE_METHODS, Util::Hashlike::SAFE_METHODS

Instance Method Summary collapse

Methods included from Util::Hashlike

#merge, #pretty_print, #update

Instance Method Details

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

Raises:



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/jsi/base/node.rb', line 53

def [](token, as_jsi: jsi_child_as_jsi_default, use_default: jsi_child_use_default_default)
  raise(BlockGivenError) if block_given?
  token = token.jsi_node_content if token.is_a?(Schema::SchemaAncestorNode)
  if jsi_node_content_hash_pubsend(:key?, token)
    jsi_child(token, as_jsi: as_jsi)
  else
    if use_default
      jsi_default_child(token, as_jsi: as_jsi)
    else
      nil
    end
  end
end

#as_json(options = {}) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/jsi/base/node.rb', line 120

def as_json(options = {})
  hash = {}
  each_key do |k|
    ks = k.is_a?(String) ? k :
      k.is_a?(Symbol) ? k.to_s :
      k.respond_to?(:to_str) && (kstr = k.to_str).is_a?(String) ? kstr :
      raise(TypeError, "JSON object (Hash) cannot be keyed with: #{k.pretty_inspect.chomp}")
    hash[ks] = jsi_child_node(k).as_json(**options)
  end
  hash
end

#each(key_as_jsi: false, **kw) {|Object, Object| ... } ⇒ self, Enumerator Also known as: each_pair

yields each Hash key (JSON object property name) and value of this node.

each yielded key is a key of the instance hash, and each yielded value is the result of JSI::Base#[].

Parameters:

Yields:

  • (Object, Object)

    each key and value of this hash node

Returns:

  • (self, Enumerator)

    an Enumerator if invoked without a block; otherwise self



85
86
87
88
89
90
91
92
93
# File 'lib/jsi/base/node.rb', line 85

def each(key_as_jsi: false, **kw, &block)
  return to_enum(__method__, key_as_jsi: key_as_jsi, **kw) { jsi_node_content_hash_pubsend(:size) } unless block
  if block.arity > 1
    each_key(key_as_jsi: key_as_jsi) { |k| yield(k, self[k, **kw]) }
  else
    each_key(key_as_jsi: key_as_jsi) { |k| yield([k, self[k, **kw]]) }
  end
  self
end

#each_key(key_as_jsi: false) {|String, Base| ... } ⇒ Object

Yields each key (property name)

Parameters:

Yields:



100
101
102
103
104
105
106
107
108
# File 'lib/jsi/base/node.rb', line 100

def each_key(key_as_jsi: false, &block)
  return to_enum(__method__, key_as_jsi: key_as_jsi) { size } unless block
  if key_as_jsi
    jsi_each_propertyName(&block)
  else
    jsi_node_content_hash_pubsend(:each_key, &block)
  end
  self
end

#jsi_as_child_default_as_jsiObject

See JSI::Base#jsi_as_child_default_as_jsi. true for HashNode.



73
74
75
# File 'lib/jsi/base/node.rb', line 73

def jsi_as_child_default_as_jsi
  true
end

#jsi_child_token_present?(token) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/jsi/base/node.rb', line 39

def jsi_child_token_present?(token)
  jsi_node_content_hash_pubsend(:key?, token)
end

#jsi_each_child_token(&block) ⇒ Object

Yields each key - see JSI::Base#jsi_each_child_token



32
33
34
35
36
# File 'lib/jsi/base/node.rb', line 32

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

#jsi_each_propertyName {|JSI::Base| ... } ⇒ nil, Enumerator

instantiates and yields each property name (hash key) as a JSI described by any propertyNames schemas.

Yields:

Returns:

  • (nil, Enumerator)

    an Enumerator if invoked without a block; otherwise nil



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/jsi/base/node.rb', line 13

def jsi_each_propertyName
  return to_enum(__method__) { jsi_node_content_hash_pubsend(:size) } unless block_given?

  property_schemas = jsi_schemas.each_yield_set do |s, y|
    s.dialect_invoke_each(:propertyNames, &y)
  end
  jsi_node_content_hash_pubsend(:each_key) do |key|
    yield property_schemas.new_jsi(key)
  end

  nil
end

#jsi_hash?Boolean

See JSI::Base#jsi_hash?. Always true for HashNode.

Returns:

  • (Boolean)


27
28
29
# File 'lib/jsi/base/node.rb', line 27

def jsi_hash?
  true
end

#jsi_node_content_child(token) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/jsi/base/node.rb', line 44

def jsi_node_content_child(token)
  # I could check token_present? and return nil here (as ArrayNode does).
  # without that check, if the instance defines Hash#default or #default_proc, that result is returned.
  # the preferred mechanism for a JSI's default value should be its schema.
  # but there's no compelling reason not to support both, so I'll return what #[] returns.
  jsi_node_content_hash_pubsend(:[], token)
end

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

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

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_hash



140
141
142
143
144
145
146
# File 'lib/jsi/base/node.rb', line 140

def jsi_node_content_hash_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_hash.public_send(method_name, *a, &b)
  end
end

#store(key, value) ⇒ Object



68
69
70
# File 'lib/jsi/base/node.rb', line 68

def store(key, value)
  self[key] = value
end

#to_hash(**kw) ⇒ Hash

a hash in which each key is a key of the instance hash and each value is the result of JSI::Base#[]

Parameters:

Returns:

  • (Hash)


113
114
115
116
117
# File 'lib/jsi/base/node.rb', line 113

def to_hash(**kw)
  hash = {}
  each_key { |k| hash[k] = self[k, **kw] }
  hash.freeze
end