Module: JSI::Util::Private Private

Extended by:
Private
Included in:
JSI::Util, Private
Defined in:
lib/jsi/util/private.rb,
lib/jsi/util/private/memo_map.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

JSI::Util::Private classes, modules, constants, and methods are internal, and will be added and removed without warning.

Defined Under Namespace

Modules: FingerprintHash Classes: MemoMap

Constant Summary collapse

EMPTY_ARY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

[].freeze
EMPTY_HASH =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

{}.freeze
EMPTY_SET =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Set[].freeze
CLASSES_ALWAYS_FROZEN =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Set[TrueClass, FalseClass, NilClass, Integer, Float, BigDecimal, Rational, Symbol].freeze
LAST_ARGUMENT_AS_KEYWORD_PARAMETERS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

is a hash as the last argument passed to keyword params? (false in ruby 3; true before - generates a warning in 2.7 but no way to make 2.7 behave like 3 so the warning is useless)

TODO remove eventually (keyword argument compatibility)

begin
  if Object.const_defined?(:Warning)
    warn = ::Warning.instance_method(:warn)
    ::Warning.send(:remove_method, :warn)
    ::Warning.send(:define_method, :warn) { |*, **| }
  end

  -> (k: ) { k }[{k: nil}]
  true
rescue ArgumentError
  false
ensure
  if Object.const_defined?(:Warning)
    ::Warning.send(:remove_method, :warn)
    ::Warning.send(:define_method, :warn, warn)
  end
end
USE_TO_JSON_METHOD =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

we won't use #to_json on classes where it is defined by JSON::Ext::Generator::GeneratorMethods / JSON::Pure::Generator::GeneratorMethods this is a bit of a kluge and disregards any singleton class to_json, but it will do.

Hash.new do |h, klass|
  h[klass] = klass.method_defined?(:to_json) &&
    klass.instance_method(:to_json).owner.name !~ /\AJSON:.*:GeneratorMethods\b/
end
RUBY_REJECT_NAME_CODEPOINTS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

[
  0..31, # C0 control chars
  %q( !"#$%&'()*+,-./:;<=>?@[\\]^`{|}~).each_codepoint, # printable special chars (note: "_" not included)
  127..159, # C1 control chars
].inject(Set[], &:merge).freeze
RUBY_REJECT_NAME_RE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Regexp.new('[' + Regexp.escape(RUBY_REJECT_NAME_CODEPOINTS.to_a.pack('U*')) + ']+').freeze

Instance Method Summary collapse

Instance Method Details

#add_visited_ref(visited_refs, ref) ⇒ Array<Schema::Ref>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters:

Returns:



180
181
182
183
184
185
186
187
# File 'lib/jsi/util/private.rb', line 180

def add_visited_ref(visited_refs, ref)
  return(visited_refs) if ref.nil?
  #chkbug fail unless ref.is_a?(Schema::Ref) && visited_refs.is_a?(Array) && visited_refs.frozen?
  if visited_refs.include?(ref)
    raise(ResolutionError, "cyclical ref application with refs: #{visited_refs}")
  end
  visited_refs.dup.push(ref).freeze
end

#const_name_from_parts(parts, join: '') ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/jsi/util/private.rb', line 70

def const_name_from_parts(parts, join: '')
  initAZ = false
  parts = parts.map do |part|
    part = part.to_str.dup
    if !initAZ
      part[/\A[^a-zA-Z]*/] = ''
    end
    if part[0]
      part[0] = part[0].upcase
      initAZ = true
    end
    part.gsub!(RUBY_REJECT_NAME_RE, '_')
    part
  end
  if !parts.all?(&:empty?)
    parts.reject(&:empty?).join(join).freeze
  else
    nil
  end
end

#json_parse_freeze(json) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



92
93
94
# File 'lib/jsi/util/private.rb', line 92

def json_parse_freeze(json)
  JSON.parse(json, freeze: true)
end

#ok_ruby_method_name?(name) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

is the given name ok to use as a ruby method name?

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
67
68
# File 'lib/jsi/util/private.rb', line 59

def ok_ruby_method_name?(name)
  # must be a string
  return false unless name.respond_to?(:to_str)
  # must not begin with a digit
  return false if name =~ /\A[0-9]/
  # must not contain special or control characters
  return false if name =~ RUBY_REJECT_NAME_RE

  return true
end

#require_jmespathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/jsi/util/private.rb', line 150

def require_jmespath
  return if instance_variable_defined?(:@jmespath_required)
  begin
    require 'jmespath'
  rescue ::LoadError => e
    # :nocov:
    msg = [
      "please install and/or add to your Gemfile the `jmespath` gem to use this. jmespath is not a dependency of JSI.",
      "original error message:",
      e.message,
    ].join("\n")
    raise(e.class, msg, e.backtrace)
    # :nocov:
  end
  hashlike = JSI::SchemaSet[].new_jsi({'test' => 0})
  unless JMESPath.search('test', hashlike) == 0
    # :nocov:
    raise(::LoadError, [
      "the loaded version of jmespath cannot be used with JSI.",
      "jmespath is compatible with JSI objects as of version 1.5.0",
    ].join("\n"))
    # :nocov:
  end
  @jmespath_required = true
  nil
end

#uri(uri, nnil: false, yabs: false, ynorm: false, tonorm: false) ⇒ URI?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

string or URI → frozen URI

Parameters:

  • nnil (defaults to: false)

    must not be nil

  • yabs (defaults to: false)

    must be absolute

  • ynorm (defaults to: false)

    must be normalized

  • tonorm (defaults to: false)

    normalize returned URI

Returns:

  • (URI, nil)


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/jsi/util/private.rb', line 107

def uri(uri, nnil: false, yabs: false, ynorm: false, tonorm: false)
  return nil if !nnil && uri.nil?
  if uri.is_a?(URI)
    auri = uri
  elsif uri.is_a?(String) || uri.respond_to?(:to_str)
    auri = URI.parse(uri)
  else
    raise(URIError, "URI is not a string: #{uri.inspect}")
  end
  if yabs && !auri.scheme
    raise(URIError, "URI must be an absolute URI. got: #{uri.inspect}")
  end
  if yabs && auri.fragment
    if auri.fragment.empty?
      auri = auri.merge(fragment: nil)
    else
      raise(URIError, "URI must have no fragment. got: #{uri.inspect}")
    end
  end
  if ynorm && uri.to_str != auri.normalize.to_s
    raise(URIError, "URI must be in normalized form. got: #{uri.inspect}; normalized: #{auri.normalize.to_s.inspect}")
  end
  auri = auri.normalize if tonorm
  auri
end

#ycombObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

this is the Y-combinator, which allows anonymous recursive functions. for a simple example, to define a recursive function to return the length of an array:

length = ycomb do |len|
  proc { |list| list == [] ? 0 : 1 + len.call(list[1..-1]) }
end

length.call([0])
# => 1

see https://en.wikipedia.org/wiki/Fixed-point_combinator#Y_combinator and chapter 9 of the little schemer, available as the sample chapter at https://felleisen.org/matthias/BTLS-index.html



146
147
148
# File 'lib/jsi/util/private.rb', line 146

def ycomb
  proc { |f| f.call(f) }.call(proc { |f| yield proc { |*x| f.call(f).call(*x) } })
end