fuby 0.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.
Files changed (222) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +29 -0
  7. data/Rakefile +8 -0
  8. data/VERSION +1 -0
  9. data/fuby.gemspec +21 -0
  10. data/lib/fuby.rb +1 -0
  11. data/lib/fuby/abbreviation.rb +20 -0
  12. data/lib/fuby/alias_method.rb +13 -0
  13. data/lib/fuby/all.rb +11 -0
  14. data/lib/fuby/and.rb +9 -0
  15. data/lib/fuby/any.rb +11 -0
  16. data/lib/fuby/attributes.rb +17 -0
  17. data/lib/fuby/bind.rb +21 -0
  18. data/lib/fuby/class_attributes.rb +39 -0
  19. data/lib/fuby/deep.rb +1 -0
  20. data/lib/fuby/deep_each.rb +14 -0
  21. data/lib/fuby/define_instance_method.rb +18 -0
  22. data/lib/fuby/define_missing_method.rb +36 -0
  23. data/lib/fuby/define_object_method.rb +18 -0
  24. data/lib/fuby/define_tok.rb +11 -0
  25. data/lib/fuby/descendants.rb +15 -0
  26. data/lib/fuby/dimension.rb +23 -0
  27. data/lib/fuby/drop.rb +20 -0
  28. data/lib/fuby/drop_until.rb +18 -0
  29. data/lib/fuby/drop_while.rb +15 -0
  30. data/lib/fuby/each.rb +2 -0
  31. data/lib/fuby/each_with_index_or_key.rb +19 -0
  32. data/lib/fuby/eql.rb +1 -0
  33. data/lib/fuby/eql_componentwise.rb +13 -0
  34. data/lib/fuby/equivalence.rb +13 -0
  35. data/lib/fuby/eval.rb +54 -0
  36. data/lib/fuby/extend.rb +13 -0
  37. data/lib/fuby/format.rb +9 -0
  38. data/lib/fuby/include.rb +13 -0
  39. data/lib/fuby/index_or_key.rb +19 -0
  40. data/lib/fuby/instance_attributes.rb +39 -0
  41. data/lib/fuby/intercept.rb +27 -0
  42. data/lib/fuby/invert.rb +16 -0
  43. data/lib/fuby/longest_common.rb +16 -0
  44. data/lib/fuby/matches.rb +11 -0
  45. data/lib/fuby/matches_componentwise.rb +11 -0
  46. data/lib/fuby/matches_part_of.rb +16 -0
  47. data/lib/fuby/matches_prefix_of.rb +11 -0
  48. data/lib/fuby/matches_suffix_of.rb +13 -0
  49. data/lib/fuby/member.rb +11 -0
  50. data/lib/fuby/merge.rb +20 -0
  51. data/lib/fuby/merge_css.rb +32 -0
  52. data/lib/fuby/method_added_as.rb +1 -0
  53. data/lib/fuby/method_added_as_binary_operator.rb +16 -0
  54. data/lib/fuby/method_added_as_filter.rb +19 -0
  55. data/lib/fuby/new.rb +16 -0
  56. data/lib/fuby/not.rb +25 -0
  57. data/lib/fuby/opposite.rb +29 -0
  58. data/lib/fuby/or.rb +9 -0
  59. data/lib/fuby/otherwise.rb +18 -0
  60. data/lib/fuby/part_of.rb +16 -0
  61. data/lib/fuby/plus.rb +10 -0
  62. data/lib/fuby/pop.rb +11 -0
  63. data/lib/fuby/pop_if.rb +15 -0
  64. data/lib/fuby/pop_options.rb +15 -0
  65. data/lib/fuby/pop_unless.rb +11 -0
  66. data/lib/fuby/pop_until.rb +11 -0
  67. data/lib/fuby/pop_while.rb +11 -0
  68. data/lib/fuby/prefix_of.rb +14 -0
  69. data/lib/fuby/prefixes.rb +11 -0
  70. data/lib/fuby/prepend.rb +11 -0
  71. data/lib/fuby/private.rb +11 -0
  72. data/lib/fuby/protected.rb +11 -0
  73. data/lib/fuby/public.rb +11 -0
  74. data/lib/fuby/push.rb +1 -0
  75. data/lib/fuby/push_options.rb +9 -0
  76. data/lib/fuby/random.rb +31 -0
  77. data/lib/fuby/self_and_descendants.rb +15 -0
  78. data/lib/fuby/shift.rb +11 -0
  79. data/lib/fuby/shift_if.rb +12 -0
  80. data/lib/fuby/shift_options.rb +11 -0
  81. data/lib/fuby/shift_unless.rb +12 -0
  82. data/lib/fuby/shift_until.rb +12 -0
  83. data/lib/fuby/shift_while.rb +16 -0
  84. data/lib/fuby/splat.rb +11 -0
  85. data/lib/fuby/strip.rb +24 -0
  86. data/lib/fuby/subclass.rb +22 -0
  87. data/lib/fuby/submodule.rb +22 -0
  88. data/lib/fuby/suffix_of.rb +19 -0
  89. data/lib/fuby/suffixes.rb +11 -0
  90. data/lib/fuby/take.rb +20 -0
  91. data/lib/fuby/take_until.rb +17 -0
  92. data/lib/fuby/take_while.rb +14 -0
  93. data/lib/fuby/tap.rb +28 -0
  94. data/lib/fuby/to.rb +1 -0
  95. data/lib/fuby/to_boolean.rb +32 -0
  96. data/lib/fuby/to_camel_case.rb +32 -0
  97. data/lib/fuby/to_case.rb +1 -0
  98. data/lib/fuby/to_components.rb +33 -0
  99. data/lib/fuby/to_dash_case.rb +28 -0
  100. data/lib/fuby/to_hash.rb +25 -0
  101. data/lib/fuby/to_pred.rb +7 -0
  102. data/lib/fuby/to_proc.rb +45 -0
  103. data/lib/fuby/to_regexp.rb +38 -0
  104. data/lib/fuby/to_snake_case.rb +28 -0
  105. data/lib/fuby/to_tok.rb +27 -0
  106. data/lib/fuby/tok.rb +2 -0
  107. data/lib/fuby/tok_arity.rb +18 -0
  108. data/lib/fuby/tok_direction.rb +16 -0
  109. data/lib/fuby/tok_parity.rb +11 -0
  110. data/lib/fuby/tok_side.rb +11 -0
  111. data/lib/fuby/try.rb +73 -0
  112. data/lib/fuby/try_each.rb +25 -0
  113. data/lib/fuby/try_eval.rb +19 -0
  114. data/lib/fuby/try_exec.rb +15 -0
  115. data/lib/fuby/unabbreviation.rb +17 -0
  116. data/lib/fuby/unshift.rb +1 -0
  117. data/lib/fuby/unshift_options.rb +11 -0
  118. data/lib/fuby/uuid.rb +28 -0
  119. data/test/fuby/abbreviation.rb +25 -0
  120. data/test/fuby/alias_method.rb +29 -0
  121. data/test/fuby/all.rb +15 -0
  122. data/test/fuby/and.rb +14 -0
  123. data/test/fuby/any.rb +15 -0
  124. data/test/fuby/attributes.rb +0 -0
  125. data/test/fuby/bind.rb +17 -0
  126. data/test/fuby/class_attributes.rb +0 -0
  127. data/test/fuby/deep.rb +0 -0
  128. data/test/fuby/deep_each.rb +0 -0
  129. data/test/fuby/define_missing_method.rb +33 -0
  130. data/test/fuby/define_tok.rb +0 -0
  131. data/test/fuby/descendants.rb +0 -0
  132. data/test/fuby/dimension.rb +0 -0
  133. data/test/fuby/drop.rb +28 -0
  134. data/test/fuby/drop_until.rb +26 -0
  135. data/test/fuby/drop_while.rb +26 -0
  136. data/test/fuby/each.rb +0 -0
  137. data/test/fuby/each_with_index_or_key.rb +22 -0
  138. data/test/fuby/eql.rb +0 -0
  139. data/test/fuby/eql_componentwise.rb +0 -0
  140. data/test/fuby/equivalence.rb +0 -0
  141. data/test/fuby/eval.rb +0 -0
  142. data/test/fuby/extend.rb +20 -0
  143. data/test/fuby/format.rb +0 -0
  144. data/test/fuby/include.rb +20 -0
  145. data/test/fuby/index_or_key.rb +0 -0
  146. data/test/fuby/instance_attributes.rb +0 -0
  147. data/test/fuby/intercept.rb +16 -0
  148. data/test/fuby/invert.rb +0 -0
  149. data/test/fuby/longest_common.rb +0 -0
  150. data/test/fuby/matches.rb +0 -0
  151. data/test/fuby/matches_componentwise.rb +0 -0
  152. data/test/fuby/matches_prefix_of.rb +0 -0
  153. data/test/fuby/matches_suffix_of.rb +0 -0
  154. data/test/fuby/member.rb +0 -0
  155. data/test/fuby/merge.rb +0 -0
  156. data/test/fuby/merge_css.rb +0 -0
  157. data/test/fuby/method_added_as.rb +0 -0
  158. data/test/fuby/method_added_as_binary_operator.rb +20 -0
  159. data/test/fuby/method_added_as_filter.rb +28 -0
  160. data/test/fuby/new.rb +3 -0
  161. data/test/fuby/not.rb +0 -0
  162. data/test/fuby/opposite.rb +0 -0
  163. data/test/fuby/or.rb +19 -0
  164. data/test/fuby/otherwise.rb +30 -0
  165. data/test/fuby/part_of.rb +0 -0
  166. data/test/fuby/plus.rb +0 -0
  167. data/test/fuby/pop.rb +0 -0
  168. data/test/fuby/pop_if.rb +31 -0
  169. data/test/fuby/pop_options.rb +31 -0
  170. data/test/fuby/pop_unless.rb +0 -0
  171. data/test/fuby/pop_until.rb +0 -0
  172. data/test/fuby/pop_while.rb +0 -0
  173. data/test/fuby/prefix_of.rb +0 -0
  174. data/test/fuby/prefixes.rb +13 -0
  175. data/test/fuby/prepend.rb +34 -0
  176. data/test/fuby/private.rb +0 -0
  177. data/test/fuby/protected.rb +0 -0
  178. data/test/fuby/public.rb +0 -0
  179. data/test/fuby/push.rb +0 -0
  180. data/test/fuby/push_options.rb +32 -0
  181. data/test/fuby/random.rb +0 -0
  182. data/test/fuby/self_and_descendants.rb +0 -0
  183. data/test/fuby/shift.rb +0 -0
  184. data/test/fuby/shift_if.rb +0 -0
  185. data/test/fuby/shift_options.rb +0 -0
  186. data/test/fuby/shift_unless.rb +0 -0
  187. data/test/fuby/shift_until.rb +0 -0
  188. data/test/fuby/shift_while.rb +0 -0
  189. data/test/fuby/splat.rb +0 -0
  190. data/test/fuby/strip.rb +0 -0
  191. data/test/fuby/submodule.rb +15 -0
  192. data/test/fuby/suffix_of.rb +0 -0
  193. data/test/fuby/suffixes.rb +13 -0
  194. data/test/fuby/take.rb +0 -0
  195. data/test/fuby/take_until.rb +0 -0
  196. data/test/fuby/take_while.rb +0 -0
  197. data/test/fuby/tap.rb +58 -0
  198. data/test/fuby/to_boolean.rb +31 -0
  199. data/test/fuby/to_camel_case.rb +15 -0
  200. data/test/fuby/to_components.rb +0 -0
  201. data/test/fuby/to_dash_case.rb +15 -0
  202. data/test/fuby/to_hash.rb +23 -0
  203. data/test/fuby/to_pred.rb +25 -0
  204. data/test/fuby/to_proc.rb +56 -0
  205. data/test/fuby/to_regexp.rb +38 -0
  206. data/test/fuby/to_snake_case.rb +15 -0
  207. data/test/fuby/to_tok.rb +0 -0
  208. data/test/fuby/tok.rb +0 -0
  209. data/test/fuby/tok_arity.rb +0 -0
  210. data/test/fuby/tok_direction.rb +0 -0
  211. data/test/fuby/tok_parity.rb +0 -0
  212. data/test/fuby/tok_side.rb +0 -0
  213. data/test/fuby/try.rb +52 -0
  214. data/test/fuby/try_each.rb +30 -0
  215. data/test/fuby/try_eval.rb +34 -0
  216. data/test/fuby/try_exec.rb +0 -0
  217. data/test/fuby/unabbreviation.rb +25 -0
  218. data/test/fuby/unshift.rb +0 -0
  219. data/test/fuby/unshift_options.rb +0 -0
  220. data/test/fuby/uuid.rb +31 -0
  221. data/test/fuby/version.rb +0 -0
  222. metadata +369 -0
@@ -0,0 +1,18 @@
1
+ require_relative 'method_added_as_filter'
2
+
3
+ using Fuby
4
+
5
+ module Fuby
6
+ refine ::Array do
7
+
8
+ def drop_until &blk
9
+ drop_while &blk.not
10
+ end
11
+
12
+ def drop_until! &blk
13
+ drop_while! &blk.not
14
+ end
15
+
16
+ method_added_as_filter :drop_until, :drop_until!
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'shift_while'
2
+
3
+ using Fuby
4
+
5
+ module Fuby
6
+ refine ::Array do
7
+
8
+ def drop_while! &blk
9
+ shift_while &blk
10
+ self
11
+ end
12
+
13
+ method_added_as_filter :drop_while, :drop_while!
14
+ end
15
+ end
data/lib/fuby/each.rb ADDED
@@ -0,0 +1,2 @@
1
+ Dir.glob "each_*.rb", &method(:require)
2
+ Dir.glob "*_each.rb", &method(:require)
@@ -0,0 +1,19 @@
1
+ using Fuby
2
+
3
+ module Fuby
4
+ refine ::Hash do
5
+
6
+ def each_with_index_or_key
7
+ return each { |key, val| yield val, key } if block_given?
8
+ return ::Enumerator.new { |result| each { |key, val| result.<< val, key } }
9
+ end
10
+
11
+ end
12
+ refine ::Array do
13
+
14
+ def each_with_index_or_key *sig, &blk
15
+ each_with_index *sig, &blk
16
+ end
17
+
18
+ end
19
+ end
data/lib/fuby/eql.rb ADDED
@@ -0,0 +1 @@
1
+ Dir.glob "#{ __FILE__.chomp ".rb" }_*.rb", &method(:require)
@@ -0,0 +1,13 @@
1
+ require_relative 'each_with_index_or_key'
2
+
3
+ using Fuby
4
+
5
+ module Fuby
6
+ module ::Enumerable # can't refine Module
7
+
8
+ def eql_componentwise? that
9
+ each_with_index_or_key.all? { |e, k| e == that[k] }
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'splat'
2
+
3
+ using Fuby
4
+
5
+ module Fuby
6
+ module ::Enumerable # can't refine Module
7
+
8
+ def equivalence? eq = :eql?
9
+ each_cons(2).splat.all? { |fst, snd| fst.send eq, snd }
10
+ end
11
+
12
+ end
13
+ end
data/lib/fuby/eval.rb ADDED
@@ -0,0 +1,54 @@
1
+ require_relative 'intercept'
2
+
3
+ module Fuby
4
+
5
+ refine ::Hash do
6
+
7
+ def hash_eval &body
8
+ intercept do |key, *sig, &blk|
9
+ val = self[key]
10
+ key = key.to_s.chomp!("!").to_sym and self.delete key if /!$/ === key.to_s
11
+
12
+ case sig
13
+ when [] then sig.unshift ({}) if blk
14
+ when [Object]
15
+ else raise ::ArgumentError
16
+ end
17
+
18
+ case arg = sig.first
19
+ when nil then next val
20
+ when ::Hash
21
+ self[key] = {} if self[key].nil?
22
+ self[key].merge! arg
23
+ self[key].hash_exec &blk if blk
24
+ else
25
+ self[key] = arg
26
+ end
27
+
28
+ self[key]
29
+ end.instance_exec &body
30
+ end
31
+
32
+ alias_method :hash_exec, :hash_eval
33
+
34
+ end
35
+
36
+ refine ::Object do
37
+
38
+ def curry_eval *pre, &shell
39
+
40
+ if Hash === pre.last
41
+ defaults = pre.pop
42
+ intercept { |*sig, &blk| send *pre, sig, (sig.pop_options defaults), &blk }
43
+
44
+ else
45
+ intercept { |*sig, &blk| send *pre, &blk }
46
+
47
+ end.instance_exec self, &shell
48
+ end
49
+
50
+ alias_method :curry_exec, :curry_eval
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,13 @@
1
+ using Fuby
2
+
3
+ module Fuby
4
+ refine ::Object do
5
+
6
+ def extend! *extends, &body
7
+ extend *extends unless extends.empty?
8
+ extend ::Module.new(&body) if block_given?
9
+ self
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Fuby
2
+ refine ::Symbol do
3
+
4
+ def % format
5
+ (to_s % format).to_sym
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ using Fuby
2
+
3
+ module Fuby
4
+ refine ::Module do
5
+
6
+ def include! *includes, &body
7
+ include *includes unless includes.empty?
8
+ include ::Module.new(&body) if block_given?
9
+ self
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Fuby
2
+
3
+ refine ::Array do
4
+
5
+ def index_or_key
6
+ index
7
+ end
8
+
9
+ end
10
+
11
+ refine ::Hash do
12
+
13
+ def index_or_key
14
+ key
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'attributes'
2
+
3
+ using Fuby
4
+
5
+ module Fuby
6
+ refine ::Object do
7
+
8
+ def instance_attribute_set key, val
9
+ (respond_to? "#{ key }=") ? (send "#{ key }=", val) : (instance_variable_set "@{ key }", val)
10
+ end
11
+
12
+ def instance_attribute_get key
13
+ (respond_to? key) ? (send key) : (instance_variable_get "@#{ key }")
14
+ end
15
+
16
+ def instance_attributes_set opt
17
+ opt.each { |key, val| instance_attribute_set key, val }
18
+ self
19
+ end
20
+
21
+ def instance_attributes_get key
22
+ keys.map &(method :instance_attribute_get)
23
+ end
24
+
25
+ alias_method :instance_attributes_at, :instance_attributes_get
26
+
27
+ def instance_attributes
28
+ InstanceAttributes.new self
29
+ end
30
+
31
+ end
32
+ class InstanceAttributes < Attributes
33
+
34
+ def __name__
35
+ :instance_attributes
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'bind'
2
+ require_relative 'define_missing_method'
3
+
4
+ using Fuby
5
+
6
+ module Fuby
7
+
8
+ refine ::Object do
9
+
10
+ def intercept &intercept
11
+ Intercept.new self, &intercept
12
+ end
13
+
14
+ end
15
+
16
+ class Intercept < BasicObject
17
+
18
+ def initialize intercepted, &intercept
19
+ @intercept = intercept.bind intercepted
20
+ end
21
+
22
+ def method_missing *sig, &blk
23
+ @intercept.call *sig, &blk
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'self_and_descendants'
2
+ require_relative 'each_with_index_or_key'
3
+
4
+ using Fuby
5
+
6
+ module Fuby
7
+
8
+ module ::Enumerable # can't refine Module
9
+
10
+ def invert
11
+ ::Hash[ each_with_index_or_key.to_a ]
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'equivalence'
2
+ using Fuby
3
+
4
+ module Fuby
5
+ module ::Enumerable # can't refine Module
6
+
7
+ def longest_common_prefix *those
8
+ zip(*those).take_while(:equivalence?).map(:first)
9
+ end
10
+
11
+ def longest_common_suffix *those
12
+ zip(*those).map(&:reverse).take_while(:equivalence?).map(:first).map(&:reverse)
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Fuby
2
+ module ::Enumerable # can't refine Module
3
+
4
+ def matches? that
5
+ count == that.count and matches_componentwise? that
6
+ end
7
+
8
+ end
9
+ end
10
+
11
+ Dir.glob "#{ __FILE__.chomp ".rb" }_*.rb", &method(:require)
@@ -0,0 +1,11 @@
1
+ require_relative 'each_with_index_or_key'
2
+
3
+ module Fuby
4
+ module ::Enumerable # can't refine Module
5
+
6
+ def matches_componentwise? that
7
+ each_with_index_or_key.all? { |e, k| e === that[k] }
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'method_added_as_binary_operator'
2
+ require_relative 'matches_componentwise'
3
+
4
+ using Fuby
5
+
6
+ module Fuby
7
+ module ::Enumerable # can't refine Module
8
+
9
+ def matches_part_of? that
10
+ count <= that.count and matches_componentwise? that
11
+ end
12
+
13
+ method_added_as_binary_operator :matches_part_of?
14
+
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'matches_part_of'
2
+
3
+ module Fuby
4
+ refine ::Array do
5
+
6
+ alias_method :matches_prefix_of?, :matches_part_of?
7
+
8
+ method_added_as_binary_operator :matches_prefix_of?
9
+
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ using Fuby
2
+
3
+ module Fuby
4
+ refine ::Array do
5
+
6
+ def matches_suffix_of? that
7
+ matches? that.drop - length
8
+ end
9
+
10
+ method_added_as_binary_operator :matches_suffix_of?
11
+
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'method_added_as_binary_operator'
2
+
3
+ using Fuby
4
+
5
+ module Fuby
6
+ module ::Enumerable # can't refine Module
7
+
8
+ method_added_as_binary_operator :member?, :include?
9
+
10
+ end
11
+ end
data/lib/fuby/merge.rb ADDED
@@ -0,0 +1,20 @@
1
+ module Fuby
2
+ refine ::Hash do
3
+
4
+ [ :'', :'!' ].each { |i| eval %{
5
+
6
+ def merge#{ i } that = self, key = nil, &blk
7
+ case key
8
+ when nil
9
+ when Symbol then return send merge_\#{ key }#{ i } that, &blk if respond_to? merge_\#{ key }#{ i }
10
+ else raise ArgumentError
11
+ end
12
+ return super
13
+ end
14
+
15
+ }}
16
+
17
+ end
18
+ end
19
+
20
+ Dir.glob "#{ __FILE__.chomp ".rb" }_*.rb", &method(:require)
@@ -0,0 +1,32 @@
1
+ module Fuby
2
+ refine ::Hash do
3
+
4
+ def merge_css that
5
+ dup.merge_css! that
6
+ end
7
+
8
+ def merge_css! that
9
+ merge! that do |key, lft, rgt|
10
+ case key
11
+ when /^class$/ then "#{ lft } #{ rgt }"
12
+ when /^style$/ then "#{ lft };#{ rgt }"
13
+ else rgt
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ module MergeCSS
21
+
22
+ def merge_css *hashes
23
+ hashes.inject ({}) do |memo, hash|
24
+ memo.merge_css! hash
25
+ end.tap do |hash|
26
+ hash.each { |key, val| hash.merge_css! val if send k if respond_to? k if /\?$/ === key }
27
+ hash.each { |key, val| hash.merge! val if send k.to_? if respond_to? k.to_? if /\!$/ === key }
28
+ end
29
+ end
30
+
31
+ end
32
+ end