Class: Hash

Inherits:
Object show all
Includes:
ActiveSupport::CoreExtensions::Hash::Conversions, ActiveSupport::CoreExtensions::Hash::DeepMerge, ActiveSupport::CoreExtensions::Hash::Diff, ActiveSupport::CoreExtensions::Hash::Except, ActiveSupport::CoreExtensions::Hash::IndifferentAccess, ActiveSupport::CoreExtensions::Hash::Keys, ActiveSupport::CoreExtensions::Hash::ReverseMerge, ActiveSupport::CoreExtensions::Hash::Slice
Defined in:
lib/gems/activesupport-2.2.2/lib/active_support/core_ext/hash.rb,
lib/mack-facets/extensions/hash.rb,
lib/gems/extlib-0.9.9/lib/extlib/hash.rb,
lib/gems/activesupport-2.2.2/lib/active_support/core_ext/blank.rb,
lib/gems/activesupport-2.2.2/lib/active_support/json/encoders/hash.rb

Overview

:nodoc:

Constant Summary

Constants included from ActiveSupport::CoreExtensions::Hash::Conversions

ActiveSupport::CoreExtensions::Hash::Conversions::XML_FORMATTING, ActiveSupport::CoreExtensions::Hash::Conversions::XML_PARSING, ActiveSupport::CoreExtensions::Hash::Conversions::XML_TYPE_NAMES

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveSupport::CoreExtensions::Hash::Except

#except!

Methods included from ActiveSupport::CoreExtensions::Hash::Slice

#slice, #slice!

Methods included from ActiveSupport::CoreExtensions::Hash::Diff

#diff

Methods included from ActiveSupport::CoreExtensions::Hash::Conversions

included, #to_query, #to_xml

Methods included from ActiveSupport::CoreExtensions::Hash::ReverseMerge

#reverse_merge, #reverse_merge!

Methods included from ActiveSupport::CoreExtensions::Hash::DeepMerge

#deep_merge, #deep_merge!

Methods included from ActiveSupport::CoreExtensions::Hash::IndifferentAccess

#with_indifferent_access

Methods included from ActiveSupport::CoreExtensions::Hash::Keys

#assert_valid_keys, #stringify_keys, #stringify_keys!, #symbolize_keys, #symbolize_keys!

Class Method Details

.from_xml(xml) ⇒ Hash

Converts valid XML into a Ruby Hash structure.

Mixed content is treated as text and any tags in it are left unparsed

Any attributes other than type on a node containing a text node will be discarded

Typecasting is performed on elements that have a type attribute:
integer

Returns an Integer

boolean

Anything other than “true” evaluates to false.

datetime

Returns a Time object. See Time documentation for valid Time strings.

date

Returns a Date object. See Date documentation for valid Date strings.

Keys are automatically converted to snake_case

Simple

<user gender=‘m’>

<age type='integer'>35</age>
<name>Home Simpson</name>
<dob type='date'>1988-01-01</dob>
<joined-at type='datetime'>2000-04-28 23:01</joined-at>
<is-cool type='boolean'>true</is-cool>

</user>

Becomes:

{ "user" => {
    "gender"    => "m",
    "age"       => 35,
    "name"      => "Home Simpson",
    "dob"       => DateObject( 1998-01-01 ),
    "joined_at" => TimeObject( 2000-04-28 23:01),
    "is_cool"   => true
  }
}
Mixed Content

<story>

A Quick <em>brown</em> Fox

</story>

Evaluates to:

{ "story" => "A Quick <em>brown</em> Fox" }
Attributes other than type on a node containing text

<story is-good=‘false’>

A Quick <em>brown</em> Fox

</story>

Are ignored:

{ "story" => "A Quick <em>brown</em> Fox" }
Other attributes in addition to type

<bicep unit=‘inches’ type=‘integer’>60</bicep>

Evaluates with a typecast to an integer. But unit attribute is ignored:

{ "bicep" => 60 }

Parameters:

  • xml (String)

    A string representation of valid XML.

Returns:

  • (Hash)

    A hash created by parsing xml



73
74
75
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 73

def from_xml( xml )
  ToHashParser.from_xml(xml)
end

Instance Method Details

#-(ars) ⇒ Object

Deletes the key(s) passed in from the hash.



14
15
16
17
# File 'lib/mack-facets/extensions/hash.rb', line 14

def -(ars)
  [ars].flatten.each {|a| self.delete(a)}
  self
end

#add_html_class!(html_class) ⇒ Object

Examples:

hash #=> nil

hash.add_html_class!(:selected)

hash #=> “selected”

hash.add_html_class!(“class1 class2”)

hash #=> “selected class1 class2”

Parameters:

  • html_class (#to_s)

    The HTML class to add to the :class key. The html_class will be concatenated to any existing classes.



201
202
203
204
205
206
207
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 201

def add_html_class!(html_class)
  if self[:class]
    self[:class] = "#{self[:class]} #{html_class}"
  else
    self[:class] = html_class.to_s
  end
end

#environmentize_keys!Hash

Destructively and non-recursively convert each key to an uppercase string, deleting nil values along the way.

Examples:

{ :name => "Bob", :contact => { :email => "[email protected]" } }.environmentize_keys!
  #=> { "NAME" => "Bob", "CONTACT" => { :email => "[email protected]" } }

Returns:

  • (Hash)

    The newly environmentized hash.



242
243
244
245
246
247
248
249
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 242

def environmentize_keys!
  keys.each do |key|
    val = delete(key)
    next if val.nil?
    self[key.to_s.upcase] = val
  end
  self
end

#except(*rejected) ⇒ Hash

Create a hash with all key/value pairs in receiver except rejected

{ :one => 1, :two => 2, :three => 3 }.except(:one)
 #=> { :two => 2, :three => 3 }

Parameters:

Returns:

  • (Hash)

    A new hash without the selected keys.



173
174
175
176
177
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 173

def except(*rejected)
  hash = self.dup
  rejected.each {|k| hash.delete(k) }
  hash
end

#join(pair_string, join_string) ⇒ Object



4
5
6
7
8
9
10
11
# File 'lib/mack-facets/extensions/hash.rb', line 4

def join(pair_string, join_string)
  output = []
  sorted = self.sort {|a,b| a[0].to_s <=> b[0].to_s}
  sorted.each do |ar|
    output << sprintf(pair_string, ar[0], ar[1])
  end
  output.join(join_string)
end

#normalize_param(key, value) ⇒ String

Convert a key, value pair into a URL query param string

normalize_param(:name, "Bob")   #=> "name=Bob&"

Parameters:

  • key (Object)

    The key for the param.

  • value (Object)

    The value for the param.

Returns:

  • (String)

    This key value pair as a param



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 121

def normalize_param(key, value)
  param = ''
  stack = []

  if value.is_a?(Array)
    param << value.map { |element| normalize_param("#{key}[]", element) }.join
  elsif value.is_a?(Hash)
    stack << [key,value]
  else
    param << "#{key}=#{value}&"
  end

  stack.each do |parent, hash|
    hash.each do |key, value|
      if value.is_a?(Hash)
        stack << ["#{parent}[#{key}]", value]
      else
        param << normalize_param("#{parent}[#{key}]", value)
      end
    end
  end

  param
end

#only(*allowed) ⇒ Hash

Create a hash with only key/value pairs in receiver and allowed

{ :one => 1, :two => 2, :three => 3 }.only(:one)    #=> { :one => 1 }

Parameters:

Returns:

  • (Hash)

    A new hash with only the selected keys.



156
157
158
159
160
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 156

def only(*allowed)
  hash = {}
  allowed.each {|k| hash[k] = self[k] if self.has_key?(k) }
  hash
end

#protect_keys!Array

Converts all keys into string values. This is used during reloading to prevent problems when classes are no longer declared.

Examples:

hash = { One => 1, Two => 2 }.proctect_keys!
hash # => { "One" => 1, "Two" => 2 }

Returns:

  • (Array)

    An array of they hash’s keys



217
218
219
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 217

def protect_keys!
  keys.each {|key| self[key.to_s] = delete(key) }
end

#to_json(options = {}) ⇒ Object

Returns a JSON string representing the hash.

Without any options, the returned JSON string will include all the hash keys. For example:

{ :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
# => {"name": "Konata Izumi", 1: 2, "age": 16}

The keys in the JSON string are unordered due to the nature of hashes.

The :only and :except options can be used to limit the attributes included, and will accept 1 or more hash keys to include/exclude.

{ :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:only => [:name, 'age'])
# => {"name": "Konata Izumi", "age": 16}

{ :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:except => 1)
# => {"name": "Konata Izumi", "age": 16}

The options also filter down to any hash values. This is particularly useful for converting hashes containing ActiveRecord objects or any object that responds to options in their to_json method. For example:

users = User.find(:all)
{ :users => users, :count => users.size }.to_json(:include => :posts)

would pass the :include => :posts option to users, allowing the posts association in the User model to be converted to JSON as well.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/gems/activesupport-2.2.2/lib/active_support/json/encoders/hash.rb', line 31

def to_json(options = {}) #:nodoc:
  hash_keys = self.keys

  if options[:except]
    hash_keys = hash_keys - Array(options[:except])
  elsif options[:only]
    hash_keys = hash_keys & Array(options[:only])
  end

  returning result = '{' do
    result << hash_keys.map do |key|
      "#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(self[key], options)}"
    end * ', '
    result << '}'
  end
end

#to_mashMash

Convert to Mash. This class has semantics of ActiveSupport’s HashWithIndifferentAccess and we only have it so that people can write params instead of params.

Returns:

  • (Mash)

    This hash as a Mash for string or symbol key access.



83
84
85
86
87
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 83

def to_mash
  hash = Mash.new(self)
  hash.default = default
  hash
end

#to_paramsString

Convert to URL query param string

{ :name => "Bob",
  :address => {
    :street => '111 Ruby Ave.',
    :city => 'Ruby Central',
    :phones => ['111-111-1111', '222-222-2222']
  }
}.to_params
  #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave."

Returns:

  • (String)

    This hash as a query string



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/mack-facets/extensions/hash.rb', line 21

def to_params(escape = true)
  params = ''
  stack = []
  
  each do |k, v|
    if v.is_a?(Hash)
      stack << [k,v]
    else
      v = v.to_s.uri_escape if escape
      params << "#{k}=#{v}&"
    end
  end
  
  stack.each do |parent, hash|
    hash.each do |k, v|
      if v.is_a?(Hash)
        stack << ["#{parent}[#{k}]", v]
      else
        v = v.to_s.uri_escape if escape
        params << "#{parent}[#{k}]=#{v}&"
      end
    end
  end
  
  params.chop! # trailing &
  params.split("&").sort.join("&")
end

#to_xml_attributesString Also known as: to_html_attributes

Returns The hash as attributes for an XML tag.

Examples:

{ :one => 1, "two"=>"TWO" }.to_xml_attributes
  #=> 'one="1" two="TWO"'

Returns:

  • (String)

    The hash as attributes for an XML tag.



184
185
186
187
188
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 184

def to_xml_attributes
  map do |k,v|
    %{#{k.to_s.snake_case.sub(/^(.{1,1})/) { |m| m.downcase }}="#{v}"}
  end.join(' ')
end

#unprotect_keys!Object

Attempts to convert all string keys into Class keys. We run this after reloading to convert protected hashes back into usable hashes.

Examples:

# Provided that classes One and Two are declared in this scope:
hash = { "One" => 1, "Two" => 2 }.unproctect_keys!
hash # => { One => 1, Two => 2 }


228
229
230
231
232
# File 'lib/gems/extlib-0.9.9/lib/extlib/hash.rb', line 228

def unprotect_keys!
  keys.each do |key|
    (self[Object.full_const_get(key)] = delete(key)) rescue nil
  end
end