hashery 1.5.0 → 2.0.0

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.
Files changed (70) hide show
  1. data/.ruby +30 -17
  2. data/.yardopts +1 -0
  3. data/Config.rb +28 -0
  4. data/{QED.rdoc → DEMO.rdoc} +0 -0
  5. data/HISTORY.rdoc +37 -0
  6. data/LICENSE.txt +26 -0
  7. data/NOTICE.txt +46 -0
  8. data/README.rdoc +10 -7
  9. data/lib/hashery.rb +6 -6
  10. data/lib/hashery.yml +30 -17
  11. data/lib/hashery/association.rb +169 -109
  12. data/lib/hashery/casting_hash.rb +128 -135
  13. data/lib/hashery/core_ext.rb +89 -61
  14. data/lib/hashery/crud_hash.rb +365 -0
  15. data/lib/hashery/dictionary.rb +545 -345
  16. data/lib/hashery/fuzzy_hash.rb +177 -125
  17. data/lib/hashery/ini_hash.rb +321 -0
  18. data/lib/hashery/key_hash.rb +54 -179
  19. data/lib/hashery/linked_list.rb +245 -191
  20. data/lib/hashery/lru_hash.rb +292 -202
  21. data/lib/hashery/open_cascade.rb +133 -78
  22. data/lib/hashery/open_hash.rb +127 -61
  23. data/lib/hashery/ordered_hash.rb +128 -122
  24. data/lib/hashery/path_hash.rb +238 -0
  25. data/lib/hashery/property_hash.rb +144 -80
  26. data/lib/hashery/query_hash.rb +85 -29
  27. data/lib/hashery/stash.rb +7 -3
  28. data/lib/hashery/static_hash.rb +46 -41
  29. data/test/case_association.rb +65 -4
  30. data/test/case_dictionary.rb +149 -5
  31. data/test/{case_keyhash.rb → case_key_hash.rb} +20 -14
  32. data/test/case_lru_hash.rb +162 -0
  33. data/test/{case_opencascade.rb → case_open_cascade.rb} +4 -8
  34. data/test/case_open_hash.rb +87 -0
  35. data/test/case_query_hash.rb +226 -0
  36. data/test/helper.rb +8 -0
  37. metadata +33 -63
  38. data/COPYING.rdoc +0 -45
  39. data/lib/hashery/basic_object.rb +0 -74
  40. data/lib/hashery/basic_struct.rb +0 -288
  41. data/lib/hashery/basicobject.rb +0 -1
  42. data/lib/hashery/basicstruct.rb +0 -1
  43. data/lib/hashery/castinghash.rb +0 -1
  44. data/lib/hashery/fuzzyhash.rb +0 -1
  45. data/lib/hashery/ini.rb +0 -268
  46. data/lib/hashery/keyhash.rb +0 -1
  47. data/lib/hashery/linkedlist.rb +0 -1
  48. data/lib/hashery/lruhash.rb +0 -1
  49. data/lib/hashery/memoizer.rb +0 -64
  50. data/lib/hashery/open_object.rb +0 -1
  51. data/lib/hashery/opencascade.rb +0 -1
  52. data/lib/hashery/openhash.rb +0 -1
  53. data/lib/hashery/openobject.rb +0 -1
  54. data/lib/hashery/orderedhash.rb +0 -1
  55. data/lib/hashery/ostructable.rb +0 -186
  56. data/lib/hashery/propertyhash.rb +0 -1
  57. data/lib/hashery/queryhash.rb +0 -1
  58. data/lib/hashery/statichash.rb +0 -1
  59. data/qed/01_openhash.rdoc +0 -57
  60. data/qed/02_queryhash.rdoc +0 -21
  61. data/qed/03_castinghash.rdoc +0 -13
  62. data/qed/04_statichash.rdoc +0 -22
  63. data/qed/05_association.rdoc +0 -59
  64. data/qed/06_opencascade.rdoc +0 -58
  65. data/qed/07_fuzzyhash.rdoc +0 -141
  66. data/qed/08_properyhash.rdoc +0 -38
  67. data/qed/09_ostructable.rdoc +0 -56
  68. data/qed/applique/ae.rb +0 -1
  69. data/test/case_basicstruct.rb +0 -192
  70. data/test/case_openhash.rb +0 -22
@@ -1 +0,0 @@
1
- require 'hasery/basic_object'
@@ -1 +0,0 @@
1
- require 'hashery/basic_struct'
@@ -1 +0,0 @@
1
- require 'hashery/casting_hash'
@@ -1 +0,0 @@
1
- require 'hashery/fuzzy_hash'
@@ -1,268 +0,0 @@
1
- # ini.rb - read and write ini files
2
- #
3
- # Copyright (C) 2007 Jeena Paradies
4
- # License: GPL
5
- # Author: Jeena Paradies (info@jeenaparadies.net)
6
- #
7
- # This file provides a read-wite handling for ini files.
8
- # The data of a ini file is represented by a object which
9
- # is populated with strings.
10
-
11
- # Class with methods to read from and write into ini files.
12
- #
13
- # A ini file is a text file in a specific format,
14
- # it may include several fields which are sparated by
15
- # field headlines which are enclosured by "[]".
16
- # Each field may include several key-value pairs.
17
- #
18
- # Each key-value pair is represented by one line and
19
- # the value is sparated from the key by a "=".
20
- #
21
- # == Examples
22
- #
23
- # === Example ini file
24
- #
25
- # # this is the first comment which will be saved in the comment attribute
26
- # mail=info@example.com
27
- # domain=example.com # this is a comment which will not be saved
28
- # [database]
29
- # db=example
30
- # user=john
31
- # passwd=very-secure
32
- # host=localhost
33
- # # this is another comment
34
- # [filepaths]
35
- # tmp=/tmp/example
36
- # lib=/home/john/projects/example/lib
37
- # htdocs=/home/john/projects/example/htdocs
38
- # [ texts ]
39
- # wellcome=Wellcome on my new website!
40
- # Website description = This is only a example. # and another comment
41
- #
42
- # === Example object
43
- #
44
- # Ini#comment stores:
45
- #
46
- # "this is the first comment which will be saved in the comment attribute"
47
- #
48
- # Ini's internal hash stores:
49
- #
50
- # {
51
- # "mail" => "info@example.com",
52
- # "domain" => "example.com",
53
- # "database" => {
54
- # "db" => "example",
55
- # "user" => "john",
56
- # "passwd" => "very-secure",
57
- # "host" => "localhost"
58
- # },
59
- # "filepaths" => {
60
- # "tmp" => "/tmp/example",
61
- # "lib" => "/home/john/projects/example/lib",
62
- # "htdocs" => "/home/john/projects/example/htdocs"
63
- # }
64
- # "texts" => {
65
- # "wellcome" => "Wellcome on my new website!",
66
- # "Website description" => "This is only a example."
67
- # }
68
- # }
69
- #
70
- # As you can see this module gets rid of all comments, linebreaks
71
- # and unnecessary spaces at the beginning and the end of each
72
- # field headline, key or value.
73
- #
74
- # === Using the object
75
- #
76
- # Using the object is stright forward:
77
- #
78
- # ini = Ini.new("path/settings.ini")
79
- # ini["mail"] = "info@example.com"
80
- # ini["filepaths"] = { "tmp" => "/tmp/example" }
81
- # ini.comment = "This is\na comment"
82
- # puts ini["filepaths"]["tmp"]
83
- # # => /tmp/example
84
- # ini.write()
85
- #
86
-
87
- class Ini
88
-
89
-
90
- #
91
- # :inihash is a hash which holds all ini data
92
- # :comment is a string which holds the comments on the top of the file
93
- #
94
- attr_accessor :inihash, :comment
95
-
96
- #
97
- # Creating a new Ini object
98
- #
99
- # +path+ is a path to the ini file
100
- # +load+ if nil restores the data if possible
101
- # if true restores the data, if not possible raises an error
102
- # if false does not resotre the data
103
- #
104
- def initialize(path, load=nil)
105
- @path = path
106
- @inihash = {}
107
-
108
- if load or ( load.nil? and FileTest.readable_real? @path )
109
- restore()
110
- end
111
- end
112
-
113
- #
114
- # Retrive the ini data for the key +key+
115
- #
116
- def [](key)
117
- @inihash[key]
118
- end
119
-
120
- #
121
- # Set the ini data for the key +key+
122
- #
123
- def []=(key, value)
124
- raise TypeError, "String expected" unless key.is_a? String
125
- raise TypeError, "String or Hash expected" unless value.is_a? String or value.is_a? Hash
126
-
127
- @inihash[key] = value
128
- end
129
-
130
- #
131
- # Restores the data from file into the object
132
- #
133
- def restore()
134
- @inihash = Ini.read_from_file(@path)
135
- @comment = Ini.read_comment_from_file(@path)
136
- end
137
-
138
- #
139
- # Store data from the object in the file
140
- #
141
- def update()
142
- Ini.write_to_file(@path, @inihash, @comment)
143
- end
144
-
145
- #
146
- def to_h
147
- @inihash.dup
148
- end
149
-
150
- #
151
- # Reading data from file
152
- #
153
- # +path+ is a path to the ini file
154
- #
155
- # returns a hash which represents the data from the file
156
- #
157
- def Ini.read_from_file(path)
158
-
159
- inihash = {}
160
- headline = nil
161
-
162
- IO.foreach(path) do |line|
163
-
164
- line = line.strip.split(/#/)[0]
165
-
166
- # read it only if the line doesn't begin with a "=" and is long enough
167
- unless line.length < 2 and line[0,1] == "="
168
-
169
- # it's a headline if the line begins with a "[" and ends with a "]"
170
- if line[0,1] == "[" and line[line.length - 1, line.length] == "]"
171
-
172
- # get rid of the [] and unnecessary spaces
173
- headline = line[1, line.length - 2 ].strip
174
- inihash[headline] = {}
175
- else
176
-
177
- key, value = line.split(/=/, 2)
178
-
179
- key = key.strip unless key.nil?
180
- value = value.strip unless value.nil?
181
-
182
- unless headline.nil?
183
- inihash[headline][key] = value
184
- else
185
- inihash[key] = value unless key.nil?
186
- end
187
- end
188
- end
189
- end
190
-
191
- inihash
192
- end
193
-
194
- #
195
- # Reading comments from file
196
- #
197
- # +path+ is a path to the ini file
198
- #
199
- # Returns a string with comments from the beginning of the
200
- # ini file.
201
- #
202
- def Ini.read_comment_from_file(path)
203
- comment = ""
204
-
205
- IO.foreach(path) do |line|
206
- line.strip!
207
- break unless line[0,1] == "#" or line == ""
208
-
209
- comment << "#{line[1, line.length ].strip}\n"
210
- end
211
-
212
- comment
213
- end
214
-
215
- #
216
- # Writing a ini hash into a file
217
- #
218
- # +path+ is a path to the ini file
219
- # +inihash+ is a hash representing the ini File. Default is a empty hash.
220
- # +comment+ is a string with comments which appear on the
221
- # top of the file. Each line will get a "#" before.
222
- # Default is no comment.
223
- #
224
- def Ini.write_to_file(path, inihash={}, comment=nil)
225
- raise TypeError, "String expected" unless comment.is_a? String or comment.nil?
226
-
227
- raise TypeError, "Hash expected" unless inihash.is_a? Hash
228
- File.open(path, "w") { |file|
229
-
230
- unless comment.nil?
231
- comment.each do |line|
232
- file << "# #{line}"
233
- end
234
- end
235
-
236
- file << Ini.to_s(inihash)
237
- }
238
- end
239
-
240
- #
241
- # Turn a hash (up to 2 levels deepness) into a ini string
242
- #
243
- # +inihash+ is a hash representing the ini File. Default is a empty hash.
244
- #
245
- # Returns a string in the ini file format.
246
- #
247
- def Ini.to_s(inihash={})
248
- str = ""
249
-
250
- inihash.each do |key, value|
251
-
252
- if value.is_a? Hash
253
- str << "[#{key.to_s}]\n"
254
-
255
- value.each do |under_key, under_value|
256
- str << "#{under_key.to_s}=#{under_value.to_s unless under_value.nil?}\n"
257
- end
258
-
259
- else
260
- str << "#{key.to_s}=#{value.to_s unless value2.nil?}\n"
261
- end
262
- end
263
-
264
- str
265
- end
266
-
267
- end
268
-
@@ -1 +0,0 @@
1
- require 'hashery/key_hash'
@@ -1 +0,0 @@
1
- require 'hashery/linked_list'
@@ -1 +0,0 @@
1
- require 'hashery/lru_hash'
@@ -1,64 +0,0 @@
1
- # Memoizer
2
- #
3
- # Copyright (c) 2006 Erik Veenstra
4
- #
5
- # See http://javathink.blogspot.com/2008/09/what-is-memoizer-and-why-should-you.html
6
-
7
- # Memoizer wraps objects to provide cached method calls.
8
- #
9
- # class X
10
- # def initialize ; @tick = 0 ; end
11
- # def tick; @tick + 1; end
12
- # def memo; @memo ||= Memoizer.new(self) ; end
13
- # end
14
- #
15
- # x = X.new
16
- # x.tick #=> 1
17
- # x.memo.tick #=> 2
18
- # x.tick #=> 3
19
- # x.memo.tick #=> 2
20
- # x.tick #=> 4
21
- # x.memo.tick #=> 2
22
- #
23
- # You can also use to cache collections of objects to gain code speed ups.
24
- #
25
- # points = points.collect{|point| Memoizer.cache(point)}
26
- #
27
- # After our algorithm has finished using points, we want to get rid of
28
- # these Memoizer objects. That's easy:
29
- #
30
- # points = points.collect{|point| point.__self__ }
31
- #
32
- # Or if you prefer (it is ever so slightly safer):
33
- #
34
- # points = points.collect{|point| Memoizer.uncache(point)}
35
- #
36
- class Memoizer
37
-
38
- #private :class, :clone, :display, :type, :method, :to_a, :to_s
39
- private *instance_methods(true).select{ |m| m.to_s !~ /^__/ }
40
-
41
- def initialize(object)
42
- @self = object
43
- @cache = {}
44
- end
45
-
46
- def __self__ ; @self ; end
47
-
48
- # Not thread-safe! Speed is important in caches... ;]
49
- def method_missing(method_name, *args, &block)
50
- @cache[[method_name, args, block]] ||= @self.__send__(method_name, *args, &block)
51
- end
52
-
53
- #def self; @self; end
54
-
55
- def self.cache(object)
56
- new(object)
57
- end
58
-
59
- def self.uncache(cached_object)
60
- cached_object.instance_variable_get('@self')
61
- end
62
-
63
- end
64
-
@@ -1 +0,0 @@
1
- raise 'Use BasicStruct in place of OpenObject for future versions.'
@@ -1 +0,0 @@
1
- require 'hashery/open_cascade'
@@ -1 +0,0 @@
1
- require 'hashery/open_hash'
@@ -1 +0,0 @@
1
- raise 'Use BasicStruct in place of OpenObject for future versions.'
@@ -1 +0,0 @@
1
- require 'hashery/ordered_hash'
@@ -1,186 +0,0 @@
1
- #--
2
- # OpenStructable
3
- #
4
- # Copyright (c) 2005 Thomas Sawyer
5
- #
6
- # ==========================================================================
7
- # Revision History ::
8
- # --------------------------------------------------------------------------
9
- # 05.04.28 Trans
10
- # - Minor modifications to documentation.
11
- # ==========================================================================
12
- #
13
- # TODO
14
- # Keep this uptodate with ostruct.rb.
15
- #
16
- # TODO Ask Matz
17
- # See if Matz will accept it into core so we don't have to anymore.
18
- #
19
- # TODO Marshalling
20
- # As with OpenStruct, marshalling is problematic at the moment.
21
- #
22
- #++
23
-
24
- # OpensStructable is a mixin module which can provide OpenStruct behavior to
25
- # any class or object. OpenStructable allows extention of data objects
26
- # with arbitrary attributes.
27
- #
28
- # == Usage
29
- #
30
- # require 'ostructable'
31
- #
32
- # class Record
33
- # include OpenStructable
34
- # end
35
- #
36
- # record = Record.new
37
- # record.name = "John Smith"
38
- # record.age = 70
39
- # record.pension = 300
40
- #
41
- # puts record.name # -> "John Smith"
42
- # puts record.address # -> nil
43
- #
44
- # == Author(s)
45
- #
46
- # * Thomas Sawyer
47
- # * Yukihiro Matsumoto
48
- # * Gavin Sinclair (Documentation)
49
- #
50
- module OpenStructable
51
-
52
- def self.include(base)
53
- if Hash > base
54
- base.module_eval do
55
- define_method(:__table__) do
56
- self
57
- end
58
- end
59
- protected :__table__
60
- end
61
- end
62
-
63
- def initialize(hash=nil)
64
- @__table__ = {}
65
- if hash
66
- for k,v in hash
67
- __table__[k.to_sym] = v
68
- new_ostruct_member(k)
69
- end
70
- end
71
- end
72
-
73
- #
74
- def __table__
75
- @__table__ ||= {}
76
- end
77
- protected :__table__
78
-
79
- # duplicate an OpenStruct object members.
80
- def initialize_copy(orig)
81
- super
82
- __table__.replace(__table__.dup)
83
- end
84
-
85
- def marshal_dump
86
- __table__
87
- end
88
-
89
- def marshal_load(hash)
90
- __table__.replace(hash)
91
- __table__.each_key{|key| new_ostruct_member(key)}
92
- end
93
-
94
- def new_ostruct_member(name)
95
- unless self.respond_to?(name)
96
- self.instance_eval %{
97
- def #{name}; __table__[:#{name}]; end
98
- def #{name}=(x); __table__[:#{name}] = x; end
99
- }
100
- end
101
- end
102
-
103
- #
104
- # Generate additional attributes and values.
105
- #
106
- def update(hash)
107
- #__table__ ||= {}
108
- if hash
109
- for k,v in hash
110
- __table__[k.to_sym] = v
111
- new_ostruct_member(k)
112
- end
113
- end
114
- end
115
-
116
- #
117
- def method_missing(mid, *args) # :nodoc:
118
- mname = mid.to_s
119
- len = args.length
120
- if mname =~ /=$/
121
- if len != 1
122
- raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
123
- end
124
- if self.frozen?
125
- raise TypeError, "can't modify frozen #{self.class}", caller(1)
126
- end
127
- mname.chop!
128
- #@__table__ ||= {}
129
- __table__[mname.intern] = args[0]
130
- self.new_ostruct_member(mname)
131
- elsif len == 0
132
- #@__table__ ||= {}
133
- __table__[mid]
134
- else
135
- raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1)
136
- end
137
- end
138
-
139
- #
140
- # Remove the named field from the object.
141
- #
142
- def delete_field(name)
143
- #@__table__ ||= {}
144
- __table__.delete(name.to_sym)
145
- end
146
-
147
- #
148
- # Returns a string containing a detailed summary of the keys and values.
149
- #
150
- def inspect
151
- str = "<#{self.class}"
152
- for k,v in (@__table__ ||= {})
153
- str << " #{k}=#{v.inspect}"
154
- end
155
- str << ">"
156
- end
157
-
158
- # Compare this object and +other+ for equality.
159
- #--
160
- # TODO: OpenStruct could be compared too, but only if it is loaded. How?
161
- #++
162
- def ==(other)
163
- case other
164
- when OpenStructable
165
- __table__ == other.__table__
166
- #when OpenStruct
167
- # __table__ == other.__table__
168
- when Hash
169
- __table__ == other
170
- else
171
- false
172
- end
173
- end
174
-
175
- end
176
-
177
- =begin
178
- #
179
- # It is possibe to implement OpenStruct itself with
180
- # this OpenStructable module as follows:
181
- #
182
- class OpenStruct
183
- include OpenStructable
184
- end
185
- =end
186
-