mcmire-openhash 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/openhash.rb +2 -0
- data/lib/openhash/hash_with_indifferent_access.rb +120 -0
- data/lib/openhash/openhash.rb +75 -0
- metadata +56 -0
data/lib/openhash.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# Copied from Rails 2.2 stable
|
2
|
+
class HashWithIndifferentAccess < Hash
|
3
|
+
def initialize(constructor = {})
|
4
|
+
if constructor.is_a?(Hash)
|
5
|
+
super()
|
6
|
+
update(constructor)
|
7
|
+
else
|
8
|
+
super(constructor)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def default(key = nil)
|
13
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
14
|
+
self[key]
|
15
|
+
else
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
21
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
22
|
+
|
23
|
+
# Assigns a new value to the hash:
|
24
|
+
#
|
25
|
+
# hash = HashWithIndifferentAccess.new
|
26
|
+
# hash[:key] = "value"
|
27
|
+
#
|
28
|
+
def []=(key, value)
|
29
|
+
regular_writer(convert_key(key), convert_value(value))
|
30
|
+
end
|
31
|
+
|
32
|
+
# Updates the instantized hash with values from the second:
|
33
|
+
#
|
34
|
+
# hash_1 = HashWithIndifferentAccess.new
|
35
|
+
# hash_1[:key] = "value"
|
36
|
+
#
|
37
|
+
# hash_2 = HashWithIndifferentAccess.new
|
38
|
+
# hash_2[:key] = "New Value!"
|
39
|
+
#
|
40
|
+
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
41
|
+
#
|
42
|
+
def update(other_hash)
|
43
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method :merge!, :update
|
48
|
+
|
49
|
+
# Checks the hash for a key matching the argument passed in:
|
50
|
+
#
|
51
|
+
# hash = HashWithIndifferentAccess.new
|
52
|
+
# hash["key"] = "value"
|
53
|
+
# hash.key? :key # => true
|
54
|
+
# hash.key? "key" # => true
|
55
|
+
#
|
56
|
+
def key?(key)
|
57
|
+
super(convert_key(key))
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :include?, :key?
|
61
|
+
alias_method :has_key?, :key?
|
62
|
+
alias_method :member?, :key?
|
63
|
+
|
64
|
+
# Fetches the value for the specified key, same as doing hash[key]
|
65
|
+
def fetch(key, *extras)
|
66
|
+
super(convert_key(key), *extras)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns an array of the values at the specified indices:
|
70
|
+
#
|
71
|
+
# hash = HashWithIndifferentAccess.new
|
72
|
+
# hash[:a] = "x"
|
73
|
+
# hash[:b] = "y"
|
74
|
+
# hash.values_at("a", "b") # => ["x", "y"]
|
75
|
+
#
|
76
|
+
def values_at(*indices)
|
77
|
+
indices.collect {|key| self[convert_key(key)]}
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns an exact copy of the hash.
|
81
|
+
def dup
|
82
|
+
HashWithIndifferentAccess.new(self)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
|
86
|
+
# Does not overwrite the existing hash.
|
87
|
+
def merge(hash)
|
88
|
+
self.dup.update(hash)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Removes a specified key from the hash.
|
92
|
+
def delete(key)
|
93
|
+
super(convert_key(key))
|
94
|
+
end
|
95
|
+
|
96
|
+
def stringify_keys!; self end
|
97
|
+
def symbolize_keys!; self end
|
98
|
+
def to_options!; self end
|
99
|
+
|
100
|
+
# Convert to a Hash with String keys.
|
101
|
+
def to_hash
|
102
|
+
Hash.new(default).merge(self)
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
def convert_key(key)
|
107
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
108
|
+
end
|
109
|
+
|
110
|
+
def convert_value(value)
|
111
|
+
case value
|
112
|
+
when Hash
|
113
|
+
value.with_indifferent_access
|
114
|
+
when Array
|
115
|
+
value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
|
116
|
+
else
|
117
|
+
value
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Adapted from Ruby Facets
|
2
|
+
class OpenHash < HashWithIndifferentAccess
|
3
|
+
def initialize(hash = {})
|
4
|
+
super()
|
5
|
+
update(hash)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.[](hash = {})
|
9
|
+
new(hash)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Route get and set calls.
|
13
|
+
def method_missing(name, *args)
|
14
|
+
name = name.to_s
|
15
|
+
# do nothing if missing method
|
16
|
+
return if name == 'default' && !args.empty?
|
17
|
+
k = name.sub(/[?!=]$/, '')
|
18
|
+
if name =~ /=$/
|
19
|
+
self[k] = args.first
|
20
|
+
elsif args.empty?
|
21
|
+
self[k]
|
22
|
+
else
|
23
|
+
# this should never be called?!
|
24
|
+
super(name, *args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def with_indifferent_access
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def dup
|
33
|
+
self.class.new(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
class Hash
|
39
|
+
def to_openhash
|
40
|
+
hash = self.dup
|
41
|
+
hash.each {|k,v| hash[k] = v.to_openhash if v.is_a?(Hash) }
|
42
|
+
OpenHash.new(hash)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#oh = OpenHash.new
|
47
|
+
#oh.x = 'y'
|
48
|
+
#oh.few = 3
|
49
|
+
#oh.regz = :sym
|
50
|
+
#oh['slimey'] = 'frog'
|
51
|
+
#puts "oh.inspect = " + oh.inspect
|
52
|
+
#puts "oh.few = #{oh.few}"
|
53
|
+
#puts "oh.slimey = #{oh.slimey}"
|
54
|
+
#exit
|
55
|
+
|
56
|
+
#openhash = OpenHash.new(
|
57
|
+
# :foo => OpenHash.new(
|
58
|
+
# :one => 'awexome',
|
59
|
+
# :two => 'cross',
|
60
|
+
# :three => 'homestar runner'
|
61
|
+
# ),
|
62
|
+
# :bar => OpenHash.new(
|
63
|
+
# :michael => 'jackson',
|
64
|
+
# :citizen => 'kane',
|
65
|
+
# :bread => 'crumbs'
|
66
|
+
# )
|
67
|
+
#)
|
68
|
+
#puts openhash.foo.inspect
|
69
|
+
#openhash.foo.one = 'pretty'
|
70
|
+
#puts openhash.foo.inspect
|
71
|
+
#exit
|
72
|
+
|
73
|
+
#hash = {:y=>{:z=>"foo"}, :x=>"blah"}
|
74
|
+
#puts hash.to_openhash.inspect
|
75
|
+
#exit
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mcmire-openhash
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Elliot Winkler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-08 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: OpenHash is an alternative to OpenStruct and Ruby Facets' OpenObject. The goal of these libraries is to allow you to access your hash in a more object-oriented syntax, but unlike the others, this library simply uses method_missing.
|
17
|
+
email: elliot.winkler@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/openhash.rb
|
26
|
+
- lib/openhash/openhash.rb
|
27
|
+
- lib/openhash/hash_with_indifferent_access.rb
|
28
|
+
has_rdoc: false
|
29
|
+
homepage: http://github.com/mcmire/openhash
|
30
|
+
licenses:
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.3.5
|
52
|
+
signing_key:
|
53
|
+
specification_version: 2
|
54
|
+
summary: Simply access your hash in a more object-oriented syntax
|
55
|
+
test_files: []
|
56
|
+
|