mcmire-openhash 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__)+'/openhash/hash_with_indifferent_access'
2
+ require File.dirname(__FILE__)+'/openhash/openhash'
@@ -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
+