garcun 0.0.2

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 (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,364 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ #
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
+ require_relative '../core_ext/method_access'
21
+
22
+ module Garcon
23
+ # Hash that allows you to access keys of the hash via method calls This gives
24
+ # you an OStruct like way to access your hash's keys. It will recognize keys
25
+ # either as strings or symbols.
26
+ #
27
+ class StashCache < Hash
28
+ include Garcon::Extensions::MethodAccess
29
+ include Garcon::Extensions::PrettyInspect
30
+ end
31
+
32
+ # In-process cache with least-recently used (LRU) and time-to-live (TTL)
33
+ # expiration semantics. This implementation is thread-safe. It does not use
34
+ # a thread to clean up expired values. Instead, an expiration check is
35
+ # performed:
36
+ #
37
+ # 1. Every time you retrieve a value, against that value. If the value has
38
+ # expired, it will be removed and `nil` will be returned.
39
+ #
40
+ # 2. Every `expire_interval` operations as the cache is used to remove all
41
+ # expired values up to that point.
42
+ #
43
+ # For manual expiration call {#expire!}.
44
+ #
45
+ class MemStash
46
+ # The maximum number of seconds an element can exist in the cache
47
+ # regardless of use. The element expires at this limit and will no longer
48
+ # be returned from the cache. The default value is 3600, or 1 hour. Setting
49
+ # A TTL value of 0 means no TTL eviction takes place (infinite lifetime).
50
+ DEFAULT_TTL_SECONDS = 3600
51
+
52
+ # The maximum number of seconds an element can exist in the cache without
53
+ # being accessed. The element expires at this limit and will no longer be
54
+ # returned from the cache. The default value is 3600, or 1 hour. Setting a
55
+ # TTI value of 0 means no TTI eviction takes place (infinite lifetime).
56
+ DEFAULT_TTI_SECONDS = 3600
57
+
58
+ # The maximum sum total number of elements (cache entries) allowed on the
59
+ # disk tier for the cache. If this target is exceeded, eviction occurs to
60
+ # bring the count within the allowed target. The default value is 1,000. A
61
+ # setting of 0 means that no eviction of the cache's entries takes place
62
+ # (infinite size is allowed), and consequently can cause the node to run
63
+ # out of disk space.
64
+ DEFAULT_MAX_ENTRIES = 1_000
65
+
66
+ # @!attribute [r] :stats
67
+ # @return [CacheStats] The Cache statistics.
68
+ attr_reader :stats
69
+
70
+ # @!attribute [r] :ttl (DEFAULT_TTL_SECONDS)
71
+ # @return [Integer] The time to live for an element before it expires.
72
+ attr_reader :ttl
73
+
74
+ # @!attribute [r] :tti (DEFAULT_TTI_SECONDS)
75
+ # @return [Integer] The time to idle for an element before it expires.
76
+ attr_reader :tti
77
+
78
+ # Initializes the cache.
79
+ #
80
+ # @param [Hash] opts
81
+ # The options to configure the cache.
82
+ #
83
+ # @option opts [Integer] :max_entries
84
+ # Maximum number of elements in the cache.
85
+ #
86
+ # @option opts [Numeric] :ttl
87
+ # Maximum time, in seconds, for a value to stay in the cache.
88
+ #
89
+ # @option opts [Numeric] :tti
90
+ # Maximum time, in seconds, for a value to stay in the cache without
91
+ # being accessed.
92
+ #
93
+ # @option opts [Integer] :interval
94
+ # Number of cache operations between calls to {#expire!}.
95
+ #
96
+ def initialize(opts = {})
97
+ @max_entries = opts.fetch(:max_entries, DEFAULT_MAX_ENTRIES)
98
+ @ttl_seconds = opts.fetch(:ttl_seconds, DEFAULT_TTL_SECONDS)
99
+ @tti_seconds = opts.fetch(:ttl_seconds, DEFAULT_TTI_SECONDS)
100
+ @interval = opts.fetch(:interval, 100)
101
+ @operations = 0
102
+ @monitor = Monitor.new
103
+ @stash = {}
104
+ @expires_at = {}
105
+ end
106
+
107
+ # Loads a hash of data into the stash.
108
+ #
109
+ # @param [Hash] data
110
+ # Hash of data with either String or Symbol keys.
111
+ #
112
+ # @return nothing.
113
+ #
114
+ def load(data)
115
+ @monitor.synchronize do
116
+ data.each do |key, value|
117
+ expire!
118
+ store(key, val)
119
+ end
120
+ end
121
+ end
122
+
123
+ # Retrieves a value from the cache, if available and not expired, or yields
124
+ # to a block that calculates the value to be stored in the cache.
125
+ #
126
+ # @param [Object] key
127
+ # The key to look up or store at.
128
+ #
129
+ # @yield yields when the value is not present.
130
+ #
131
+ # @yieldreturn [Object]
132
+ # The value to store in the cache.
133
+ #
134
+ # @return [Object]
135
+ # The value at the key.
136
+ #
137
+ def fetch(key)
138
+ @monitor.synchronize do
139
+ found, value = get(key)
140
+ found ? value : store(key, yield)
141
+ end
142
+ end
143
+
144
+ # Retrieves a value from the cache.
145
+ #
146
+ # @param [Object] key
147
+ # The key to look up.
148
+ #
149
+ # @return [Object, nil]
150
+ # The value at the key, when present, or `nil`.
151
+ #
152
+ def [](key)
153
+ @monitor.synchronize do
154
+ _, value = get(key)
155
+ value
156
+ end
157
+ end
158
+ alias_method :get, :[]
159
+
160
+ # Stores a value in the cache.
161
+ #
162
+ # @param [Object] key
163
+ # The key to store.
164
+ #
165
+ # @param val [Object]
166
+ # The value to store.
167
+ #
168
+ # @return [Object, nil]
169
+ # The value at the key.
170
+ #
171
+ def []=(key, val)
172
+ @monitor.synchronize do
173
+ expire!
174
+ store(key, val)
175
+ end
176
+ end
177
+ alias_method :set, :[]=
178
+
179
+ # Removes a value from the cache.
180
+ #
181
+ # @param [Object] key
182
+ # The key to remove.
183
+ #
184
+ # @return [Object, nil]
185
+ # The value at the key, when present, or `nil`.
186
+ #
187
+ def delete(key)
188
+ @monitor.synchronize do
189
+ entry = @stash.delete(key)
190
+ if entry
191
+ @expires_at.delete(entry)
192
+ entry.value
193
+ else
194
+ nil
195
+ end
196
+ end
197
+ end
198
+
199
+ # Checks whether the cache is empty.
200
+ #
201
+ # @note calls to {#empty?} do not count against `expire_interval`.
202
+ #
203
+ # @return [Boolean]
204
+ #
205
+ def empty?
206
+ @monitor.synchronize { count == 0 }
207
+ end
208
+
209
+ # Clears the cache.
210
+ #
211
+ # @return [self]
212
+ #
213
+ def clear
214
+ @monitor.synchronize do
215
+ @stash.clear
216
+ @expires_at.clear
217
+ self
218
+ end
219
+ end
220
+
221
+ # Returns the number of elements in the cache.
222
+ #
223
+ # @note
224
+ # Calls to {#empty?} do not count against `expire_interval`. Therefore,
225
+ # the number of elements is that prior to any expiration.
226
+ #
227
+ # @return [Integer]
228
+ # Number of elements in the cache.
229
+ #
230
+ def count
231
+ @monitor.synchronize { @stash.count }
232
+ end
233
+ alias_method :size, :count
234
+ alias_method :length, :count
235
+
236
+ # Allows iteration over the items in the cache. Enumeration is stable: it
237
+ # is not affected by changes to the cache, including value expiration.
238
+ # Expired values are removed first.
239
+ #
240
+ # @note
241
+ # The returned values could have expired by the time the client code gets
242
+ # to accessing them.
243
+ #
244
+ # @note
245
+ # Because of its stability, this operation is very expensive. Use with
246
+ # caution.
247
+ #
248
+ # @yield [Array<key, value>]
249
+ # Key/value pairs, when a block is provided.
250
+ #
251
+ # @return [Enumerator, Array<key, value>]
252
+ # An Enumerator, when no block is provided, or array of key/value pairs.
253
+ #
254
+ def each(&block)
255
+ @monitor.synchronize do
256
+ expire!
257
+ @stash.map { |key, entry| [key, entry.value] }.each(&block)
258
+ end
259
+ end
260
+
261
+ # Removes expired values from the cache.
262
+ #
263
+ # @return [self]
264
+ #
265
+ def expire!
266
+ @monitor.synchronize do
267
+ check_expired(Time.now.to_f)
268
+ self
269
+ end
270
+ end
271
+
272
+ # Return all keys in the store as an array.
273
+ #
274
+ # @return [Array<String, Symbol>] all the keys in store
275
+ #
276
+ def keys
277
+ @monitor.synchronize { @stash.keys }
278
+ end
279
+
280
+ # Returns information about the number of objects in the cache, its
281
+ # maximum size and TTL.
282
+ #
283
+ # @return [String]
284
+ #
285
+ def inspect
286
+ @monitor.synchronize do
287
+ "<#{self.class.name} count=#{count} max_entries=#{@max_entries} " \
288
+ "ttl=#{@ttl_seconds}>"
289
+ end
290
+ end
291
+
292
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
293
+
294
+ # @private
295
+ class Entry
296
+ attr_reader :value
297
+ attr_reader :expires_at
298
+
299
+ def initialize(value, expires_at)
300
+ @value = value
301
+ @expires_at = expires_at
302
+ end
303
+ end
304
+
305
+ def get(key)
306
+ @monitor.synchronize do
307
+ time = Time.now.to_f
308
+ check_expired(time)
309
+ found = true
310
+ entry = @stash.delete(key) { found = false }
311
+ if found
312
+ if entry.expires_at <= time
313
+ @expires_at.delete(entry)
314
+ return false, nil
315
+ else
316
+ @stash[key] = entry
317
+ return true, entry.value
318
+ end
319
+ else
320
+ return false, nil
321
+ end
322
+ end
323
+ end
324
+
325
+ def store(key, val)
326
+ @monitor.synchronize do
327
+ expires_at = Time.now.to_f + @ttl_seconds
328
+ entry = Entry.new(val, expires_at)
329
+ store_entry(key, entry)
330
+ val
331
+ end
332
+ end
333
+
334
+ def store_entry(key, entry)
335
+ @monitor.synchronize do
336
+ @stash.delete(key)
337
+ @stash[key] = entry
338
+ @expires_at[entry] = key
339
+ shrink_if_needed
340
+ end
341
+ end
342
+
343
+ def shrink_if_needed
344
+ @monitor.synchronize do
345
+ if @stash.length > @max_entries
346
+ entry = delete(@stash.shift)
347
+ @expires_at.delete(entry)
348
+ end
349
+ end
350
+ end
351
+
352
+ def check_expired(time)
353
+ @monitor.synchronize do
354
+ if (@operations += 1) % @interval == 0
355
+ while (key_value_pair = @expires_at.first) &&
356
+ (entry = key_value_pair.first).expires_at <= time
357
+ key = @expires_at.delete(entry)
358
+ @stash.delete(key)
359
+ end
360
+ end
361
+ end
362
+ end
363
+ end
364
+ end
@@ -0,0 +1,54 @@
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
+ module Garcon
21
+ # Returns the columns and lines of the current tty.
22
+ #
23
+ # @return [Integer]
24
+ # Number of columns and lines of tty, returns [0, 0] if no tty is present.
25
+ #
26
+ def terminal_dimensions
27
+ [0, 0] unless STDOUT.tty?
28
+ [80, 40] if OS.windows?
29
+
30
+ if ENV['COLUMNS'] && ENV['LINES']
31
+ [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
32
+ elsif ENV['TERM'] && command_in_path?('tput')
33
+ [`tput cols`.to_i, `tput lines`.to_i]
34
+ elsif command_in_path?('stty')
35
+ `stty size`.scan(/\d+/).map {|s| s.to_i }
36
+ else
37
+ [0, 0]
38
+ end
39
+ rescue
40
+ [0, 0]
41
+ end
42
+ end
43
+
44
+ class GarconHash < Hash
45
+ def method_missing(method_name, *args)
46
+ return super unless respond_to?(method_name)
47
+ self[method_name].to_s
48
+ end
49
+
50
+ def respond_to?(symbol, include_private=false)
51
+ return true if key?(symbol.to_s)
52
+ super
53
+ end
54
+ end
@@ -0,0 +1,62 @@
1
+
2
+ # God speaks in Ruby, not Python!! MsgFromGod is an implementation of a
3
+ # Higher-Order-Message. Essentally, a MsgFromGod can vary its behavior
4
+ # accorrding to the operation applied to it.
5
+ #
6
+ # @example
7
+ # g = MsgFromGod.new { |op, x| x.send(op, x) }
8
+ # (g + 1) # => 2
9
+ # (g + 2) # => 4
10
+ # (g + 3) # => 6
11
+ # (g * 1) # => 1
12
+ # (g * 2) # => 4
13
+ # (g * 3) # => 9
14
+ #
15
+ class MsgFromGod
16
+
17
+ # MsgFromGod can be somewhat inefficient if a new MsgFromGod is frequently
18
+ # recreated for the same use. So this cache can be used to speed things up.
19
+ #
20
+ # The key will always be an array, wich makes it easier to cache MsgFromGod
21
+ # for multiple factors.
22
+ #
23
+ def self.cache(*key, &function)
24
+ @cache ||= {}
25
+ if function
26
+ @cache[key] = new(&function)
27
+ else
28
+ @cache[key]
29
+ end
30
+ end
31
+
32
+ EXCEPTIONS = [:binding, :inspect, :object_id]
33
+ if defined?(::BasicObject)
34
+ EXCEPTIONS.concat(::BasicObject.instance_methods)
35
+ EXCEPTIONS.uniq!
36
+ EXCEPTIONS.map! { |m| m.to_sym }
37
+ end
38
+
39
+ alias :__class__ :class
40
+
41
+ # Privatize all methods except vital methods and #binding.
42
+ instance_methods(true).each do |m|
43
+ next if m.to_s =~ /^__/
44
+ next if EXCEPTIONS.include?(m.to_sym)
45
+ undef_method(m)
46
+ end
47
+
48
+ def initialize(&function)
49
+ @function = function
50
+ end
51
+
52
+ def to_proc
53
+ @function
54
+ end
55
+
56
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
57
+
58
+ # Any action against the MsgFromGod is processesd by the function.
59
+ def method_missing(op, *args, &blk)
60
+ @function.call(op, *args, &blk)
61
+ end
62
+ end