Class: Hash

Inherits:
Object show all
Defined in:
runtime/ext/hash.rb,
runtime/ext/hash.rbs

Overview

Hash — the key transforms and the query-string renderer.

Each transform builds a NEW hash; the receiver is untouched.

Constant Summary collapse

QUERY_ESCAPES =

Percent-encoding table for one query-string component: space renders as +, A-Za-z0-9.-_~ pass through, and the rest percent-encodes.

Table and pattern: Hash#to_query runs each value through CGI.escape, which keeps only A-Za-z0-9.-_~, renders space as + (not %20), and percent-encodes the rest.

ASCII-only on purpose: a UTF-8 value would need a per-byte walk the lookup-table substitution cannot express, so it passes through unencoded — a caller feeding one must encode it before the call.

{
  " " => "+",   "!" => "%21", "\"" => "%22", "#" => "%23",
  "$" => "%24", "%" => "%25", "&" => "%26", "'" => "%27",
  "(" => "%28", ")" => "%29", "*" => "%2A", "+" => "%2B",
  "," => "%2C", "/" => "%2F", ":" => "%3A", ";" => "%3B",
  "<" => "%3C", "=" => "%3D", ">" => "%3E", "?" => "%3F",
  "@" => "%40", "[" => "%5B", "\\" => "%5C", "]" => "%5D",
  "^" => "%5E", "`" => "%60", "{" => "%7B", "|" => "%7C",
  "}" => "%7D",
}.freeze
QUERY_ESCAPE_PATTERN =
/[ !"\#$%&'()*+,\/:;<=>?@\[\\\]^`{|}]/.freeze

Instance Method Summary collapse

Instance Method Details

#deep_transform_keys(&block) ⇒ Hash

a new Hash with the block applied to every key at every depth; Arrays are walked element-wise and non-collection values pass through. The receiver is untouched.

Examples:

{ "host_info" => { "os_name" => "ios" } }
  .deep_transform_keys { |key| key.to_s.camelize(:lower) }
# => { "hostInfo" => { "osName" => "ios" } }

Returns:

  • (Hash) —

    a new Hash with the transformed keys



49
# File 'runtime/ext/hash.rb', line 49

def deep_transform_keys: () { (untyped key) -> untyped } -> Hash[untyped, untyped]

#deep_transform_keys!(&block) ⇒ Hash

the same transform. Typed hashes cannot widen in place in this runtime, so the answer is a NEW Hash and the receiver keeps its old keys: callers must use the return value (the bang name mirrors the non-bang method; the value is the contract).

Examples:

{ "host_info" => 1 }.deep_transform_keys! { |key| key.to_s.camelize(:lower) }
# => { "hostInfo" => 1 }

Returns:

  • (Hash) —

    a new Hash with the transformed keys



62
# File 'runtime/ext/hash.rb', line 62

def deep_transform_keys!: () { (untyped key) -> untyped } -> Hash[untyped, untyped]

#stringify_keys ⇒ Hash[String, untyped]

Returns:



3
# File 'runtime/ext/hash.rbs', line 3

def stringify_keys: () -> Hash[String, untyped]

#symbolize_keys ⇒ Hash[Symbol, untyped]

Returns:

  • (Hash[Symbol, untyped])


2
# File 'runtime/ext/hash.rbs', line 2

def symbolize_keys: () -> Hash[Symbol, untyped]

#to_query(namespace = nil) ⇒ String

the query string rendered for key: value options: a scalar becomes key=value, a nil value renders its key alone, a nested Hash becomes outer[inner], and a scalar Array repeats key[]. Pairs sort at each level.

Not modeled, and loud when reached: an Array carrying a Hash or an Array element, and a top-level Array (Array#to_query). A non-ASCII value passes through unencoded — see QUERY_ESCAPES.

Examples:

{ name: "David", page: 2 }.to_query  # => "name=David&page=2"
{ user: { name: "David" } }.to_query("user")
# => "user%5Bname%5D=David"

Parameters:

  • namespace (String, nil) (defaults to: nil) —

    the enclosing key for a nested Hash

Returns:

  • (String) —

    the &-joined query string

Raises:

  • (ArgumentError) —

    an Array element is a Hash or an Array



82
# File 'runtime/ext/hash.rb', line 82

def to_query: (?String? namespace) -> String