facets 2.5.0 → 2.5.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.
Files changed (191) hide show
  1. data/AUTHORS +1 -1
  2. data/CHANGES +28 -45
  3. data/MANIFEST +35 -4
  4. data/README +3 -14
  5. data/RELEASE +36 -70
  6. data/VERSION +1 -1
  7. data/doc/archive/RELEASE-2.5.0 +83 -0
  8. data/doc/log/basic_stats/index.html +4 -4
  9. data/doc/log/changelog.html +509 -2
  10. data/doc/log/changelog.txt +130 -1522
  11. data/doc/rdoc/core/classes/Array.html +366 -141
  12. data/doc/rdoc/core/classes/Binding.html +45 -45
  13. data/doc/rdoc/core/classes/Class.html +38 -38
  14. data/doc/rdoc/core/classes/Comparable.html +26 -26
  15. data/doc/rdoc/core/classes/Enumerable.html +174 -170
  16. data/doc/rdoc/core/classes/Enumerable/Enumerator.html +130 -0
  17. data/doc/rdoc/core/classes/Enumerator.html +132 -0
  18. data/doc/rdoc/core/classes/Exception.html +8 -8
  19. data/doc/rdoc/core/classes/File.html +58 -58
  20. data/doc/rdoc/core/classes/FileTest.html +4 -4
  21. data/doc/rdoc/core/classes/Float.html +8 -8
  22. data/doc/rdoc/core/classes/Functor.html +12 -12
  23. data/doc/rdoc/core/classes/Hash.html +447 -263
  24. data/doc/rdoc/core/classes/Indexable.html +110 -110
  25. data/doc/rdoc/core/classes/Integer.html +2 -2
  26. data/doc/rdoc/core/classes/Kernel.html +329 -329
  27. data/doc/rdoc/core/classes/Lazy/Promise.html +1 -1
  28. data/doc/rdoc/core/classes/MatchData.html +15 -15
  29. data/doc/rdoc/core/classes/Module.html +176 -157
  30. data/doc/rdoc/core/classes/NilClass.html +23 -23
  31. data/doc/rdoc/core/classes/Numeric.html +27 -27
  32. data/doc/rdoc/core/classes/Object.html +8 -8
  33. data/doc/rdoc/core/classes/ObjectSpace.html +5 -5
  34. data/doc/rdoc/core/classes/Proc.html +22 -22
  35. data/doc/rdoc/core/classes/Regexp.html +1 -1
  36. data/doc/rdoc/core/classes/Stackable.html +31 -31
  37. data/doc/rdoc/core/classes/String.html +332 -291
  38. data/doc/rdoc/core/classes/Symbol.html +1 -1
  39. data/doc/rdoc/core/classes/TrueClass.html +8 -8
  40. data/doc/rdoc/core/classes/UnboundMethod.html +18 -13
  41. data/doc/rdoc/core/created.rid +1 -1
  42. data/doc/rdoc/core/files/README.html +7 -29
  43. data/doc/rdoc/core/files/lib/core/facets/array/product_rb.html +1 -1
  44. data/doc/rdoc/core/files/lib/core/facets/enumerable/collect_rb.html +10 -1
  45. data/doc/rdoc/core/files/lib/core/facets/enumerable/compact_map_rb.html +92 -0
  46. data/doc/rdoc/core/files/lib/core/facets/enumerable/map_with_index_rb.html +92 -0
  47. data/doc/rdoc/core/files/lib/core/facets/enumerable/split_rb.html +1 -1
  48. data/doc/rdoc/core/files/lib/core/facets/hash/collate_rb.html +1 -1
  49. data/doc/rdoc/core/files/lib/core/facets/hash/group_by_value_rb.html +92 -0
  50. data/doc/rdoc/core/files/lib/core/facets/hash/new_with_rb.html +92 -0
  51. data/doc/rdoc/core/files/lib/core/facets/module/conflict_rb.html +1 -1
  52. data/doc/rdoc/core/files/lib/core/facets/module/extend_rb.html +92 -0
  53. data/doc/rdoc/core/files/lib/core/facets/string/align_rb.html +1 -1
  54. data/doc/rdoc/core/files/lib/core/facets/string/file_rb.html +96 -0
  55. data/doc/rdoc/core/files/lib/core/facets/string/xor_rb.html +1 -1
  56. data/doc/rdoc/core/files/lib/core/facets/to_hash_rb.html +5 -1
  57. data/doc/rdoc/core/files/lib/core/facets/unboundmethod/name_rb.html +1 -1
  58. data/doc/rdoc/core/fr_class_index.html +2 -0
  59. data/doc/rdoc/core/fr_file_index.html +6 -0
  60. data/doc/rdoc/core/fr_method_index.html +386 -373
  61. data/doc/rdoc/lore/classes/OpenStruct.html +6 -4
  62. data/doc/rdoc/lore/created.rid +1 -1
  63. data/doc/rdoc/lore/files/README.html +7 -29
  64. data/doc/rdoc/lore/files/lib/lore/facets/ostruct_rb.html +1 -1
  65. data/doc/rdoc/more/classes/ANSICode.html +66 -66
  66. data/doc/rdoc/more/classes/Advisable.html +37 -37
  67. data/doc/rdoc/more/classes/Advisable/Method.html +20 -20
  68. data/doc/rdoc/more/classes/Archive/Tar/Minitar.html +27 -27
  69. data/doc/rdoc/more/classes/Archive/Tar/Minitar/Input.html +28 -28
  70. data/doc/rdoc/more/classes/Archive/Tar/Minitar/Output.html +19 -19
  71. data/doc/rdoc/more/classes/Archive/Tar/Minitar/Reader.html +31 -31
  72. data/doc/rdoc/more/classes/Archive/Tar/Minitar/Writer.html +33 -33
  73. data/doc/rdoc/more/classes/Association.html +67 -53
  74. data/doc/rdoc/more/classes/Association/Kernel.html +11 -12
  75. data/doc/rdoc/more/classes/BBCode.html +36 -36
  76. data/doc/rdoc/more/classes/BaseX.html +16 -16
  77. data/doc/rdoc/more/classes/BiCrypt.html +67 -67
  78. data/doc/rdoc/more/classes/BinReadable.html +85 -85
  79. data/doc/rdoc/more/classes/BinReadable/ByteOrder.html +25 -25
  80. data/doc/rdoc/more/classes/Binding.html +8 -8
  81. data/doc/rdoc/more/classes/Buildable.html +4 -4
  82. data/doc/rdoc/more/classes/Cloneable.html +4 -4
  83. data/doc/rdoc/more/classes/ConsoleUtils.html +18 -18
  84. data/doc/rdoc/more/classes/Crypt.html +16 -16
  85. data/doc/rdoc/more/classes/CssTree.html +8 -8
  86. data/doc/rdoc/more/classes/Dictionary.html +52 -45
  87. data/doc/rdoc/more/classes/Enumerable.html +50 -50
  88. data/doc/rdoc/more/classes/Enumerable/Elementor.html +16 -16
  89. data/doc/rdoc/more/classes/Enumerable/Enumerator.html +4 -4
  90. data/doc/rdoc/more/classes/Enumerable/Filterable.html +30 -30
  91. data/doc/rdoc/more/classes/EnumerablePass.html +15 -15
  92. data/doc/rdoc/more/classes/Equatable.html +16 -16
  93. data/doc/rdoc/more/classes/Expirable.html +17 -17
  94. data/doc/rdoc/more/classes/Fileable.html +14 -14
  95. data/doc/rdoc/more/classes/Fileable/DSL.html +41 -41
  96. data/doc/rdoc/more/classes/Hash2Xml.html +4 -4
  97. data/doc/rdoc/more/classes/Hook.html +162 -0
  98. data/doc/rdoc/more/classes/HtmlFilter.html +9 -9
  99. data/doc/rdoc/more/classes/Instantiable.html +9 -9
  100. data/doc/rdoc/more/classes/Instantize.html +8 -8
  101. data/doc/rdoc/more/classes/Interval.html +187 -187
  102. data/doc/rdoc/more/classes/It.html +12 -12
  103. data/doc/rdoc/more/classes/Matcher.html +38 -38
  104. data/doc/rdoc/more/classes/Matcher/MatchData.html +4 -4
  105. data/doc/rdoc/more/classes/Memoizer.html +21 -21
  106. data/doc/rdoc/more/classes/Multiton.html +12 -12
  107. data/doc/rdoc/more/classes/Multiton/MetaMethods.html +28 -28
  108. data/doc/rdoc/more/classes/Net/SMTP.html +8 -8
  109. data/doc/rdoc/more/classes/OpEsc.html +5 -5
  110. data/doc/rdoc/more/classes/OpenCascade.html +4 -4
  111. data/doc/rdoc/more/classes/OpenHash.html +9 -9
  112. data/doc/rdoc/more/classes/OpenStructable.html +36 -36
  113. data/doc/rdoc/more/classes/PQueue.html +84 -84
  114. data/doc/rdoc/more/classes/Paramix.html +16 -16
  115. data/doc/rdoc/more/classes/Paramix/Delegator.html +16 -16
  116. data/doc/rdoc/more/classes/RWDelegator.html +16 -16
  117. data/doc/rdoc/more/classes/Random.html +5 -5
  118. data/doc/rdoc/more/classes/Random/Array.html +37 -37
  119. data/doc/rdoc/more/classes/Random/Hash.html +52 -52
  120. data/doc/rdoc/more/classes/Random/Object.html +4 -4
  121. data/doc/rdoc/more/classes/Random/String.html +34 -34
  122. data/doc/rdoc/more/classes/Random/String/Self.html +9 -9
  123. data/doc/rdoc/more/classes/Registerable.html +13 -13
  124. data/doc/rdoc/more/classes/Stash.html +28 -28
  125. data/doc/rdoc/more/classes/String/Mask.html +72 -72
  126. data/doc/rdoc/more/classes/String/Words.html +31 -31
  127. data/doc/rdoc/more/classes/System.html +253 -253
  128. data/doc/rdoc/more/classes/Timer.html +48 -48
  129. data/doc/rdoc/more/classes/Timer/Dummy.html +9 -9
  130. data/doc/rdoc/more/classes/Tuple.html +170 -170
  131. data/doc/rdoc/more/classes/TypeCast/Class.html +4 -4
  132. data/doc/rdoc/more/classes/TypeCast/Object.html +4 -4
  133. data/doc/rdoc/more/classes/Uninheritable.html +6 -6
  134. data/doc/rdoc/more/classes/X.html +117 -0
  135. data/doc/rdoc/more/classes/XOXO.html +11 -11
  136. data/doc/rdoc/more/classes/ZipUtils.html +88 -88
  137. data/doc/rdoc/more/classes/ZipUtils/DryRun.html +68 -68
  138. data/doc/rdoc/more/classes/ZipUtils/NoWrite.html +68 -68
  139. data/doc/rdoc/more/classes/ZipUtils/Verbose.html +60 -60
  140. data/doc/rdoc/more/created.rid +1 -1
  141. data/doc/rdoc/more/files/README.html +7 -29
  142. data/doc/rdoc/more/files/lib/more/facets/association_rb.html +1 -1
  143. data/doc/rdoc/more/files/lib/more/facets/dictionary_rb.html +1 -1
  144. data/doc/rdoc/more/files/lib/more/facets/hook_rb.html +96 -0
  145. data/doc/rdoc/more/files/lib/more/facets/paramix_rb.html +1 -1
  146. data/doc/rdoc/more/files/lib/more/facets/xoxo_rb.html +2 -2
  147. data/doc/rdoc/more/fr_class_index.html +2 -0
  148. data/doc/rdoc/more/fr_file_index.html +1 -0
  149. data/doc/rdoc/more/fr_method_index.html +686 -681
  150. data/lib/core/facets/array/product.rb +6 -23
  151. data/lib/core/facets/enumerable/collect.rb +3 -53
  152. data/lib/core/facets/enumerable/compact_map.rb +35 -0
  153. data/lib/core/facets/enumerable/map_with_index.rb +23 -0
  154. data/lib/core/facets/enumerable/split.rb +3 -3
  155. data/lib/core/facets/hash/collate.rb +45 -14
  156. data/lib/core/facets/hash/group_by_value.rb +65 -0
  157. data/lib/core/facets/hash/new_with.rb +15 -0
  158. data/lib/core/facets/module/extend.rb +11 -0
  159. data/lib/core/facets/string/align.rb +19 -18
  160. data/lib/core/facets/string/file.rb +17 -0
  161. data/lib/core/facets/string/xor.rb +9 -3
  162. data/lib/core/facets/to_hash.rb +274 -17
  163. data/lib/core/facets/unboundmethod/name.rb +4 -2
  164. data/lib/lore/facets/ostruct.rb +3 -0
  165. data/lib/more/facets/association.rb +28 -12
  166. data/lib/more/facets/dictionary.rb +10 -4
  167. data/lib/more/facets/hook.rb +65 -0
  168. data/lib/more/facets/paramix.rb +5 -5
  169. data/meta/abstract +13 -0
  170. data/meta/authors +1 -0
  171. data/meta/contact +1 -0
  172. data/meta/contributors +48 -0
  173. data/meta/created +1 -0
  174. data/meta/homepage +1 -0
  175. data/meta/license +1 -0
  176. data/meta/loadpath +3 -0
  177. data/meta/releases +14 -0
  178. data/meta/slogan +1 -0
  179. data/meta/summary +1 -0
  180. data/task/test.rake +116 -18
  181. data/test/core/array/test_product.rb +0 -6
  182. data/test/core/binding/test_local_variables.rb +9 -3
  183. data/test/core/enumerable/test_split.rb +19 -0
  184. data/test/core/module/test_conflict.rb +8 -3
  185. data/test/core/test_to_hash.rb +152 -0
  186. data/test/core/unboundmethod/test_arguments.rb +1 -1
  187. data/test/core/unboundmethod/test_name.rb +2 -2
  188. metadata +39 -8
  189. data/doc/log/bstats/stats.html +0 -39
  190. data/doc/log/stats.html +0 -25
  191. data/test/more/test_to_hash.rb +0 -58
@@ -0,0 +1,17 @@
1
+ require 'facets/functor'
2
+
3
+ class String
4
+
5
+ # Use fluent notation for making file directives.
6
+ #
7
+ # '~/trans/Desktop/notes.txt'.file.mtime
8
+ #
9
+ def file
10
+ f = self
11
+ Functor.new do |op, *a|
12
+ File.send(op, f, *a)
13
+ end
14
+ end
15
+
16
+ end
17
+
@@ -1,9 +1,15 @@
1
1
  class String
2
2
 
3
- # XOR two string.
3
+ # Binary XOR of two strings.
4
+ #
5
+ # puts "\000\000\001\001" ^ "\000\001\000\001"
6
+ # puts "\003\003\003" ^ "\000\001\002"
7
+ #
8
+ # _produces_
9
+ #
10
+ # "\000\001\001\000"
11
+ # "\003\002\001"
4
12
  #
5
- # TODO: This is used by crypt.rb, it needs to be documented.
6
-
7
13
  def ^(aString)
8
14
  a = self.unpack('C'*(self.length))
9
15
  b = aString.unpack('C'*(aString.length))
@@ -1,38 +1,238 @@
1
+ require 'enumerator' if RUBY_VERSION < "1.9"
2
+
3
+ class Hash
4
+
5
+ # Any array values with less one or no elements will have the element
6
+ # or nil set as the value instead.
7
+ #
8
+ # h = { :a=>[1], :b=>[1,2], :c=>3, :d=>[] }
9
+ # h.dearray_values #=> { :a=>1, :b=>1, :c=>3, :d=>nil }
10
+ #
11
+ # CREDIT: Trans
12
+
13
+ def dearray_values(index=0)
14
+ h = {}
15
+ each do |k,v|
16
+ case v
17
+ when Array
18
+ h[k] = v[index] || v[-1]
19
+ else
20
+ h[k] = v
21
+ end
22
+ end
23
+ h
24
+ end
25
+
26
+ # Any array values with less one or no elements will have the element
27
+ # or nil set as the value instead.
28
+ #
29
+ # h = { :a=>[1], :b=>[1,2], :c=>3, :d=>[] }
30
+ # h.dearray_singluar_values #=> { :a=>1, :b=>[1,2], :c=>3, :d=>nil }
31
+ #
32
+ # CREDIT: Trans
33
+
34
+ def dearray_singluar_values
35
+ h = {}
36
+ each do |k,v|
37
+ case v
38
+ when Array
39
+ h[k] = (v.size < 2) ? v[0] : v
40
+ else
41
+ h[k] = v
42
+ end
43
+ end
44
+ h
45
+ end
46
+
47
+ end
48
+
49
+
1
50
  class Array
2
51
 
3
- # Converts a two-element associative array into a hash.
52
+ # Converts an array into a hash. Converting an array
53
+ # into a hash is not a one-to-one conversion, for this
54
+ # reason #to_h examines at the array being converted
55
+ # and then dispatches the conversion to the most sutiable
56
+ # specialized function. There are three possiblities for this.
57
+ #
58
+ # If the array is a collection of perfect pairs, like that
59
+ # which Hash#to_a generates, then conversion is handled by
60
+ # #to_h_flat.
4
61
  #
5
62
  # a = [ [:a,1], [:b,2] ]
6
63
  # a.to_h #=> { :a=>1, :b=>2 }
7
64
  #
8
- # If +arrayed+ is set it will maintain trailing arrays.
65
+ # If the array contains only arrays, but are not perfect pairs,
66
+ # then #to_h_multi is called.
67
+ #
68
+ # a = [ [:a,1,2], [:b,2], [:c], [:d] ]
69
+ # a.to_h #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
70
+ #
71
+ # If the array contians objects other then arrays then
72
+ # the #to_h_splat method is called.
9
73
  #
10
- # a = [ [:a,1,2], [:b,3] ]
11
- # a.to_h(true) #=> { :a=>[1,2], :b=>[3] }
74
+ # a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
75
+ # a.to_h #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }
12
76
  #
13
- # Note that the use of a values parameter has been deprecated
77
+ # Finally, a particular dispatch can be forced by
78
+ # specifying the +mode+ of conversion, eg. +:multi+,
79
+ # +:splat+, +:flat+, +:assoc+, etc.
80
+ #
81
+ # Setting +mode+ to +true+ is the same as setting it +:multi+.
82
+ # This has been left in for backward compatability.
83
+ #
84
+ # NOTE: The use of a +values+ parameter has been deprecated
14
85
  # because that functionality is as simple as:
15
86
  #
16
87
  # array1.zip(array2).to_h
17
88
  #
89
+ # CREDIT: Robert Klemme
18
90
  # CREDIT: Trans
91
+ #
92
+ #--
93
+ # The +True+ option in the case statement provides some
94
+ # backward compatability with the previous versions of this
95
+ # method.
96
+ #++
19
97
 
20
- def to_h(arrayed=nil)
21
- h = {}
22
- if arrayed #or (flatten.size % 2 == 1)
23
- #each{ |e| h[e.first] = e.slice(1..-1) }
24
- each{ |k,*v| h[k] = v }
98
+ def to_h(mode=nil)
99
+ case mode
100
+ when :splat
101
+ return to_h_splat
102
+ when :flat
103
+ return to_h_flat
104
+ when :multi, true
105
+ return to_h_multi
106
+ when :assoc
107
+ return to_h_assoc
25
108
  else
26
- #h = Hash[*flatten(1)] # TODO Use in 1.9 instead.
27
- ary = []
28
- each do |a|
29
- Array===a ? ary.concat(a) : ary << a
109
+ return to_h_auto
110
+ end
111
+ end
112
+
113
+ # Converts an array into a hash. Converting an array
114
+ # into a hash is not a one-to-one conversion, for this
115
+ # reason #to_h examines at the array being converted
116
+ # and then dispatches the conversion to the most sutiable
117
+ # specialized function. There are three possiblities for this.
118
+ #
119
+ # If the array is a collection of perfect pairs, like that
120
+ # which Hash#to_a generates, then conversion is handled by
121
+ # #to_h_flat.
122
+ #
123
+ # a = [ [:a,1], [:b,2] ]
124
+ # a.to_h #=> { :a=>1, :b=>2 }
125
+ #
126
+ # If the array contains only arrays, but are not perfect pairs,
127
+ # then #to_h_multi is called.
128
+ #
129
+ # a = [ [:a,1,2], [:b,2], [:c], [:d] ]
130
+ # a.to_h #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
131
+ #
132
+ # If the array contians objects other then arrays then
133
+ # the #to_h_splat method is called.
134
+ #
135
+ # a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
136
+ # a.to_h #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }
137
+ #
138
+ def to_h_auto
139
+ pairs = true
140
+ mixed = false
141
+
142
+ each do |e|
143
+ case e
144
+ when Array
145
+ pairs = false if e.size > 2
146
+ else
147
+ mixed = true
30
148
  end
31
- h = Hash[*ary]
149
+ end
150
+
151
+ if mixed
152
+ to_h_splat
153
+ elsif pairs
154
+ to_h_flat
155
+ else
156
+ to_h_multi
157
+ end
158
+ end
159
+
160
+ # This is equivalent to Hash[*array], but it will pad
161
+ # the array with a +nil+ object if there are not an even number
162
+ # of elements.
163
+ #
164
+ # a = [:a,1,:b,2,:c]
165
+ # a.to_h_splat #=> { :a=>1, :b=>2, :c=>nil }
166
+ #
167
+ def to_h_splat
168
+ a = dup
169
+ a << nil if a.size % 2 == 1
170
+ Hash[*a]
171
+ end
172
+
173
+ # This is equivalent to Hash[*array.flatten], but it will pad
174
+ # the array with a +nil+ object if there are not an even number
175
+ # of elements.
176
+ #
177
+ # a = [:a,1,[:b,2,:c]]
178
+ # a.to_h_flat #=> { :a=>1, :b=>2, :c=>nil }
179
+ #
180
+ def to_h_flat
181
+ a = flatten
182
+ a << nil if a.size % 2 == 1
183
+ Hash[*a]
184
+ end
185
+
186
+ #def to_h_flat
187
+ # each_slice(2).inject({}) {|ha,(k,v)| ha[k]=v; ha}
188
+ #end
189
+
190
+ # When a mixed or multi-element accociative array
191
+ # is used, the result is as follows:
192
+ #
193
+ # a = [ [:a,1,2], [:b,2], [:c], :d ]
194
+ # a.to_h #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
195
+ #
196
+ # If the fist entry of any subelements are the same, then
197
+ # the value will be set to the last occuring value.
198
+ #
199
+ # a = [ :x, [:x], [:x,1,2], [:x,3], [:x,4] ]
200
+ # a.to_h_assoc #=> { :x=>4 }
201
+ #
202
+ def to_h_assoc
203
+ h = {}
204
+ each do |k,*v|
205
+ h[k] = v
206
+ end
207
+ h
208
+ end
209
+
210
+ # When a mixed or multi-element accociative array
211
+ # is used, the result is as follows:
212
+ #
213
+ # a = [ [:a,1,2], [:b,2], [:c], :d ]
214
+ # a.to_h #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
215
+ #
216
+ # If the fist entry of the subelements is the same, then
217
+ # the values will be merged using #concat.
218
+ #
219
+ # a = [ [:a,1,2], [:a,3], [:a,4], [:a], :a ]
220
+ # a.to_h_multi #=> { :a=>[1,2,3,4,nil,nil] }
221
+ #
222
+ def to_h_multi
223
+ h = {}
224
+ each do |k,*v|
225
+ h[k] ||= []
226
+ h[k].concat(v)
32
227
  end
33
228
  h
34
229
  end
35
230
 
231
+ #def to_h_multi
232
+ # inject({}) {|h,a| h[a.first] = a[1..-1]; h}
233
+ #end
234
+
235
+ # Is this a good idea?
36
236
  #def to_hash
37
237
  # h = {}
38
238
  # each_with_index do |v, i|
@@ -62,8 +262,8 @@ module Enumerable
62
262
  #
63
263
  # CREDIT: Trans
64
264
 
65
- def to_h(arrayed=nil)
66
- to_a.to_h(arrayed)
265
+ def to_h(mode=nil)
266
+ to_a.to_h(mode)
67
267
  end
68
268
 
69
269
  #def to_hash
@@ -85,3 +285,60 @@ class NilClass
85
285
 
86
286
  end
87
287
 
288
+
289
+ if RUBY_VERSION < "1.9"
290
+
291
+ class Enumerable::Enumerator
292
+
293
+ # Convert an Enumerable::Enumerator object directly into a hash.
294
+ #
295
+ # e = [1,2,3,4,5].to_enum
296
+ # e.to_h #=> {5=>nil, 1=>2, 3=>4}
297
+ # e2 = [1,2,1,3,1,5].to_enum
298
+ # e2.to_h #=> {1=>5}
299
+ # e3 = [[1,:a],[2,:b],[3,:c]].to_enum
300
+ # e3.to_h #=> { 1=>:a, 2=>:b, 3=>:c }
301
+ #
302
+ # CREDIT: Sandor Szücs
303
+
304
+ def to_h(mode=nil)
305
+ to_a.to_h(mode)
306
+ end
307
+ end
308
+
309
+ else
310
+
311
+ class Enumerator
312
+
313
+ # Convert an Enumerator object directly into a hash.
314
+ #
315
+ # e3 = [[1,:a],[2,:b],[3,:c]].to_enum
316
+ # e3.to_h #=> { 1=>:a, 2=>:b, 3=>:c }
317
+ #
318
+ # e1 = [1,2,3,4,5].to_enum
319
+ # e1.to_h #=> {5=>nil, 1=>2, 3=>4}
320
+ #
321
+ # e2 = [1,2,1,3,1,5].to_enum
322
+ # e2.to_h #=> {1=>5}
323
+ #
324
+ #
325
+ # CREDIT: Sandor Szücs
326
+
327
+ def to_h(mode=nil)
328
+ to_a.to_h(mode)
329
+ end
330
+
331
+ #def to_h
332
+ # h = {}
333
+ # loop do
334
+ # x,y = self.next
335
+ # h[x] ||= nil
336
+ # y = self.next unless y
337
+ # h[x] = y
338
+ # end
339
+ # return h
340
+ #end
341
+ end
342
+
343
+ end
344
+
@@ -1,9 +1,11 @@
1
- unless (RUBY_VERSION[0,3] == '1.9')
1
+ if RUBY_VERSION < '1.9'
2
2
 
3
3
  class UnboundMethod
4
4
 
5
5
  # Return the name of the method.
6
- # Is this already in 1.9+ ?
6
+ #
7
+ # Be aware that in ruby 1.9 UnboundMethod#name is defined already,
8
+ # but it returns a Symbol not a String.
7
9
  #
8
10
  # class X
9
11
  # def foo; end
@@ -125,6 +125,7 @@ class OpenStruct
125
125
  def instance_delegate
126
126
  @table
127
127
  end
128
+
128
129
  alias ostruct_delegate instance_delegate
129
130
 
130
131
  # Insert/update hash data on the fly.
@@ -134,6 +135,7 @@ class OpenStruct
134
135
  # o.a #=> 2
135
136
  #
136
137
  def ostruct_update(other)
138
+ raise TypeError, "can't modify frozen #{self.class}", caller(1) if self.frozen?
137
139
  #other = other.to_hash #to_h ?
138
140
  for k,v in other
139
141
  @table[k.to_sym] = v
@@ -166,6 +168,7 @@ class OpenStruct
166
168
  # o.a #=> 2
167
169
  #
168
170
  def __update__(other)
171
+ raise TypeError, "can't modify frozen #{self.class}", caller(1) if self.frozen?
169
172
  #other = other.to_hash #to_h?
170
173
  for k,v in other
171
174
  @table[k.to_sym] = v
@@ -96,19 +96,40 @@
96
96
  # IPAddr
97
97
  # Process::Status
98
98
  #
99
- class Association
99
+ # TODO: Should associations be singleton?
100
100
 
101
+ class Association
101
102
  include Comparable
102
103
 
103
- attr_accessor :index, :value
104
+ class << self
105
+ # Store association references.
106
+ def reference
107
+ @reference ||= Hash.new{ |h,k,v| h[k]=[] }
108
+ end
109
+
110
+ def [](index, value)
111
+ new(index, value)
112
+ end
113
+
114
+ #def new(index, value)
115
+ # lookup[[index, value]] ||= new(index, value)
116
+ #end
104
117
 
105
- def self.[](*args)
106
- new(*args)
118
+ #def lookup
119
+ # @lookup ||= {}
120
+ #end
107
121
  end
108
122
 
123
+ attr_accessor :index
124
+ attr_accessor :value
125
+
109
126
  def initialize(index, value=nil)
110
127
  @index = index
111
128
  @value = value
129
+
130
+ unless index.associations.include?(value)
131
+ index.associations << value
132
+ end
112
133
  end
113
134
 
114
135
  def <=>(assoc)
@@ -135,22 +156,17 @@ class Association
135
156
  [ @index, @value ]
136
157
  end
137
158
 
138
- # Store association references.
139
-
140
- REFERENCE = Hash.new{ |h,k,v| h[k]=[] }
141
-
142
159
  # Object extensions.
143
-
160
+ #
144
161
  module Kernel
145
162
 
146
163
  # Define an association with +self+.
147
164
  def >>(to)
148
- REFERENCE[self] << to
149
165
  Association.new(self, to)
150
166
  end
151
167
 
152
168
  def associations
153
- REFERENCE[self]
169
+ Association.reference[self]
154
170
  end
155
171
 
156
172
  end
@@ -163,7 +179,7 @@ end
163
179
 
164
180
 
165
181
  #--
166
- # Setup the >> method in classes that use it already.
182
+ # Setup the >> method in classes that use it already.
167
183
  #
168
184
  # This is a bad idea b/c it can cause backward compability issues.
169
185
  #