garcun 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +17 -0
  3. data/.gitignore +197 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +22 -0
  6. data/LICENSE +201 -0
  7. data/README.md +521 -0
  8. data/Rakefile +47 -0
  9. data/garcun.gemspec +83 -0
  10. data/lib/garcon.rb +290 -0
  11. data/lib/garcon/chef/chef_helpers.rb +343 -0
  12. data/lib/garcon/chef/coerce/coercer.rb +134 -0
  13. data/lib/garcon/chef/coerce/coercions/boolean_definitions.rb +34 -0
  14. data/lib/garcon/chef/coerce/coercions/date_definitions.rb +32 -0
  15. data/lib/garcon/chef/coerce/coercions/date_time_definitions.rb +32 -0
  16. data/lib/garcon/chef/coerce/coercions/fixnum_definitions.rb +34 -0
  17. data/lib/garcon/chef/coerce/coercions/float_definitions.rb +32 -0
  18. data/lib/garcon/chef/coerce/coercions/hash_definitions.rb +29 -0
  19. data/lib/garcon/chef/coerce/coercions/integer_definitions.rb +31 -0
  20. data/lib/garcon/chef/coerce/coercions/string_definitions.rb +45 -0
  21. data/lib/garcon/chef/coerce/coercions/time_definitions.rb +32 -0
  22. data/lib/garcon/chef/handler/devreporter.rb +127 -0
  23. data/lib/garcon/chef/log.rb +64 -0
  24. data/lib/garcon/chef/node.rb +100 -0
  25. data/lib/garcon/chef/provider/civilize.rb +209 -0
  26. data/lib/garcon/chef/provider/development.rb +159 -0
  27. data/lib/garcon/chef/provider/download.rb +420 -0
  28. data/lib/garcon/chef/provider/house_keeping.rb +265 -0
  29. data/lib/garcon/chef/provider/node_cache.rb +31 -0
  30. data/lib/garcon/chef/provider/partial.rb +183 -0
  31. data/lib/garcon/chef/provider/recovery.rb +80 -0
  32. data/lib/garcon/chef/provider/zip_file.rb +271 -0
  33. data/lib/garcon/chef/resource/attribute.rb +52 -0
  34. data/lib/garcon/chef/resource/base_dsl.rb +174 -0
  35. data/lib/garcon/chef/resource/blender.rb +140 -0
  36. data/lib/garcon/chef/resource/lazy_eval.rb +66 -0
  37. data/lib/garcon/chef/resource/resource_name.rb +109 -0
  38. data/lib/garcon/chef/secret_bag.rb +204 -0
  39. data/lib/garcon/chef/validations.rb +76 -0
  40. data/lib/garcon/chef_inclusions.rb +151 -0
  41. data/lib/garcon/configuration.rb +138 -0
  42. data/lib/garcon/core_ext.rb +39 -0
  43. data/lib/garcon/core_ext/array.rb +27 -0
  44. data/lib/garcon/core_ext/binding.rb +64 -0
  45. data/lib/garcon/core_ext/boolean.rb +66 -0
  46. data/lib/garcon/core_ext/duration.rb +271 -0
  47. data/lib/garcon/core_ext/enumerable.rb +34 -0
  48. data/lib/garcon/core_ext/file.rb +127 -0
  49. data/lib/garcon/core_ext/filetest.rb +62 -0
  50. data/lib/garcon/core_ext/hash.rb +279 -0
  51. data/lib/garcon/core_ext/kernel.rb +159 -0
  52. data/lib/garcon/core_ext/lazy.rb +222 -0
  53. data/lib/garcon/core_ext/method_access.rb +243 -0
  54. data/lib/garcon/core_ext/module.rb +92 -0
  55. data/lib/garcon/core_ext/nil.rb +53 -0
  56. data/lib/garcon/core_ext/numeric.rb +44 -0
  57. data/lib/garcon/core_ext/object.rb +342 -0
  58. data/lib/garcon/core_ext/pathname.rb +152 -0
  59. data/lib/garcon/core_ext/process.rb +41 -0
  60. data/lib/garcon/core_ext/random.rb +497 -0
  61. data/lib/garcon/core_ext/string.rb +312 -0
  62. data/lib/garcon/core_ext/struct.rb +49 -0
  63. data/lib/garcon/core_ext/symbol.rb +170 -0
  64. data/lib/garcon/core_ext/time.rb +234 -0
  65. data/lib/garcon/exceptions.rb +101 -0
  66. data/lib/garcon/inflections.rb +237 -0
  67. data/lib/garcon/inflections/defaults.rb +79 -0
  68. data/lib/garcon/inflections/inflections.rb +182 -0
  69. data/lib/garcon/inflections/rules_collection.rb +37 -0
  70. data/lib/garcon/secret.rb +271 -0
  71. data/lib/garcon/stash/format.rb +114 -0
  72. data/lib/garcon/stash/journal.rb +226 -0
  73. data/lib/garcon/stash/queue.rb +83 -0
  74. data/lib/garcon/stash/serializer.rb +86 -0
  75. data/lib/garcon/stash/store.rb +435 -0
  76. data/lib/garcon/task.rb +31 -0
  77. data/lib/garcon/task/atomic.rb +151 -0
  78. data/lib/garcon/task/atomic_boolean.rb +127 -0
  79. data/lib/garcon/task/condition.rb +99 -0
  80. data/lib/garcon/task/copy_on_notify_observer_set.rb +154 -0
  81. data/lib/garcon/task/copy_on_write_observer_set.rb +153 -0
  82. data/lib/garcon/task/count_down_latch.rb +92 -0
  83. data/lib/garcon/task/delay.rb +196 -0
  84. data/lib/garcon/task/dereferenceable.rb +144 -0
  85. data/lib/garcon/task/event.rb +119 -0
  86. data/lib/garcon/task/executor.rb +275 -0
  87. data/lib/garcon/task/executor_options.rb +59 -0
  88. data/lib/garcon/task/future.rb +107 -0
  89. data/lib/garcon/task/immediate_executor.rb +84 -0
  90. data/lib/garcon/task/ivar.rb +171 -0
  91. data/lib/garcon/task/lazy_reference.rb +74 -0
  92. data/lib/garcon/task/monotonic_time.rb +69 -0
  93. data/lib/garcon/task/obligation.rb +256 -0
  94. data/lib/garcon/task/observable.rb +101 -0
  95. data/lib/garcon/task/priority_queue.rb +234 -0
  96. data/lib/garcon/task/processor_count.rb +128 -0
  97. data/lib/garcon/task/read_write_lock.rb +304 -0
  98. data/lib/garcon/task/safe_task_executor.rb +58 -0
  99. data/lib/garcon/task/single_thread_executor.rb +97 -0
  100. data/lib/garcon/task/thread_pool/cached.rb +71 -0
  101. data/lib/garcon/task/thread_pool/executor.rb +294 -0
  102. data/lib/garcon/task/thread_pool/fixed.rb +61 -0
  103. data/lib/garcon/task/thread_pool/worker.rb +90 -0
  104. data/lib/garcon/task/timer.rb +44 -0
  105. data/lib/garcon/task/timer_set.rb +194 -0
  106. data/lib/garcon/task/timer_task.rb +377 -0
  107. data/lib/garcon/task/waitable_list.rb +58 -0
  108. data/lib/garcon/utility/ansi.rb +199 -0
  109. data/lib/garcon/utility/at_random.rb +77 -0
  110. data/lib/garcon/utility/crypto.rb +292 -0
  111. data/lib/garcon/utility/equalizer.rb +146 -0
  112. data/lib/garcon/utility/faker/extensions/array.rb +22 -0
  113. data/lib/garcon/utility/faker/extensions/symbol.rb +9 -0
  114. data/lib/garcon/utility/faker/faker.rb +164 -0
  115. data/lib/garcon/utility/faker/faker/company.rb +17 -0
  116. data/lib/garcon/utility/faker/faker/hacker.rb +30 -0
  117. data/lib/garcon/utility/faker/faker/version.rb +3 -0
  118. data/lib/garcon/utility/faker/locales/en-US.yml +83 -0
  119. data/lib/garcon/utility/faker/locales/en.yml +21 -0
  120. data/lib/garcon/utility/file_helper.rb +170 -0
  121. data/lib/garcon/utility/hookers.rb +178 -0
  122. data/lib/garcon/utility/interpolation.rb +90 -0
  123. data/lib/garcon/utility/memstash.rb +364 -0
  124. data/lib/garcon/utility/misc.rb +54 -0
  125. data/lib/garcon/utility/msg_from_god.rb +62 -0
  126. data/lib/garcon/utility/retry.rb +238 -0
  127. data/lib/garcon/utility/timeout.rb +58 -0
  128. data/lib/garcon/utility/uber/builder.rb +91 -0
  129. data/lib/garcon/utility/uber/callable.rb +7 -0
  130. data/lib/garcon/utility/uber/delegates.rb +13 -0
  131. data/lib/garcon/utility/uber/inheritable_attr.rb +37 -0
  132. data/lib/garcon/utility/uber/options.rb +101 -0
  133. data/lib/garcon/utility/uber/uber_version.rb +3 -0
  134. data/lib/garcon/utility/uber/version.rb +33 -0
  135. data/lib/garcon/utility/url_helper.rb +100 -0
  136. data/lib/garcon/utils.rb +29 -0
  137. data/lib/garcon/version.rb +62 -0
  138. data/lib/garcun.rb +24 -0
  139. metadata +680 -0
@@ -0,0 +1,92 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ class Module
21
+
22
+ # Create an instance of Object and extend it with +self+.
23
+ #
24
+ # mod = Module.new do
25
+ # def foo; "foo"; end
26
+ # end
27
+ #
28
+ # obj = mod.to_obj
29
+ #
30
+ # obj.foo #=> "foo"
31
+ #
32
+ def to_obj
33
+ o = Object.new
34
+ o.extend self
35
+ o
36
+ end
37
+
38
+ # Creates a new method wrapping the previous of the same name.
39
+ # Reference to the old method is passed into the new definition
40
+ # block as the first parameter.
41
+ #
42
+ # class WrapExample
43
+ # def foo
44
+ # "foo"
45
+ # end
46
+ #
47
+ # wrap_method(:foo) do |old_meth, *args|
48
+ # old_meth.call + '!'
49
+ # end
50
+ # end
51
+ #
52
+ # example = WrapExample.new
53
+ # example.foo #=> 'foo!'
54
+ #
55
+ # Keep in mind that this cannot be used to wrap methods
56
+ # that take a block.
57
+ #
58
+ def wrap_method( sym, &blk )
59
+ old = instance_method(sym)
60
+ define_method(sym) { |*args| blk.call(old.bind(self), *args) }
61
+ end
62
+ alias_method :wrap, :wrap_method
63
+
64
+ unless method_defined?(:set)
65
+ # Sets an option to the given value. If the value is a proc,
66
+ # the proc will be called every time the option is accessed.
67
+ #
68
+ def set(option, value=self, &block)
69
+ raise ArgumentError if block && value != self
70
+ value = block if block
71
+ if value.kind_of?(Proc)
72
+ if value.arity == 1
73
+ yield self
74
+ else
75
+ (class << self; self; end).module_eval do
76
+ define_method(option, &value)
77
+ define_method("#{option}?"){ !!__send__(option) }
78
+ define_method("#{option}="){ |val| set(option, Proc.new{val}) }
79
+ end
80
+ end
81
+ elsif value == self
82
+ option.each{ |k,v| set(k, v) }
83
+ elsif respond_to?("#{option}=")
84
+ __send__("#{option}=", value)
85
+ else
86
+ set(option, Proc.new{value})
87
+ end
88
+ self
89
+ end
90
+ end
91
+ end
92
+
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ # Add #blank? method to NilClass class.
21
+ class NilClass
22
+ # Nil is always blank
23
+ #
24
+ # @example
25
+ # nil.blank? # => true
26
+ #
27
+ # @return [TrueClass]
28
+ #
29
+ # @api public
30
+ def blank?
31
+ true
32
+ end
33
+
34
+ # Calling `try` on `nil` always returns `nil`. It becomes especially helpful
35
+ # when navigating through associations that may return `nil`.
36
+ #
37
+ def try(*args)
38
+ nil
39
+ end
40
+
41
+ def try!(*args)
42
+ nil
43
+ end
44
+
45
+ # Since NilClass is immutable it cannot be duplicated.
46
+ # For this reason #try_dup returns +self+.
47
+ #
48
+ # nil.dup! #=> nil
49
+ #
50
+ def dup! ; self ; end
51
+ def dup? ; false ; end
52
+ def clone? ; false ; end
53
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ # Add #blank? method to Numeric class.
21
+ class Numeric
22
+ # Numerics are never blank
23
+ #
24
+ # @example
25
+ # 0.blank? # => false
26
+ # 1.blank? # => false
27
+ # 6.54321.blank? # => false
28
+ #
29
+ # @return [FalseClass]
30
+ #
31
+ # @api public
32
+ def blank?
33
+ false
34
+ end
35
+
36
+ # Since Numeric is immutable it cannot be duplicated.
37
+ # For this reason #try_dup returns +self+.
38
+ #
39
+ # 1.dup! #=> 1
40
+ #
41
+ def dup! ; self ; end
42
+ def dup? ; false ; end
43
+ def clone? ; false ; end
44
+ end
@@ -0,0 +1,342 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+
21
+ # Add #blank?, #present?, #try and #try! methods to Object class.
22
+ class Object
23
+
24
+ # Returns true if the object is nil or empty (if applicable)
25
+ #
26
+ # @example
27
+ # [].blank? # => true
28
+ # [1].blank? # => false
29
+ # [nil].blank? # => false
30
+ #
31
+ # @return [Boolean]
32
+ #
33
+ def blank?
34
+ nil? || (respond_to?(:empty?) && empty?)
35
+ end
36
+
37
+ # Returns true if the object is NOT nil or empty
38
+ #
39
+ # @example
40
+ # [].present? # => false
41
+ # [1].present? # => true
42
+ # [nil].present? # => true
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ def present?
47
+ !blank?
48
+ end
49
+
50
+ # Invokes the public method whose name goes as first argument just like
51
+ # `public_send` does, except that if the receiver does not respond to it the
52
+ # call returns `nil` rather than raising an exception.
53
+ #
54
+ # @note
55
+ # `try` is defined on `Object`. Therefore, it won't work with instances
56
+ # of classes that do not have `Object` among their ancestors, like direct
57
+ # subclasses of `BasicObject`.
58
+ #
59
+ # @param [String] object
60
+ #
61
+ # @param [Symbol] method
62
+ #
63
+ # @return [Object]
64
+ #
65
+ def try(*a, &b)
66
+ try!(*a, &b) if a.empty? || respond_to?(a.first)
67
+ end
68
+
69
+ # Same as #try, but will raise a NoMethodError exception if the receiver is
70
+ # not `nil` and does not implement the tried method.
71
+ #
72
+ # @raise NoMethodError
73
+ # If the receiver is not `nil` and does not implement the tried method.
74
+ #
75
+ # @return [Object]
76
+ #
77
+ def try!(*a, &b)
78
+ if a.empty? && block_given?
79
+ if b.arity.zero?
80
+ instance_eval(&b)
81
+ else
82
+ yield self
83
+ end
84
+ else
85
+ public_send(*a, &b)
86
+ end
87
+ end
88
+
89
+ # If receiver is callable, calls it and returns result. If not, just returns
90
+ # receiver itself.
91
+ #
92
+ # @return [Object]
93
+ #
94
+ def try_call(*args)
95
+ if self.respond_to?(:call)
96
+ self.call(*args)
97
+ else
98
+ self
99
+ end
100
+ end
101
+
102
+ # An identity method that provides access to an object's 'self'.
103
+ #
104
+ # Example
105
+ # [1,2,3,4,5,1,2,2,3].group_by(&:itself)
106
+ # #=> {1=>[1, 1], 2=>[2, 2, 2], 3=>[3, 3], 4=>[4], 5=>[5]}
107
+ #
108
+ def itself
109
+ self
110
+ end
111
+
112
+ # Override this in a child class if it cannot be dup'ed.
113
+ #
114
+ # obj1 = Object.new
115
+ # obj2 = obj1.dup!
116
+ # obj2.equal?(obj1) #=> false
117
+ #
118
+ # @return [Object]
119
+ #
120
+ def dup!
121
+ dup
122
+ end
123
+
124
+ # Alternative name for #dup!
125
+ #
126
+ # @return [Object]
127
+ #
128
+ def try_dup
129
+ dup!
130
+ end
131
+
132
+ # Can you safely call #dup on this object?
133
+ #
134
+ # Returns `false` for `nil`, `false`, `true`, symbols, and numbers;
135
+ # `true` otherwise.
136
+ #
137
+ # @return [Object]
138
+ #
139
+ def dup? ; true ; end
140
+ def clone? ; true ; end
141
+
142
+ # Extracts the singleton class, so that metaprogramming can be done on it.
143
+ #
144
+ # @example [Setup]
145
+ # class MyString < String; end
146
+ #
147
+ # MyString.instance_eval do
148
+ # define_method :foo do
149
+ # puts self
150
+ # end
151
+ # end
152
+ #
153
+ # MyString.meta_class.instance_eval do
154
+ # define_method :bar do
155
+ # puts self
156
+ # end
157
+ # end
158
+ #
159
+ # def String.add_meta_var(var)
160
+ # self.meta_class.instance_eval do
161
+ # define_method var do
162
+ # puts "HELLO"
163
+ # end
164
+ # end
165
+ # end
166
+ #
167
+ # @example
168
+ # MyString.new("Hello").foo # => "Hello"
169
+ #
170
+ # @example
171
+ # MyString.new("Hello").bar
172
+ # # => NoMethodError: undefined method `bar' for "Hello":MyString
173
+ #
174
+ # @example
175
+ # MyString.foo
176
+ # # => NoMethodError: undefined method `foo' for MyString:Class
177
+ #
178
+ # @example
179
+ # MyString.bar
180
+ # # => MyString
181
+ #
182
+ # @example
183
+ # String.bar
184
+ # # => NoMethodError: undefined method `bar' for String:Class
185
+ #
186
+ # @example
187
+ # MyString.add_meta_var(:x)
188
+ # MyString.x # => HELLO
189
+ #
190
+ # @details [Description of Examples]
191
+ # As you can see, using #meta_class allows you to execute code (and here,
192
+ # define a method) on the metaclass itself. It also allows you to define
193
+ # class methods that can be run on subclasses, and then be able to execute
194
+ # code on the metaclass of the subclass (here MyString).
195
+ #
196
+ # In this case, we were able to define a class method (add_meta_var) on
197
+ # String that was executable by the MyString subclass. It was then able to
198
+ # define a method on the subclass by adding it to the MyString metaclass.
199
+ #
200
+ # @return [Class]
201
+ # The meta class.
202
+ #
203
+ def meta_class() class << self; self end end
204
+
205
+ # @param [String] name
206
+ # The name of the constant to get, e.g. "Garcon::Check".
207
+ #
208
+ # @return [Object]
209
+ # The constant corresponding to the name.
210
+ #
211
+ def full_const_get(name)
212
+ list = name.split('::')
213
+ list.shift if list.first.blank?
214
+ obj = self
215
+ list.each do |x|
216
+ obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
217
+ end
218
+ obj
219
+ end
220
+
221
+ # @param [String] name
222
+ # The name of the constant to get, e.g. "Garcon::Check".
223
+ #
224
+ # @param [Object] value
225
+ # The value to assign to the constant.
226
+ #
227
+ # @return [Object]
228
+ # The constant corresponding to the name.
229
+ #
230
+ def full_const_set(name, value)
231
+ list = name.split('::')
232
+ toplevel = list.first.blank?
233
+ list.shift if toplevel
234
+ last = list.pop
235
+ obj = list.empty? ? Object : Object.full_const_get(list.join('::'))
236
+ obj.const_set(last, value) if obj && !obj.const_defined?(last)
237
+ end
238
+
239
+ # Defines module from a string name (e.g. Foo::Bar::Baz). If module already
240
+ # exists, no exception raised.
241
+ #
242
+ # @param [String] name
243
+ # The name of the full module name to make
244
+ #
245
+ # @return [nil]
246
+ #
247
+ def make_module(string)
248
+ current_module = self
249
+ string.split('::').each do |part|
250
+ current_module = if current_module.const_defined?(part)
251
+ current_module.const_get(part)
252
+ else
253
+ current_module.const_set(part, Module.new)
254
+ end
255
+ end
256
+ current_module
257
+ end
258
+
259
+ # @param [Symbol, Class, Array] duck
260
+ # The thing to compare the object to.
261
+ #
262
+ # @note
263
+ # The behavior of the method depends on the type of duck as follows:
264
+ # Symbol:: Check whether the object respond_to?(duck).
265
+ # Class:: Check whether the object is_a?(duck).
266
+ # Array:: Check whether the object quacks_like? at least one of the
267
+ # options in the array.
268
+ #
269
+ # @return [Boolean]
270
+ # True if the object quacks like a duck.
271
+ #
272
+ def quacks_like?(duck)
273
+ case duck
274
+ when Symbol
275
+ self.respond_to?(duck)
276
+ when Class
277
+ self.is_a?(duck)
278
+ when Array
279
+ duck.any? { |d| self.quacks_like?(d) }
280
+ else
281
+ false
282
+ end
283
+ end
284
+
285
+ # @example 1.in?([1,2,3]) # => true
286
+ #
287
+ # @example 1.in?(1,2,3) # => true
288
+ #
289
+ # @param [#include?] arrayish
290
+ # Container to check, to see if it includes the object.
291
+ #
292
+ # @param [Array] *more
293
+ # additional args, will be flattened into arrayish
294
+ #
295
+ # @return [Boolean]
296
+ # True if the object is included in arrayish (+ more)
297
+ #
298
+ def in?(arrayish, *more)
299
+ arrayish = more.unshift(arrayish) unless more.empty?
300
+ arrayish.include?(self)
301
+ end
302
+
303
+ # Get or set state of object. You can think of #object_state as an in-code
304
+ # form of marshalling.
305
+ #
306
+ # class StateExample
307
+ # attr_reader :a, :b
308
+ # def initialize(a,b)
309
+ # @a, @b = a, b
310
+ # end
311
+ # end
312
+ #
313
+ # obj = StateExample.new(1,2)
314
+ # obj.a #=> 1
315
+ # obj.b #=> 2
316
+ #
317
+ # obj.object_state #=> {:a=>1, :b=>2}
318
+ #
319
+ # obj.object_state(:a=>3, :b=>4)
320
+ # obj.a #=> 3
321
+ # obj.b #=> 4
322
+ #
323
+ # For most object's this is essentially the same as `instance.to_h`.
324
+ # But for data structures like Array and Hash it returns a snapshot of their
325
+ # contents, not the state of their instance variables.
326
+ #
327
+ def object_state(data = nil)
328
+ if data
329
+ instance_variables.each do |iv|
330
+ name = iv.to_s.sub(/^[@]/, '').to_sym
331
+ instance_variable_set(iv, data[name])
332
+ end
333
+ else
334
+ data = {}
335
+ instance_variables.each do |iv|
336
+ name = iv.to_s.sub(/^[@]/, '').to_sym
337
+ data[name] = instance_variable_get(iv)
338
+ end
339
+ data
340
+ end
341
+ end
342
+ end