garcun 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/lib/garcon/chef/chef_helpers.rb +9 -12
- data/lib/garcon/chef/coerce/coercer.rb +3 -0
- data/lib/garcon/chef/node.rb +7 -5
- data/lib/garcon/chef/provider/download.rb +2 -30
- data/lib/garcon/chef/resource/base_dsl.rb +53 -0
- data/lib/garcon/chef/secret_bag.rb +2 -1
- data/lib/garcon/chef_inclusions.rb +1 -9
- data/lib/garcon/core_ext/array.rb +1 -1
- data/lib/garcon/core_ext/binding.rb +0 -1
- data/lib/garcon/core_ext/boolean.rb +2 -0
- data/lib/garcon/core_ext/hash.rb +1 -2
- data/lib/garcon/core_ext/kernel.rb +0 -2
- data/lib/garcon/core_ext/module.rb +0 -1
- data/lib/garcon/core_ext/object.rb +0 -3
- data/lib/garcon/core_ext/string.rb +9 -15
- data/lib/garcon/core_ext/struct.rb +0 -1
- data/lib/garcon/core_ext/symbol.rb +0 -1
- data/lib/garcon/core_ext/time.rb +0 -1
- data/lib/garcon/core_ext.rb +0 -4
- data/lib/garcon/exceptions.rb +0 -35
- data/lib/garcon/task/executor.rb +0 -1
- data/lib/garcon/task/ivar.rb +0 -2
- data/lib/garcon/utility/file_helper.rb +88 -1
- data/lib/garcon/utility/retry.rb +0 -3
- data/lib/garcon/utility/timeout.rb +0 -3
- data/lib/garcon/utils.rb +0 -1
- data/lib/garcon/version.rb +1 -1
- data/lib/garcon.rb +1 -4
- data/lib/garcun.rb +1 -3
- metadata +2 -11
- data/lib/garcon/chef/handler/devreporter.rb +0 -127
- data/lib/garcon/chef/resource/resource_name.rb +0 -109
- data/lib/garcon/core_ext/file.rb +0 -127
- data/lib/garcon/core_ext/filetest.rb +0 -62
- data/lib/garcon/core_ext/lazy.rb +0 -222
- data/lib/garcon/core_ext/process.rb +0 -41
- data/lib/garcon/utility/ansi.rb +0 -199
- data/lib/garcon/utility/equalizer.rb +0 -146
- data/lib/garcon/utility/msg_from_god.rb +0 -62
data/lib/garcon/core_ext/lazy.rb
DELETED
@@ -1,222 +0,0 @@
|
|
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
|
-
# Lazy ass Ruby.
|
21
|
-
#
|
22
|
-
module Lazy
|
23
|
-
# Raised when a demanded computation diverges (e.g. if it tries to directly
|
24
|
-
# use its own result)
|
25
|
-
#
|
26
|
-
class DivergenceError < Exception
|
27
|
-
def initialize(message = 'Computation diverges')
|
28
|
-
super(message)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Wraps an exception raised by a lazy computation.
|
33
|
-
#
|
34
|
-
# The reason we wrap such exceptions in LazyException is that they need to
|
35
|
-
# be distinguishable from similar exceptions which might normally be raised
|
36
|
-
# by whatever strict code we happen to be in at the time.
|
37
|
-
#
|
38
|
-
class LazyException < DivergenceError
|
39
|
-
attr_reader :reason
|
40
|
-
|
41
|
-
def initialize(reason)
|
42
|
-
@reason = reason
|
43
|
-
super "Exception in lazy computation: #{reason} (#{reason.class})"
|
44
|
-
set_backtrace(reason.backtrace.dup) if reason
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# A handle for a promised computation. They are transparent, so that in
|
49
|
-
# most cases, a promise can be used as a proxy for the computation's result
|
50
|
-
# object. The one exception is truth testing -- a promise will always look
|
51
|
-
# true to Ruby, even if the actual result object is nil or false.
|
52
|
-
#
|
53
|
-
# If you want to test the result for truth, get the unwrapped result object
|
54
|
-
# via Kernel.demand.
|
55
|
-
#
|
56
|
-
class Promise
|
57
|
-
alias __class__ class
|
58
|
-
instance_methods.each do |method|
|
59
|
-
undef_method method unless method =~ /^(__|object_|instance_)/
|
60
|
-
end
|
61
|
-
|
62
|
-
def initialize(&computation)
|
63
|
-
@computation = computation
|
64
|
-
end
|
65
|
-
|
66
|
-
def __synchronize__
|
67
|
-
yield
|
68
|
-
end
|
69
|
-
|
70
|
-
# Create this once here, rather than creating a proc object for every
|
71
|
-
# evaluation.
|
72
|
-
DIVERGES = lambda { raise DivergenceError.new }
|
73
|
-
|
74
|
-
# Differentiate inspection of DIVERGES lambda.
|
75
|
-
def DIVERGES.inspect
|
76
|
-
'DIVERGES'
|
77
|
-
end
|
78
|
-
|
79
|
-
def __result__
|
80
|
-
__synchronize__ do
|
81
|
-
if @computation
|
82
|
-
raise LazyException.new(@exception) if @exception
|
83
|
-
|
84
|
-
computation = @computation
|
85
|
-
@computation = DIVERGES
|
86
|
-
|
87
|
-
begin
|
88
|
-
@result = demand(computation.call(self))
|
89
|
-
@computation = nil
|
90
|
-
rescue DivergenceError
|
91
|
-
raise
|
92
|
-
rescue Exception => e
|
93
|
-
@exception = e
|
94
|
-
raise LazyException.new(@exception)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
@result
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def inspect
|
103
|
-
__synchronize__ do
|
104
|
-
if @computation
|
105
|
-
"#<#{__class__} computation=#{@computation.inspect}>"
|
106
|
-
else
|
107
|
-
@result.inspect
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def respond_to?(message)
|
113
|
-
message = message.to_sym
|
114
|
-
message == :__result__ or
|
115
|
-
message == :inspect or
|
116
|
-
__result__.respond_to? message
|
117
|
-
end
|
118
|
-
|
119
|
-
def method_missing(*args, &block)
|
120
|
-
__result__.__send__(*args, &block)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# Thread safe version of Promise class.
|
125
|
-
#
|
126
|
-
class PromiseSafe < Promise
|
127
|
-
def __synchronize__
|
128
|
-
current = Thread.current
|
129
|
-
|
130
|
-
Thread.critical = true
|
131
|
-
unless @computation
|
132
|
-
Thread.critical = false
|
133
|
-
yield
|
134
|
-
else
|
135
|
-
if @owner == current
|
136
|
-
Thread.critical = false
|
137
|
-
raise DivergenceError.new
|
138
|
-
end
|
139
|
-
while @owner
|
140
|
-
Thread.critical = false
|
141
|
-
Thread.pass
|
142
|
-
Thread.critical = true
|
143
|
-
end
|
144
|
-
@owner = current
|
145
|
-
Thread.critical = false
|
146
|
-
|
147
|
-
begin
|
148
|
-
yield
|
149
|
-
ensure
|
150
|
-
@owner = nil
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
# Future class subclasses PromiseSafe.
|
157
|
-
#
|
158
|
-
class Future < PromiseSafe
|
159
|
-
def initialize(&computation)
|
160
|
-
result = nil
|
161
|
-
exception = nil
|
162
|
-
thread = Thread.new do
|
163
|
-
begin
|
164
|
-
result = computation.call(self)
|
165
|
-
rescue Exception => exception
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
super do
|
170
|
-
raise DivergenceError.new if Thread.current == thread
|
171
|
-
thread.join
|
172
|
-
raise exception if exception
|
173
|
-
result
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
module Kernel
|
180
|
-
# The promise() function is used together with demand() to implement
|
181
|
-
# lazy evaluation. It returns a promise to evaluate the provided
|
182
|
-
# block at a future time. Evaluation can be demanded and the block's
|
183
|
-
# result obtained via the demand() function.
|
184
|
-
#
|
185
|
-
# Implicit evaluation is also supported: the first message sent to it will
|
186
|
-
# demand evaluation, after which that message and any subsequent messages
|
187
|
-
# will be forwarded to the result object.
|
188
|
-
#
|
189
|
-
# As an aid to circular programming, the block will be passed a promise
|
190
|
-
# for its own result when it is evaluated. Be careful not to force
|
191
|
-
# that promise during the computation, lest the computation diverge.
|
192
|
-
#
|
193
|
-
def promise(&computation)
|
194
|
-
Lazy::Promise.new(&computation)
|
195
|
-
end
|
196
|
-
|
197
|
-
# Forces the result of a promise to be computed (if necessary) and returns
|
198
|
-
# the bare result object. Once evaluated, the result of the promise will
|
199
|
-
# be cached. Nested promises will be evaluated together, until the first
|
200
|
-
# non-promise result.
|
201
|
-
#
|
202
|
-
# If called on a value that is not a promise, it will simply return it.
|
203
|
-
#
|
204
|
-
def demand(promise)
|
205
|
-
if promise.respond_to? :__result__
|
206
|
-
promise.__result__
|
207
|
-
else
|
208
|
-
promise
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
# Schedules a computation to be run asynchronously in a background thread
|
213
|
-
# and returns a promise for its result. An attempt to demand the result of
|
214
|
-
# the promise will block until the computation finishes.
|
215
|
-
#
|
216
|
-
# As with Kernel.promise, this passes the block a promise for its own result.
|
217
|
-
# Use wisely.
|
218
|
-
#
|
219
|
-
def future(&computation)
|
220
|
-
Lazy::Future.new(&computation)
|
221
|
-
end
|
222
|
-
end
|
@@ -1,41 +0,0 @@
|
|
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 Process
|
21
|
-
|
22
|
-
# Turns the current script into a daemon process
|
23
|
-
# that detaches from the console. It can be shut
|
24
|
-
# down with a TERM signal.
|
25
|
-
#
|
26
|
-
def self.daemon(nochdir = nil, noclose = nil)
|
27
|
-
exit if fork
|
28
|
-
Process.setsid
|
29
|
-
exit if fork
|
30
|
-
Dir.chdir '/' unless nochdir
|
31
|
-
File.umask 0000
|
32
|
-
unless noclose
|
33
|
-
STDIN.reopen '/dev/null'
|
34
|
-
STDOUT.reopen '/dev/null', 'a'
|
35
|
-
STDERR.reopen '/dev/null', 'a'
|
36
|
-
end
|
37
|
-
trap('TERM') { exit }
|
38
|
-
return 0
|
39
|
-
end unless respond_to?(:daemon)
|
40
|
-
end
|
41
|
-
|
data/lib/garcon/utility/ansi.rb
DELETED
@@ -1,199 +0,0 @@
|
|
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
|
-
|
22
|
-
# ANSI Mixin Module
|
23
|
-
#
|
24
|
-
# Standard use is to mix this module into String.
|
25
|
-
#
|
26
|
-
# @example Mix this module into String to enable easy ANSI coloring methods
|
27
|
-
# like:
|
28
|
-
# "bold red".red.bold
|
29
|
-
#
|
30
|
-
# @example Or
|
31
|
-
# "green".green
|
32
|
-
#
|
33
|
-
module ANSI
|
34
|
-
extend self
|
35
|
-
|
36
|
-
# Defines our ANSI color codes
|
37
|
-
ANSI_COLORS = {
|
38
|
-
black: 30,
|
39
|
-
red: 31,
|
40
|
-
green: 32,
|
41
|
-
yellow: 33,
|
42
|
-
blue: 34,
|
43
|
-
magenta: 35,
|
44
|
-
cyan: 36,
|
45
|
-
white: 37
|
46
|
-
}
|
47
|
-
|
48
|
-
# @!method black(string=nil, &block)
|
49
|
-
# Sets the foreground color to black for the supplied string.
|
50
|
-
# @param [String] string The string to operate on.
|
51
|
-
# @yieldreturn [String] The string to operate on.
|
52
|
-
# @return [String] The colored string.
|
53
|
-
#
|
54
|
-
# @!method red(string=nil, &block)
|
55
|
-
# Sets the foreground color to red for the supplied string.
|
56
|
-
# @param [String] string The string to operate on.
|
57
|
-
# @yieldreturn [String] The string to operate on.
|
58
|
-
# @return [String] The colored string.
|
59
|
-
#
|
60
|
-
# @!method green(string=nil, &block)
|
61
|
-
# Sets the foreground color to green for the supplied string.
|
62
|
-
# @param [String] string The string to operate on.
|
63
|
-
# @yieldreturn [String] The string to operate on.
|
64
|
-
# @return [String] The colored string.
|
65
|
-
#
|
66
|
-
# @!method yellow(string=nil, &block)
|
67
|
-
# Sets the foreground color to yellow for the supplied string.
|
68
|
-
# @param [String] string The string to operate on.
|
69
|
-
# @yieldreturn [String] The string to operate on.
|
70
|
-
# @return [String] The colored string.
|
71
|
-
#
|
72
|
-
# @!method blue(string=nil, &block)
|
73
|
-
# Sets the foreground color to blue for the supplied string.
|
74
|
-
# @param [String] string The string to operate on.
|
75
|
-
# @yieldreturn [String] The string to operate on.
|
76
|
-
# @return [String] The colored string.
|
77
|
-
#
|
78
|
-
# @!method magenta(string=nil, &block)
|
79
|
-
# Sets the foreground color to magenta for the supplied string.
|
80
|
-
# @param [String] string The string to operate on.
|
81
|
-
# @yieldreturn [String] The string to operate on.
|
82
|
-
# @return [String] The colored string.
|
83
|
-
#
|
84
|
-
# @!method cyan(string=nil, &block)
|
85
|
-
# Sets the foreground color to cyan for the supplied string.
|
86
|
-
# @param [String] string The string to operate on.
|
87
|
-
# @yieldreturn [String] The string to operate on.
|
88
|
-
# @return [String] The colored string.
|
89
|
-
#
|
90
|
-
# @!method white(string=nil, &block)
|
91
|
-
# Sets the foreground color to white for the supplied string.
|
92
|
-
# @param [String] string The string to operate on.
|
93
|
-
# @yieldreturn [String] The string to operate on.
|
94
|
-
# @return [String] The colored string.
|
95
|
-
|
96
|
-
# Defines our ANSI attribute codes
|
97
|
-
ANSI_ATTRIBUTES = {
|
98
|
-
normal: 0,
|
99
|
-
bold: 1
|
100
|
-
}
|
101
|
-
|
102
|
-
# @!method normal(string=nil, &block)
|
103
|
-
# Sets the foreground color to normal for the supplied string.
|
104
|
-
# @param [String] string The string to operate on.
|
105
|
-
# @yieldreturn [String] The string to operate on.
|
106
|
-
# @return [String] The colored string.
|
107
|
-
#
|
108
|
-
# @!method bold(string=nil, &block)
|
109
|
-
# Sets the foreground color to bold for the supplied string.
|
110
|
-
# @param [String] string The string to operate on.
|
111
|
-
# @yieldreturn [String] The string to operate on.
|
112
|
-
# @return [String] The colored string.
|
113
|
-
|
114
|
-
# Defines a RegEx for stripping ANSI codes from strings
|
115
|
-
ANSI_REGEX = /\e\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/
|
116
|
-
|
117
|
-
# Dynamicly constructs ANSI methods for the color methods based on the ANSI
|
118
|
-
# code hash passed in.
|
119
|
-
#
|
120
|
-
# @param [Hash] hash
|
121
|
-
# A hash where the keys represent the method names and the values are the
|
122
|
-
# ANSI codes.
|
123
|
-
#
|
124
|
-
# @return [Boolean]
|
125
|
-
# True if successful.
|
126
|
-
#
|
127
|
-
def build_ansi_methods(hash)
|
128
|
-
hash.each do |key, value|
|
129
|
-
|
130
|
-
define_method(key) do |string=nil, &block|
|
131
|
-
result = Array.new
|
132
|
-
|
133
|
-
result << %(\e[#{value}m)
|
134
|
-
if block_given?
|
135
|
-
result << block.call
|
136
|
-
elsif string.respond_to?(:to_str)
|
137
|
-
result << string.to_str
|
138
|
-
elsif respond_to?(:to_str)
|
139
|
-
result << to_str
|
140
|
-
else
|
141
|
-
return result
|
142
|
-
end
|
143
|
-
result << %(\e[0m)
|
144
|
-
|
145
|
-
result.join
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
true
|
150
|
-
end
|
151
|
-
|
152
|
-
# Removes ANSI code sequences from a string.
|
153
|
-
#
|
154
|
-
# @param [String] string
|
155
|
-
# The string to operate on.
|
156
|
-
#
|
157
|
-
# @yieldreturn [String]
|
158
|
-
# The string to operate on.
|
159
|
-
#
|
160
|
-
# @return [String]
|
161
|
-
# The supplied string stripped of ANSI codes.
|
162
|
-
#
|
163
|
-
def uncolor(string = nil, &block)
|
164
|
-
if block_given?
|
165
|
-
block.call.to_str.gsub(ANSI_REGEX, '')
|
166
|
-
elsif string.respond_to?(:to_str)
|
167
|
-
string.to_str.gsub(ANSI_REGEX, '')
|
168
|
-
elsif respond_to?(:to_str)
|
169
|
-
to_str.gsub(ANSI_REGEX, '')
|
170
|
-
else
|
171
|
-
''
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def reset(string = nil, &block)
|
176
|
-
result = Array.new
|
177
|
-
|
178
|
-
result << %(\e[2J)
|
179
|
-
if block_given?
|
180
|
-
result << block.call
|
181
|
-
elsif string.respond_to?(:to_str)
|
182
|
-
result << string.to_str
|
183
|
-
elsif respond_to?(:to_str)
|
184
|
-
result << to_str
|
185
|
-
else
|
186
|
-
return result
|
187
|
-
end
|
188
|
-
|
189
|
-
result.join
|
190
|
-
end
|
191
|
-
|
192
|
-
def goto(x=0, y=0)
|
193
|
-
%(\e[#{x};#{y}H)
|
194
|
-
end
|
195
|
-
|
196
|
-
build_ansi_methods(ANSI_COLORS)
|
197
|
-
build_ansi_methods(ANSI_ATTRIBUTES)
|
198
|
-
end
|
199
|
-
end
|
@@ -1,146 +0,0 @@
|
|
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
|
-
# Define equality, equivalence and inspection methods.
|
22
|
-
#
|
23
|
-
class Equalizer
|
24
|
-
|
25
|
-
# Initialize an Equalizer with the given keys.
|
26
|
-
#
|
27
|
-
# Will use the keys with which it is initialized to define #cmp?,
|
28
|
-
# #hash, and #inspect
|
29
|
-
#
|
30
|
-
# @param [String] name
|
31
|
-
#
|
32
|
-
# @param [Array<Symbol>] keys
|
33
|
-
#
|
34
|
-
# @return [undefined]
|
35
|
-
#
|
36
|
-
# @api private
|
37
|
-
def initialize(name, keys = [])
|
38
|
-
@name = name.dup.freeze
|
39
|
-
@keys = keys.dup
|
40
|
-
define_methods
|
41
|
-
include_comparison_methods
|
42
|
-
end
|
43
|
-
|
44
|
-
# Append a key and compile the equality methods.
|
45
|
-
#
|
46
|
-
# @return [Equalizer] self
|
47
|
-
#
|
48
|
-
# @api private
|
49
|
-
def <<(key)
|
50
|
-
@keys << key
|
51
|
-
self
|
52
|
-
end
|
53
|
-
|
54
|
-
private # P R O P R I E T À P R I V A T A Vietato L'accesso
|
55
|
-
|
56
|
-
# Define the equalizer methods based on #keys.
|
57
|
-
#
|
58
|
-
# @return [undefined]
|
59
|
-
#
|
60
|
-
# @api private
|
61
|
-
def define_methods
|
62
|
-
define_cmp_method
|
63
|
-
define_hash_method
|
64
|
-
define_inspect_method
|
65
|
-
end
|
66
|
-
|
67
|
-
# Define an #cmp? method based on the instance's values identified by #keys.
|
68
|
-
#
|
69
|
-
# @return [undefined]
|
70
|
-
#
|
71
|
-
# @api private
|
72
|
-
def define_cmp_method
|
73
|
-
keys = @keys
|
74
|
-
define_method(:cmp?) do |comparator, other|
|
75
|
-
keys.all? { |key| send(key).send(comparator, other.send(key)) }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# Define a #hash method based on the instance's values identified by #keys.
|
80
|
-
#
|
81
|
-
# @return [undefined]
|
82
|
-
#
|
83
|
-
# @api private
|
84
|
-
def define_hash_method
|
85
|
-
keys = @keys
|
86
|
-
define_method(:hash) do
|
87
|
-
keys.map { |key| send(key) }.push(self.class).hash
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Define an inspect method that reports the values of the instance's keys.
|
92
|
-
#
|
93
|
-
# @return [undefined]
|
94
|
-
#
|
95
|
-
# @api private
|
96
|
-
def define_inspect_method
|
97
|
-
name, keys = @name, @keys
|
98
|
-
define_method(:inspect) do
|
99
|
-
"#<#{name}#{keys.map { |key| " #{key}=#{send(key).inspect}" }.join}>"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# Include the #eql? and #== methods
|
104
|
-
#
|
105
|
-
# @return [undefined]
|
106
|
-
#
|
107
|
-
# @api private
|
108
|
-
def include_comparison_methods
|
109
|
-
module_eval { include Methods }
|
110
|
-
end
|
111
|
-
|
112
|
-
# The comparison methods
|
113
|
-
module Methods
|
114
|
-
|
115
|
-
# Compare the object with other object for equality.
|
116
|
-
#
|
117
|
-
# @example
|
118
|
-
# object.eql?(other) # => true or false
|
119
|
-
#
|
120
|
-
# @param [Object] other
|
121
|
-
# the other object to compare with
|
122
|
-
#
|
123
|
-
# @return [Boolean]
|
124
|
-
#
|
125
|
-
# @api public
|
126
|
-
def eql?(other)
|
127
|
-
instance_of?(other.class) && cmp?(__method__, other)
|
128
|
-
end
|
129
|
-
|
130
|
-
# Compare the object with other object for equivalency.
|
131
|
-
#
|
132
|
-
# @example
|
133
|
-
# object == other # => true or false
|
134
|
-
#
|
135
|
-
# @param [Object] other
|
136
|
-
# the other object to compare with
|
137
|
-
#
|
138
|
-
# @return [Boolean]
|
139
|
-
#
|
140
|
-
# @api public
|
141
|
-
def ==(other)
|
142
|
-
other.kind_of?(self.class) && cmp?(__method__, other)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
@@ -1,62 +0,0 @@
|
|
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
|