Methods
A
D
E
F
N
R
S
T
W
Class Public methods
from_trusted_xml(xml)

Builds a Hash from XML just like Hash.from_xml, but also allows Symbol and YAML.

# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 112
def from_trusted_xml(xml)
  from_xml xml, []
end
from_xml(xml, disallowed_types = nil)

Returns a Hash containing a collection of pairs when the key is the node name and the value is its content

xml = <<-XML
  <?xml version="1.0" encoding="UTF-8"?>
    <hash>
      <foo type="integer">1</foo>
      <bar type="integer">2</bar>
    </hash>
XML

hash = Hash.from_xml(xml)
# => {"hash"=>{"foo"=>1, "bar"=>2}}

DisallowedType is raise if the XML contains attributes with type="yaml" or type="symbol". Use Hash.from_trusted_xml to parse this XML.

# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 107
def from_xml(xml, disallowed_types = nil)
  ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
end
Instance Public methods
assert_valid_keys(*valid_keys)

Validate all keys in a hash match *valid_keys, raising ArgumentError on a mismatch. Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols as keys, this will fail.

{ name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
{ name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
{ name: 'Rob', age: '28' }.assert_valid_keys(:name, :age)   # => passes, raises nothing
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 67
def assert_valid_keys(*valid_keys)
  valid_keys.flatten!
  each_key do |k|
    raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k)
  end
end
deep_dup()

Returns a deep copy of hash.

hash = { a: { b: 'b' } }
dup  = hash.deep_dup
dup[:a][:c] = 'c'

hash[:a][:c] #=> nil
dup[:a][:c]  #=> "c"
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 41
def deep_dup
  each_with_object(dup) do |(key, value), hash|
    hash[key.deep_dup] = value.deep_dup
  end
end
deep_merge(other_hash, &block)

Returns a new hash with self and other_hash merged recursively.

h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
h2 = { x: { y: [7,8,9] }, z: 'xyz' }

h1.deep_merge(h2) #=> {x: {y: [7, 8, 9]}, z: "xyz"}
h2.deep_merge(h1) #=> {x: {y: [4, 5, 6]}, z: [7, 8, 9]}
h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) }
#=> {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
# File activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 11
def deep_merge(other_hash, &block)
  dup.deep_merge!(other_hash, &block)
end
deep_merge!(other_hash, &block)

Same as deep_merge, but modifies self.

# File activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 16
def deep_merge!(other_hash, &block)
  other_hash.each_pair do |k,v|
    tv = self[k]
    if tv.is_a?(Hash) && v.is_a?(Hash)
      self[k] = tv.deep_merge(v, &block)
    else
      self[k] = block && tv ? block.call(k, tv, v) : v
    end
  end
  self
end
deep_stringify_keys()

Return a new hash with all keys converted to strings. This includes the keys from the root hash and from all nested hashes.

hash = { person: { name: 'Rob', age: '28' } }

hash.deep_stringify_keys
# => { "person" => { "name" => "Rob", "age" => "28" } }
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 109
def deep_stringify_keys
  deep_transform_keys{ |key| key.to_s }
end
deep_stringify_keys!()

Destructively convert all keys to strings. This includes the keys from the root hash and from all nested hashes.

# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 116
def deep_stringify_keys!
  deep_transform_keys!{ |key| key.to_s }
end
deep_symbolize_keys()

Return a new hash with all keys converted to symbols, as long as they respond to to_sym. This includes the keys from the root hash and from all nested hashes.

hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }

hash.deep_symbolize_keys
# => { person: { name: "Rob", age: "28" } }
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 128
def deep_symbolize_keys
  deep_transform_keys{ |key| key.to_sym rescue key }
end
deep_symbolize_keys!()

Destructively convert all keys to symbols, as long as they respond to to_sym. This includes the keys from the root hash and from all nested hashes.

# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 135
def deep_symbolize_keys!
  deep_transform_keys!{ |key| key.to_sym rescue key }
end
deep_transform_keys(&block)

Return a new hash with all keys converted by the block operation. This includes the keys from the root hash and from all nested hashes.

hash = { person: { name: 'Rob', age: '28' } }

hash.deep_transform_keys{ |key| key.to_s.upcase }
# => { "PERSON" => { "NAME" => "Rob", "AGE" => "28" } }
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 82
def deep_transform_keys(&block)
  result = {}
  each do |key, value|
    result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
  end
  result
end
deep_transform_keys!(&block)

Destructively convert all keys by using the block operation. This includes the keys from the root hash and from all nested hashes.

# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 93
def deep_transform_keys!(&block)
  keys.each do |key|
    value = delete(key)
    self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
  end
  self
end
diff(other)

Returns a hash that represents the difference between two hashes.

{1 => 2}.diff(1 => 2)         # => {}
{1 => 2}.diff(1 => 3)         # => {1 => 2}
{}.diff(1 => 2)               # => {1 => 2}
{1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}
# File activesupport/lib/active_support/core_ext/hash/diff.rb, line 8
def diff(other)
  ActiveSupport::Deprecation.warn "Hash#diff is no longer used inside of Rails, and is being deprecated with no replacement. If you're using it to compare hashes for the purpose of testing, please use MiniTest's assert_equal instead."
  dup.
    delete_if { |k, v| other[k] == v }.
    merge!(other.dup.delete_if { |k, v| has_key?(k) })
end
except(*keys)

Return a hash that includes everything but the given keys. This is useful for limiting a set of parameters to everything but a few known toggles:

@person.update(params[:person].except(:admin))
# File activesupport/lib/active_support/core_ext/hash/except.rb, line 6
def except(*keys)
  dup.except!(*keys)
end
except!(*keys)

Replaces the hash without the given keys.

# File activesupport/lib/active_support/core_ext/hash/except.rb, line 11
def except!(*keys)
  keys.each { |key| delete(key) }
  self
end
extract!(*keys)

Removes and returns the key/value pairs matching the given keys.

{ a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
{ a: 1, b: 2 }.extract!(:a, :x)             # => {:a=>1}
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 37
def extract!(*keys)
  keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
end
extractable_options?()

By default, only instances of Hash itself are extractable. Subclasses of Hash may implement this method and return true to declare themselves as extractable. If a Hash is extractable, Array#extract_options! pops it from the Array when it is the last element of the Array.

# File activesupport/lib/active_support/core_ext/array/extract_options.rb, line 7
def extractable_options?
  instance_of?(Hash)
end
nested_under_indifferent_access()

Called when object is nested under an object that receives with_indifferent_access. This method will be called on the current object by the enclosing object and is aliased to with_indifferent_access by default. Subclasses of Hash may overwrite this method to return self if converting to an ActiveSupport::HashWithIndifferentAccess would not be desirable.

b = { b: 1 }
{ a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
reverse_merge(other_hash)

Merges the caller into other_hash. For example,

options = options.reverse_merge(size: 25, velocity: 10)

is equivalent to

options = { size: 25, velocity: 10 }.merge(options)

This is particularly useful for initializing an options hash with default values.

# File activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 12
def reverse_merge(other_hash)
  other_hash.merge(self)
end
reverse_merge!(other_hash)

Destructive reverse_merge.

Also aliased as: reverse_update
# File activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 17
def reverse_merge!(other_hash)
  # right wins if there is no left
  merge!( other_hash ){|key,left,right| left }
end
reverse_update(other_hash)
slice(*keys)

Slice a hash to include only the given keys. This is useful for limiting an options hash to valid keys before passing to a method:

def search(criteria = {})
  criteria.assert_valid_keys(:mass, :velocity, :time)
end

search(options.slice(:mass, :velocity, :time))

If you have an array of keys you want to limit to, you should splat them:

valid_keys = [:mass, :velocity, :time]
search(options.slice(*valid_keys))
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 15
def slice(*keys)
  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
  keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
end
slice!(*keys)

Replaces the hash with only the given keys. Returns a hash containing the removed key/value pairs.

{ a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
# => {:c=>3, :d=>4}
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 25
def slice!(*keys)
  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
  omit = slice(*self.keys - keys)
  hash = slice(*keys)
  replace(hash)
  omit
end
stringify_keys()

Return a new hash with all keys converted to strings.

hash = { name: 'Rob', age: '28' }

hash.stringify_keys
#=> { "name" => "Rob", "age" => "28" }
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 31
def stringify_keys
  transform_keys{ |key| key.to_s }
end
stringify_keys!()

Destructively convert all keys to strings. Same as stringify_keys, but modifies self.

# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 37
def stringify_keys!
  transform_keys!{ |key| key.to_s }
end
symbolize_keys()

Return a new hash with all keys converted to symbols, as long as they respond to to_sym.

hash = { 'name' => 'Rob', 'age' => '28' }

hash.symbolize_keys
#=> { name: "Rob", age: "28" }
Also aliased as: to_options
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 48
def symbolize_keys
  transform_keys{ |key| key.to_sym rescue key }
end
symbolize_keys!()

Destructively convert all keys to symbols, as long as they respond to to_sym. Same as symbolize_keys, but modifies self.

Also aliased as: to_options!
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 55
def symbolize_keys!
  transform_keys!{ |key| key.to_sym rescue key }
end
to_options()
to_options!()
to_param(namespace = nil)

Returns a string representation of the receiver suitable for use as a URL query string:

{name: 'David', nationality: 'Danish'}.to_param
# => "name=David&nationality=Danish"

An optional namespace can be passed to enclose the param names:

{name: 'David', nationality: 'Danish'}.to_param('user')
# => "user[name]=David&user[nationality]=Danish"

The string pairs “key=value” that conform the query string are sorted lexicographically in ascending order.

This method is also aliased as to_query.

Also aliased as: to_query
# File activesupport/lib/active_support/core_ext/object/to_param.rb, line 53
def to_param(namespace = nil)
  collect do |key, value|
    value.to_query(namespace ? "#{namespace}[#{key}]" : key)
  end.sort * '&'
end
to_query(namespace = nil)
to_xml(options = {})

Returns a string containing an XML representation of its receiver:

{'foo' => 1, 'bar' => 2}.to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <hash>
#   <foo type="integer">1</foo>
#   <bar type="integer">2</bar>
# </hash>

To do so, the method loops over the pairs and builds nodes that depend on the values. Given a pair key, value:

  • If value is a hash there’s a recursive call with key as :root.

  • If value is an array there’s a recursive call with key as :root, and key singularized as :children.

  • If value is a callable object it must expect one or two arguments. Depending on the arity, the callable is invoked with the options hash as first argument with key as :root, and key singularized as second argument. The callable can add nodes by using options[:builder].

    'foo'.to_xml(lambda { |options, key| options[:builder].b(key) })
    # => "<b>foo</b>"
    
  • If value responds to to_xml the method is invoked with key as :root.

    class Foo
      def to_xml(options)
        options[:builder].bar 'fooing!'
      end
    end
    
    { foo: Foo.new }.to_xml(skip_instruct: true)
    # => "<hash><bar>fooing!</bar></hash>"
    
  • Otherwise, a node with key as tag is created with a string representation of value as text node. If value is nil an attribute “nil” set to “true” is added. Unless the option :skip_types exists and is true, an attribute “type” is added as well according to the following mapping:

    XML_TYPE_NAMES = {
      "Symbol"     => "symbol",
      "Fixnum"     => "integer",
      "Bignum"     => "integer",
      "BigDecimal" => "decimal",
      "Float"      => "float",
      "TrueClass"  => "boolean",
      "FalseClass" => "boolean",
      "Date"       => "date",
      "DateTime"   => "dateTime",
      "Time"       => "dateTime"
    }
    

By default the root node is “hash”, but that’s configurable via the :root option.

The default XML builder is a fresh instance of Builder::XmlMarkup. You can configure your own builder with the :builder option. The method also accepts options like :dasherize and friends, they are forwarded to the builder.

# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 71
def to_xml(options = {})
  require 'active_support/builder' unless defined?(Builder)

  options = options.dup
  options[:indent]  ||= 2
  options[:root]    ||= 'hash'
  options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])

  builder = options[:builder]
  builder.instruct! unless options.delete(:skip_instruct)

  root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)

  builder.tag!(root) do
    each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, options) }
    yield builder if block_given?
  end
end
transform_keys()

Return a new hash with all keys converted using the block operation.

hash = { name: 'Rob', age: '28' }

hash.transform_keys{ |key| key.to_s.upcase }
# => { "NAME" => "Rob", "AGE" => "28" }
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 8
def transform_keys
  result = {}
  each_key do |key|
    result[yield(key)] = self[key]
  end
  result
end
transform_keys!()

Destructively convert all keys using the block operations. Same as #transform_keys but modifies self.

# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 18
def transform_keys!
  keys.each do |key|
    self[yield(key)] = delete(key)
  end
  self
end
with_indifferent_access()

Returns an ActiveSupport::HashWithIndifferentAccess out of its receiver:

{ a: 1 }.with_indifferent_access['a'] # => 1
# File activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 8
def with_indifferent_access
  ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
end