garcun 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +17 -0
- data/.gitignore +197 -0
- data/.rspec +2 -0
- data/Gemfile +22 -0
- data/LICENSE +201 -0
- data/README.md +521 -0
- data/Rakefile +47 -0
- data/garcun.gemspec +83 -0
- data/lib/garcon.rb +290 -0
- data/lib/garcon/chef/chef_helpers.rb +343 -0
- data/lib/garcon/chef/coerce/coercer.rb +134 -0
- data/lib/garcon/chef/coerce/coercions/boolean_definitions.rb +34 -0
- data/lib/garcon/chef/coerce/coercions/date_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/date_time_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/fixnum_definitions.rb +34 -0
- data/lib/garcon/chef/coerce/coercions/float_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/hash_definitions.rb +29 -0
- data/lib/garcon/chef/coerce/coercions/integer_definitions.rb +31 -0
- data/lib/garcon/chef/coerce/coercions/string_definitions.rb +45 -0
- data/lib/garcon/chef/coerce/coercions/time_definitions.rb +32 -0
- data/lib/garcon/chef/handler/devreporter.rb +127 -0
- data/lib/garcon/chef/log.rb +64 -0
- data/lib/garcon/chef/node.rb +100 -0
- data/lib/garcon/chef/provider/civilize.rb +209 -0
- data/lib/garcon/chef/provider/development.rb +159 -0
- data/lib/garcon/chef/provider/download.rb +420 -0
- data/lib/garcon/chef/provider/house_keeping.rb +265 -0
- data/lib/garcon/chef/provider/node_cache.rb +31 -0
- data/lib/garcon/chef/provider/partial.rb +183 -0
- data/lib/garcon/chef/provider/recovery.rb +80 -0
- data/lib/garcon/chef/provider/zip_file.rb +271 -0
- data/lib/garcon/chef/resource/attribute.rb +52 -0
- data/lib/garcon/chef/resource/base_dsl.rb +174 -0
- data/lib/garcon/chef/resource/blender.rb +140 -0
- data/lib/garcon/chef/resource/lazy_eval.rb +66 -0
- data/lib/garcon/chef/resource/resource_name.rb +109 -0
- data/lib/garcon/chef/secret_bag.rb +204 -0
- data/lib/garcon/chef/validations.rb +76 -0
- data/lib/garcon/chef_inclusions.rb +151 -0
- data/lib/garcon/configuration.rb +138 -0
- data/lib/garcon/core_ext.rb +39 -0
- data/lib/garcon/core_ext/array.rb +27 -0
- data/lib/garcon/core_ext/binding.rb +64 -0
- data/lib/garcon/core_ext/boolean.rb +66 -0
- data/lib/garcon/core_ext/duration.rb +271 -0
- data/lib/garcon/core_ext/enumerable.rb +34 -0
- data/lib/garcon/core_ext/file.rb +127 -0
- data/lib/garcon/core_ext/filetest.rb +62 -0
- data/lib/garcon/core_ext/hash.rb +279 -0
- data/lib/garcon/core_ext/kernel.rb +159 -0
- data/lib/garcon/core_ext/lazy.rb +222 -0
- data/lib/garcon/core_ext/method_access.rb +243 -0
- data/lib/garcon/core_ext/module.rb +92 -0
- data/lib/garcon/core_ext/nil.rb +53 -0
- data/lib/garcon/core_ext/numeric.rb +44 -0
- data/lib/garcon/core_ext/object.rb +342 -0
- data/lib/garcon/core_ext/pathname.rb +152 -0
- data/lib/garcon/core_ext/process.rb +41 -0
- data/lib/garcon/core_ext/random.rb +497 -0
- data/lib/garcon/core_ext/string.rb +312 -0
- data/lib/garcon/core_ext/struct.rb +49 -0
- data/lib/garcon/core_ext/symbol.rb +170 -0
- data/lib/garcon/core_ext/time.rb +234 -0
- data/lib/garcon/exceptions.rb +101 -0
- data/lib/garcon/inflections.rb +237 -0
- data/lib/garcon/inflections/defaults.rb +79 -0
- data/lib/garcon/inflections/inflections.rb +182 -0
- data/lib/garcon/inflections/rules_collection.rb +37 -0
- data/lib/garcon/secret.rb +271 -0
- data/lib/garcon/stash/format.rb +114 -0
- data/lib/garcon/stash/journal.rb +226 -0
- data/lib/garcon/stash/queue.rb +83 -0
- data/lib/garcon/stash/serializer.rb +86 -0
- data/lib/garcon/stash/store.rb +435 -0
- data/lib/garcon/task.rb +31 -0
- data/lib/garcon/task/atomic.rb +151 -0
- data/lib/garcon/task/atomic_boolean.rb +127 -0
- data/lib/garcon/task/condition.rb +99 -0
- data/lib/garcon/task/copy_on_notify_observer_set.rb +154 -0
- data/lib/garcon/task/copy_on_write_observer_set.rb +153 -0
- data/lib/garcon/task/count_down_latch.rb +92 -0
- data/lib/garcon/task/delay.rb +196 -0
- data/lib/garcon/task/dereferenceable.rb +144 -0
- data/lib/garcon/task/event.rb +119 -0
- data/lib/garcon/task/executor.rb +275 -0
- data/lib/garcon/task/executor_options.rb +59 -0
- data/lib/garcon/task/future.rb +107 -0
- data/lib/garcon/task/immediate_executor.rb +84 -0
- data/lib/garcon/task/ivar.rb +171 -0
- data/lib/garcon/task/lazy_reference.rb +74 -0
- data/lib/garcon/task/monotonic_time.rb +69 -0
- data/lib/garcon/task/obligation.rb +256 -0
- data/lib/garcon/task/observable.rb +101 -0
- data/lib/garcon/task/priority_queue.rb +234 -0
- data/lib/garcon/task/processor_count.rb +128 -0
- data/lib/garcon/task/read_write_lock.rb +304 -0
- data/lib/garcon/task/safe_task_executor.rb +58 -0
- data/lib/garcon/task/single_thread_executor.rb +97 -0
- data/lib/garcon/task/thread_pool/cached.rb +71 -0
- data/lib/garcon/task/thread_pool/executor.rb +294 -0
- data/lib/garcon/task/thread_pool/fixed.rb +61 -0
- data/lib/garcon/task/thread_pool/worker.rb +90 -0
- data/lib/garcon/task/timer.rb +44 -0
- data/lib/garcon/task/timer_set.rb +194 -0
- data/lib/garcon/task/timer_task.rb +377 -0
- data/lib/garcon/task/waitable_list.rb +58 -0
- data/lib/garcon/utility/ansi.rb +199 -0
- data/lib/garcon/utility/at_random.rb +77 -0
- data/lib/garcon/utility/crypto.rb +292 -0
- data/lib/garcon/utility/equalizer.rb +146 -0
- data/lib/garcon/utility/faker/extensions/array.rb +22 -0
- data/lib/garcon/utility/faker/extensions/symbol.rb +9 -0
- data/lib/garcon/utility/faker/faker.rb +164 -0
- data/lib/garcon/utility/faker/faker/company.rb +17 -0
- data/lib/garcon/utility/faker/faker/hacker.rb +30 -0
- data/lib/garcon/utility/faker/faker/version.rb +3 -0
- data/lib/garcon/utility/faker/locales/en-US.yml +83 -0
- data/lib/garcon/utility/faker/locales/en.yml +21 -0
- data/lib/garcon/utility/file_helper.rb +170 -0
- data/lib/garcon/utility/hookers.rb +178 -0
- data/lib/garcon/utility/interpolation.rb +90 -0
- data/lib/garcon/utility/memstash.rb +364 -0
- data/lib/garcon/utility/misc.rb +54 -0
- data/lib/garcon/utility/msg_from_god.rb +62 -0
- data/lib/garcon/utility/retry.rb +238 -0
- data/lib/garcon/utility/timeout.rb +58 -0
- data/lib/garcon/utility/uber/builder.rb +91 -0
- data/lib/garcon/utility/uber/callable.rb +7 -0
- data/lib/garcon/utility/uber/delegates.rb +13 -0
- data/lib/garcon/utility/uber/inheritable_attr.rb +37 -0
- data/lib/garcon/utility/uber/options.rb +101 -0
- data/lib/garcon/utility/uber/uber_version.rb +3 -0
- data/lib/garcon/utility/uber/version.rb +33 -0
- data/lib/garcon/utility/url_helper.rb +100 -0
- data/lib/garcon/utils.rb +29 -0
- data/lib/garcon/version.rb +62 -0
- data/lib/garcun.rb +24 -0
- metadata +680 -0
@@ -0,0 +1,312 @@
|
|
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
|
+
# Adds `#contains?`, `#blank?` and `#shatter` methods to strings
|
21
|
+
#
|
22
|
+
class String
|
23
|
+
|
24
|
+
# Get or set state of object. You can think of #object_state as an in-code
|
25
|
+
# form of marshalling.
|
26
|
+
#
|
27
|
+
def object_state(data=nil)
|
28
|
+
data ? replace(data) : dup
|
29
|
+
end
|
30
|
+
|
31
|
+
# Common Unix cryptography method.
|
32
|
+
# This adds a default salt to the built-in crypt method.
|
33
|
+
#
|
34
|
+
def crypt(salt=nil)
|
35
|
+
salt ||= ((SecureRandom.random_number(26) +
|
36
|
+
(SecureRandom.random_number(2) == 0 ? 65 : 97)).chr +
|
37
|
+
(SecureRandom.random_number(26) +
|
38
|
+
(SecureRandom.random_number(2) == 0 ? 65 : 97)).chr)
|
39
|
+
_crypt(salt)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Search a text file for a matching string
|
43
|
+
#
|
44
|
+
# @return [Boolean]
|
45
|
+
# True if the file is present and a match was found, otherwise returns
|
46
|
+
# false if file does not exist and/or does not contain a match
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
def contains?(str)
|
50
|
+
return false unless ::File.exist?(self)
|
51
|
+
::File.open(self, &:readlines).collect { |l| return true if l.match(str) }
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
# Turns a string into a regular expression.
|
56
|
+
#
|
57
|
+
# "a?".to_re #=> /a?/
|
58
|
+
#
|
59
|
+
def to_re(esc=false)
|
60
|
+
Regexp.new((esc ? Regexp.escape(self) : self))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Turns a string into a regular expression.
|
64
|
+
# By default it will escape all characters.
|
65
|
+
# Use <tt>false</tt> argument to turn off escaping.
|
66
|
+
#
|
67
|
+
# "[".to_rx #=> /\[/
|
68
|
+
#
|
69
|
+
def to_rx(esc=true)
|
70
|
+
Regexp.new((esc ? Regexp.escape(self) : self))
|
71
|
+
end
|
72
|
+
|
73
|
+
# Strips out whitespace then tests if the string is empty.
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
# "".blank? # => true
|
77
|
+
# " ".blank? # => true
|
78
|
+
# " sup? ".blank? # => false
|
79
|
+
#
|
80
|
+
# @return [Boolean]
|
81
|
+
# True if blank, else false.
|
82
|
+
#
|
83
|
+
# @api public
|
84
|
+
def blank?
|
85
|
+
strip.empty?
|
86
|
+
end
|
87
|
+
|
88
|
+
# Breaks a string up into an array based on a regular expression.
|
89
|
+
# Similar to scan, but includes the matches.
|
90
|
+
#
|
91
|
+
# @example
|
92
|
+
# s = "<p>This<b>is</b>a test.</p>"
|
93
|
+
# s.shatter(/\<.*?\>/)
|
94
|
+
# => [
|
95
|
+
# [0] "<p>",
|
96
|
+
# [1] "This",
|
97
|
+
# [2] "<b>",
|
98
|
+
# [3] "is",
|
99
|
+
# [4] "</b>",
|
100
|
+
# [5] "a test.",
|
101
|
+
# [6] "</p>"
|
102
|
+
# ]
|
103
|
+
#
|
104
|
+
# @param [Regexp] regex
|
105
|
+
# Regular expression for breaking string into array.
|
106
|
+
#
|
107
|
+
# @return [String]
|
108
|
+
#
|
109
|
+
# @api public
|
110
|
+
def shatter(re)
|
111
|
+
r = self.gsub(re) { |s| "\1" + s + "\1" }
|
112
|
+
while r[ 0, 1] == "\1"; r[0] = ''; end
|
113
|
+
while r[-1, 1] == "\1"; r[-1] = ''; end
|
114
|
+
r.split("\1")
|
115
|
+
end
|
116
|
+
|
117
|
+
# Left-flush a string based off of the number of whitespace characters on the
|
118
|
+
# first line. This is especially useful for heredocs when whitespace matters.
|
119
|
+
#
|
120
|
+
# @example Remove leading whitespace and flush
|
121
|
+
# <<-EOH.flush
|
122
|
+
# def method
|
123
|
+
# 'This is a string!'
|
124
|
+
# end
|
125
|
+
# EOH # =>"def method\n 'This is a string!'\nend"
|
126
|
+
#
|
127
|
+
# @return [String]
|
128
|
+
#
|
129
|
+
# @api public
|
130
|
+
def flush
|
131
|
+
gsub(/^#{self[/\A\s*/]}/, '').chomp
|
132
|
+
end unless method_defined?(:flush)
|
133
|
+
|
134
|
+
# Escape all regexp special characters.
|
135
|
+
#
|
136
|
+
# @example
|
137
|
+
# "*?{}.".escape_regexp # => "\\*\\?\\{\\}\\."
|
138
|
+
#
|
139
|
+
# @return [String]
|
140
|
+
# Receiver with all regexp special characters escaped.
|
141
|
+
#
|
142
|
+
# @api public
|
143
|
+
def escape_regexp
|
144
|
+
Regexp.escape self
|
145
|
+
end
|
146
|
+
|
147
|
+
# Unescape all regexp special characters.
|
148
|
+
#
|
149
|
+
# @example
|
150
|
+
# "\\*\\?\\{\\}\\.".unescape_regexp # => "*?{}."
|
151
|
+
#
|
152
|
+
# @return [String]
|
153
|
+
# Receiver with all regexp special characters unescaped.
|
154
|
+
#
|
155
|
+
# @api public
|
156
|
+
def unescape_regexp
|
157
|
+
self.gsub(/\\([\.\?\|\(\)\[\]\{\}\^\$\*\+\-])/, '\1')
|
158
|
+
end
|
159
|
+
|
160
|
+
# Convert a path string to a constant name.
|
161
|
+
#
|
162
|
+
# @example
|
163
|
+
# "chef/mixin/checksum".to_const_string # => "Chef::Mixin::Checksum"
|
164
|
+
#
|
165
|
+
# @return [String]
|
166
|
+
# Receiver converted to a constant name.
|
167
|
+
#
|
168
|
+
# @api public
|
169
|
+
def to_const_string
|
170
|
+
gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
171
|
+
end
|
172
|
+
|
173
|
+
# Convert a constant name to a path, assuming a conventional structure.
|
174
|
+
#
|
175
|
+
# @example
|
176
|
+
# "FooBar::Baz".to_const_path # => "foo_bar/baz"
|
177
|
+
#
|
178
|
+
# @return [String]
|
179
|
+
# Path to the file containing the constant named by receiver (constantized
|
180
|
+
# string), assuming a conventional structure.
|
181
|
+
#
|
182
|
+
# @api public
|
183
|
+
def to_const_path
|
184
|
+
snake_case.gsub(/::/, "/")
|
185
|
+
end
|
186
|
+
|
187
|
+
# Join with _o_ as a file path.
|
188
|
+
#
|
189
|
+
# @example
|
190
|
+
# 'usr'/'local' # => 'usr/local'
|
191
|
+
#
|
192
|
+
# @param [String] other
|
193
|
+
# Path component(s) to join with receiver.
|
194
|
+
#
|
195
|
+
# @return [String]
|
196
|
+
# Receiver joined with other as a file path.
|
197
|
+
#
|
198
|
+
# @api public
|
199
|
+
def /(other)
|
200
|
+
File.join(self, other.to_s)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Calculate a relative path *from* _other_.
|
204
|
+
#
|
205
|
+
# @example
|
206
|
+
# '/opt/chefdk/'.relative_path_from '/opt/chefdk/embedded/bin' # => '../..'
|
207
|
+
#
|
208
|
+
# @param [String] other
|
209
|
+
# Base path to calculate *from*.
|
210
|
+
#
|
211
|
+
# @return [String]
|
212
|
+
# Relative path from _other_ to receiver.
|
213
|
+
#
|
214
|
+
# @api public
|
215
|
+
def relative_path_from(other)
|
216
|
+
Pathname.new(self).relative_path_from(Pathname.new(other)).to_s
|
217
|
+
end
|
218
|
+
|
219
|
+
# Replace sequences of whitespace (including newlines) with either
|
220
|
+
# a single space or remove them entirely (according to param _spaced_)
|
221
|
+
#
|
222
|
+
# @example
|
223
|
+
# <<QUERY.compress_lines
|
224
|
+
# SELECT name
|
225
|
+
# FROM users
|
226
|
+
# QUERY => 'SELECT name FROM users'
|
227
|
+
#
|
228
|
+
# @param [Boolean] spaced (default=true)
|
229
|
+
# Determines whether returned string has whitespace collapsed or removed
|
230
|
+
#
|
231
|
+
# @return [String]
|
232
|
+
# Receiver with whitespace (including newlines) replaced
|
233
|
+
#
|
234
|
+
# @api public
|
235
|
+
def compress_lines(spaced = true)
|
236
|
+
split($/).map { |line| line.strip }.join(spaced ? ' ' : '')
|
237
|
+
end
|
238
|
+
|
239
|
+
# Remove whitespace margin.
|
240
|
+
#
|
241
|
+
# @return [String]
|
242
|
+
# Receiver with whitespace margin removed.
|
243
|
+
#
|
244
|
+
# @api public
|
245
|
+
def margin(indicator = nil)
|
246
|
+
lines = self.dup.split($/)
|
247
|
+
|
248
|
+
min_margin = 0
|
249
|
+
lines.each do |line|
|
250
|
+
if line =~ /^(\s+)/ && (min_margin == 0 || $1.size < min_margin)
|
251
|
+
min_margin = $1.size
|
252
|
+
end
|
253
|
+
end
|
254
|
+
lines.map { |line| line.sub(/^\s{#{min_margin}}/, '') }.join($/)
|
255
|
+
end
|
256
|
+
|
257
|
+
# Formats String for easy translation. Replaces an arbitrary number of
|
258
|
+
# values using numeric identifier replacement.
|
259
|
+
#
|
260
|
+
# @example
|
261
|
+
# "%s %s %s" % %w(one two three) # => 'one two three'
|
262
|
+
# "%3$s %2$s %1$s" % %w(one two three) # => 'three two one'
|
263
|
+
#
|
264
|
+
# @param [#to_s] values
|
265
|
+
# A list of values to translate and interpolate into receiver
|
266
|
+
#
|
267
|
+
# @return [String]
|
268
|
+
# Receiver translated with values translated and interpolated positionally
|
269
|
+
#
|
270
|
+
# @api public
|
271
|
+
def t(*values)
|
272
|
+
self.class::translate(self) % values.collect! do |value|
|
273
|
+
value.frozen? ? value : self.class::translate(value.to_s)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def clear; colorize(self, "\e[0m"); end
|
278
|
+
def erase_line; colorize(self, "\e[K"); end
|
279
|
+
def erase_char; colorize(self, "\e[P"); end
|
280
|
+
def bold; colorize(self, "\e[1m"); end
|
281
|
+
def dark; colorize(self, "\e[2m"); end
|
282
|
+
def underline; colorize(self, "\e[4m"); end
|
283
|
+
def blink; colorize(self, "\e[5m"); end
|
284
|
+
def reverse; colorize(self, "\e[7m"); end
|
285
|
+
def concealed; colorize(self, "\e[8m"); end
|
286
|
+
def black; colorize(self, "\e[0;30m"); end
|
287
|
+
def gray; colorize(self, "\e[1;30m"); end
|
288
|
+
def red; colorize(self, "\e[0;31m"); end
|
289
|
+
def magenta; colorize(self, "\e[1;31m"); end
|
290
|
+
def green; colorize(self, "\e[0;32m"); end
|
291
|
+
def olive; colorize(self, "\e[1;32m"); end
|
292
|
+
def yellow; colorize(self, "\e[0;33m"); end
|
293
|
+
def cream; colorize(self, "\e[1;33m"); end
|
294
|
+
def blue; colorize(self, "\e[0;34m"); end
|
295
|
+
def purple; colorize(self, "\e[1;34m"); end
|
296
|
+
def orange; colorize(self, "\e[0;35m"); end
|
297
|
+
def mustard; colorize(self, "\e[1;35m"); end
|
298
|
+
def cyan; colorize(self, "\e[0;36m"); end
|
299
|
+
def cyan2; colorize(self, "\e[1;36m"); end
|
300
|
+
def light_gray; colorize(self, "\e[2;37m"); end
|
301
|
+
def bright_red; colorize(self, "\e[1;41m"); end
|
302
|
+
def white; colorize(self, "\e[0;97m"); end
|
303
|
+
def on_black; colorize(self, "\e[40m"); end
|
304
|
+
def on_red; colorize(self, "\e[41m"); end
|
305
|
+
def on_green; colorize(self, "\e[42m"); end
|
306
|
+
def on_yellow; colorize(self, "\e[43m"); end
|
307
|
+
def on_blue; colorize(self, "\e[44m"); end
|
308
|
+
def on_magenta; colorize(self, "\e[45m"); end
|
309
|
+
def on_cyan; colorize(self, "\e[46m"); end
|
310
|
+
def on_white; colorize(self, "\e[47m"); end
|
311
|
+
def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
|
312
|
+
end
|
@@ -0,0 +1,49 @@
|
|
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 Struct
|
21
|
+
|
22
|
+
# Get or set state of object. You can think of #object_state as an in-code
|
23
|
+
# form of marshalling.
|
24
|
+
#
|
25
|
+
def object_state(data=nil)
|
26
|
+
if data
|
27
|
+
data.each_pair {|k,v| send(k.to_s + "=", v)}
|
28
|
+
else
|
29
|
+
data = {}
|
30
|
+
each_pair{|k,v| data[k] = v}
|
31
|
+
data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get a hash with names and values of all instance variables.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# class Foo < Struct.new(:name, :age, :gender); end
|
39
|
+
# f = Foo.new("Jill", 50, :female)
|
40
|
+
# f.attributes # => {:name => "Jill", :age => 50, :gender => :female}
|
41
|
+
#
|
42
|
+
# @return [Hash]
|
43
|
+
# Hash of instance variables in receiver, keyed by ivar name
|
44
|
+
def attributes
|
45
|
+
h = {}
|
46
|
+
each_pair { |key, value| h[key] = value }
|
47
|
+
h
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,170 @@
|
|
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 Symbol
|
21
|
+
|
22
|
+
# Override this in a child if it cannot be dup'ed
|
23
|
+
#
|
24
|
+
# @return [Object]
|
25
|
+
def try_dup
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
# Since Symbol is immutable it cannot be duplicated.
|
30
|
+
# For this reason #try_dup returns +self+.
|
31
|
+
#
|
32
|
+
# :a.dup! #=> :a
|
33
|
+
#
|
34
|
+
def dup! ; self ; end
|
35
|
+
def dup? ; false ; end
|
36
|
+
def clone? ; false ; end
|
37
|
+
|
38
|
+
# Join with _o_ as a file path.
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# :chef/'provider' # => 'chef/provider'
|
42
|
+
# :chef/ :provider # => 'chef/provider'
|
43
|
+
#
|
44
|
+
# @param [#to_s] other
|
45
|
+
# Path component(s) to join with receiver.
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
# Receiver joined with other as a file path.
|
49
|
+
#
|
50
|
+
# @api public
|
51
|
+
def /(other)
|
52
|
+
File.join(self.to_s, other.to_s)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Symbol does not end in `!`, `=`, or `?`.
|
56
|
+
#
|
57
|
+
# :a.plain? #=> true
|
58
|
+
# :a?.plain? #=> false
|
59
|
+
# :a!.plain? #=> false
|
60
|
+
# :a=.plain? #=> false
|
61
|
+
#
|
62
|
+
def plain?
|
63
|
+
c = to_s[-1,1]
|
64
|
+
!(c == '=' || c == '?' || c == '!')
|
65
|
+
end
|
66
|
+
|
67
|
+
# Alias for `#plain?` method. Likely this should have been the original
|
68
|
+
# and only name, but such is life.
|
69
|
+
alias_method :reader?, :plain?
|
70
|
+
|
71
|
+
# Symbol ends in `=`.
|
72
|
+
#
|
73
|
+
# :a=.setter? #=> true
|
74
|
+
# :a.setter? #=> false
|
75
|
+
#
|
76
|
+
def setter?
|
77
|
+
to_s[-1,1] == '='
|
78
|
+
end
|
79
|
+
|
80
|
+
# Alias for `#setter?` method. Likely this should have been the original
|
81
|
+
# and only name, but such is life.
|
82
|
+
alias_method :writer?, :setter?
|
83
|
+
|
84
|
+
# Symbol ends in `?`.
|
85
|
+
#
|
86
|
+
# :a?.query? #=> true
|
87
|
+
# :a.query? #=> false
|
88
|
+
#
|
89
|
+
def query?
|
90
|
+
to_s[-1,1] == '?'
|
91
|
+
end
|
92
|
+
|
93
|
+
# Symbol ends in `!`.
|
94
|
+
#
|
95
|
+
# :a!.bang? #=> true
|
96
|
+
# :a.bang? #=> false
|
97
|
+
#
|
98
|
+
def bang?
|
99
|
+
to_s[-1,1] == '!'
|
100
|
+
end
|
101
|
+
|
102
|
+
# Does a symbol have a "not" sign?
|
103
|
+
#
|
104
|
+
# "friend".to_sym.not? #=> false
|
105
|
+
# "~friend".to_sym.not? #=> true
|
106
|
+
#
|
107
|
+
def not?
|
108
|
+
self.to_s.slice(0,1) == '~'
|
109
|
+
end
|
110
|
+
|
111
|
+
# Add a "not" sign to the front of a symbol.
|
112
|
+
#
|
113
|
+
# (~:friend) #=> :"~friend"
|
114
|
+
#
|
115
|
+
def ~@
|
116
|
+
if self.to_s.slice(0,1) == '~'
|
117
|
+
"#{self.to_s[1..-1]}".to_sym
|
118
|
+
else
|
119
|
+
"~#{self}".to_sym
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Generate a unique symbol.
|
124
|
+
#
|
125
|
+
# Symbol.generate #=> :"-1"
|
126
|
+
#
|
127
|
+
# If +key+ is given the new symbol will be prefixed with it.
|
128
|
+
#
|
129
|
+
# Symbol.generate(:foo) #=> :"foo-1"
|
130
|
+
#
|
131
|
+
def self.generate(key = nil)
|
132
|
+
key = key.to_sym if key
|
133
|
+
@symbol_generate_counter ||= {}
|
134
|
+
@symbol_generate_counter[key] ||= 0
|
135
|
+
num = @symbol_generate_counter[key] += 1
|
136
|
+
("#{key}-%X" % num).to_sym
|
137
|
+
end
|
138
|
+
|
139
|
+
# This allows us to call obj(&:method) instead of obj { |i| i.method }
|
140
|
+
unless method_defined?(:to_proc)
|
141
|
+
def to_proc
|
142
|
+
proc { |obj, args| obj.send(self, *args) }
|
143
|
+
# lambda { |obj, args=nil| obj.send(self, *args) }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Useful extension for &:symbol which makes it possible
|
148
|
+
# to pass arguments for method in block
|
149
|
+
#
|
150
|
+
# ['abc','','','def','ghi'].tap(&:delete.(''))
|
151
|
+
# #=> ['abc','def','ghi']
|
152
|
+
#
|
153
|
+
# [1,2,3].map(&:to_s.(2))
|
154
|
+
# #=> ['1','10','11']
|
155
|
+
#
|
156
|
+
# ['abc','cdef','xy','z','wwww'].select(&:size.() == 4)
|
157
|
+
# #=> ['cdef', 'wwww']
|
158
|
+
#
|
159
|
+
# ['abc','aaA','AaA','z'].count(&:upcase.().succ == 'AAB')
|
160
|
+
# #=> 2
|
161
|
+
#
|
162
|
+
# [%w{1 2 3 4 5},%w{6 7 8 9}].map(&:join.().length)
|
163
|
+
# #=> [5,4]
|
164
|
+
#
|
165
|
+
def call(*args, &block)
|
166
|
+
proc do |recv|
|
167
|
+
recv.__send__(self, *args, &block)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|