leap 0.5.5 → 0.5.6
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.
- data/README.markdown +28 -0
- data/lib/leap/committee.rb +7 -2
- data/lib/leap/decision.rb +9 -3
- data/lib/leap/quorum.rb +4 -2
- data/lib/leap/register.rb +68 -0
- data/lib/leap/report.rb +6 -4
- data/lib/leap/subject.rb +14 -10
- data/lib/leap/version.rb +1 -1
- data/lib/leap/whip.rb +62 -0
- data/lib/leap.rb +2 -1
- metadata +77 -116
- data/lib/leap/core_ext.rb +0 -11
data/README.markdown
CHANGED
@@ -256,6 +256,34 @@ and then perform your decision with a protocol constraint:
|
|
256
256
|
|
257
257
|
You can name your protocols how ever you want; they just have to match between the quorum assertions and the decision option.
|
258
258
|
|
259
|
+
## Logging
|
260
|
+
|
261
|
+
You can follow along with Leap's computation process by enabling detailed logging with
|
262
|
+
|
263
|
+
``` ruby
|
264
|
+
Leap.log!
|
265
|
+
```
|
266
|
+
|
267
|
+
By default, after being enabled, Leap will log to `Logger.new($stdout)`, per Ruby convention. If you have custom logging needs, use
|
268
|
+
|
269
|
+
``` ruby
|
270
|
+
Leap.log!(my_logging_object)
|
271
|
+
```
|
272
|
+
|
273
|
+
Make sure your logging object (`my_logging_object` in this example) provides a `#info` method.
|
274
|
+
|
275
|
+
## Instrumentation
|
276
|
+
|
277
|
+
You can time Leap activity by enabling instrumentation:
|
278
|
+
|
279
|
+
``` ruby
|
280
|
+
Leap.instrument!
|
281
|
+
```
|
282
|
+
|
283
|
+
Leap uses `Benchmark.measure` internally and displays timings in standard `Benchmark::Tms` format.
|
284
|
+
|
285
|
+
Enabling instrumentation automatically enables logging.
|
286
|
+
|
259
287
|
## Internals
|
260
288
|
|
261
289
|
Normally you'll construct your decision strategies using `decide :foo . . . end` blocks and perform them using the resulting `#foo` methods, but sometimes you'll want access to Leap's internals.
|
data/lib/leap/committee.rb
CHANGED
@@ -46,12 +46,17 @@ module Leap
|
|
46
46
|
# @see Leap::GoalMethodsDocumentation
|
47
47
|
# @return Leap::Report
|
48
48
|
def report(characteristics, considerations, options = {})
|
49
|
-
|
49
|
+
Leap.log.committee "Convening committee", name
|
50
|
+
quorums.each do |quorum|
|
51
|
+
Leap.log.quorum "Assessing quorum", quorum.name
|
50
52
|
next unless quorum.satisfied_by? characteristics and quorum.complies_with? Array.wrap(options[:comply])
|
53
|
+
Leap.log.quorum "Acknowledging quorum", quorum.name
|
51
54
|
if conclusion = quorum.acknowledge(characteristics.slice(*quorum.characteristics), considerations.dup)
|
52
|
-
|
55
|
+
Leap.log.quorum "Success", quorum.name
|
56
|
+
return ::Leap::Report.new(self, quorum, conclusion)
|
53
57
|
end
|
54
58
|
end
|
59
|
+
nil
|
55
60
|
end
|
56
61
|
|
57
62
|
include ::Blockenspiel::DSL
|
data/lib/leap/decision.rb
CHANGED
@@ -33,11 +33,17 @@ module Leap
|
|
33
33
|
# General you won't call this directly, but rather use the dynamically-created method with this decision's goal as its name on the subject instance.
|
34
34
|
# @see Leap::GoalMethodsDocumentation
|
35
35
|
def make(characteristics, *considerations)
|
36
|
+
Leap.log.decision "Leaping to conclusion", goal
|
37
|
+
Leap.log.decision "Initial characteristics: #{characteristics.inspect}", goal
|
36
38
|
options = considerations.extract_options!
|
37
39
|
committees.reject { |c| characteristics.keys.include? c.name }.reverse.inject(Deliberation.new(characteristics)) do |deliberation, committee|
|
38
|
-
|
39
|
-
deliberation.
|
40
|
-
|
40
|
+
Leap.instrument.committee committee.name do
|
41
|
+
if report = committee.report(deliberation.characteristics, considerations, options)
|
42
|
+
Leap.log.committee "Success", committee.name
|
43
|
+
deliberation.reports.unshift report
|
44
|
+
deliberation.characteristics[committee.name] = report.conclusion
|
45
|
+
end
|
46
|
+
Leap.log.decision "Updated characteristics: #{deliberation.characteristics.inspect}", goal
|
41
47
|
end
|
42
48
|
deliberation
|
43
49
|
end
|
data/lib/leap/quorum.rb
CHANGED
@@ -46,8 +46,10 @@ module Leap
|
|
46
46
|
# @param [Hash] characteristics
|
47
47
|
# @return The methodology's result
|
48
48
|
def acknowledge(characteristics, considerations)
|
49
|
-
|
50
|
-
|
49
|
+
Leap.instrument.quorum name do
|
50
|
+
considerations.unshift characteristics
|
51
|
+
process.call(*considerations[0...process.arity])
|
52
|
+
end
|
51
53
|
end
|
52
54
|
|
53
55
|
# All characteristics either needed or wanted by the quorum.
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Leap
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
# Begin logging Leap activity
|
5
|
+
#
|
6
|
+
# @param [optional] logger An object to receive logging signals (currently <tt>#info</tt>). If not provided, Leap will log to <tt>Logger.new($stdout)</tt>.
|
7
|
+
def log!(logger = nil)
|
8
|
+
@@logger = Register.new logger
|
9
|
+
end
|
10
|
+
module_function :log!
|
11
|
+
|
12
|
+
# Returns the logger object if logging is enabled
|
13
|
+
def log?
|
14
|
+
defined?(@@logger)
|
15
|
+
end
|
16
|
+
module_function :log?
|
17
|
+
|
18
|
+
# Returns the logging object--or a "black hole" logger if logging is not enabled.
|
19
|
+
def log
|
20
|
+
log? ? @@logger : @@shredder ||= Shredder.new
|
21
|
+
end
|
22
|
+
module_function :log
|
23
|
+
|
24
|
+
# Facilitates the logging of Leap activity
|
25
|
+
class Register
|
26
|
+
# Creates a <tt>Leap::Register</tt> wrapper around a given (optional) logger. If no logger is provided, Leap assumes <tt>Logger.new($stdout)</tt>.
|
27
|
+
def initialize(logger = nil)
|
28
|
+
@logger = logger || ::Logger.new($stdout)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Log a Leap decision
|
32
|
+
#
|
33
|
+
# @param [String] message The message to be logged
|
34
|
+
# @param [String] name The name of the decision
|
35
|
+
def decision(message, name)
|
36
|
+
record name, message, 0
|
37
|
+
end
|
38
|
+
|
39
|
+
# Log Leap committee action
|
40
|
+
#
|
41
|
+
# @param [String] message The message to be logged
|
42
|
+
# @param [String] name The name of the committee
|
43
|
+
def committee(message, name)
|
44
|
+
record name, message, 1
|
45
|
+
end
|
46
|
+
|
47
|
+
# Log Leap quorum activity
|
48
|
+
#
|
49
|
+
# @param [String] message The message to be logged
|
50
|
+
# @param [String] name The name of the quorum
|
51
|
+
def quorum(message, name)
|
52
|
+
record name, message, 2
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def record(name, message, indents)
|
58
|
+
@logger.info 'Leap ' + (' ' * indents * 2) + " [#{name}] #{message}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# A "black hole" logging class that does absolutely nothing with the logging messages it receives.
|
63
|
+
class Shredder
|
64
|
+
def decision(*) nil end
|
65
|
+
def committee(*) nil end
|
66
|
+
def quorum(*) nil end
|
67
|
+
end
|
68
|
+
end
|
data/lib/leap/report.rb
CHANGED
@@ -15,13 +15,15 @@ module Leap
|
|
15
15
|
#
|
16
16
|
# This is generally called in the midst of <tt>Leap::Committee#report</tt>
|
17
17
|
# @param [Leap::Committee] The committee that produced the report.
|
18
|
+
# @param [Leap::Quorum] The responsible quorum.
|
19
|
+
# @param [any] The conclusion.
|
18
20
|
# @param [Hash] report A single-pair hash containing the responsible quorum and its conclusion.
|
19
|
-
# @raise [ArgumentError] Raised for anonymous reports
|
20
|
-
def initialize(committee,
|
21
|
+
# @raise [ArgumentError] Raised for anonymous reports.
|
22
|
+
def initialize(committee, quorum, conclusion)
|
21
23
|
raise ArgumentError, 'Reports must identify themselves' unless committee.is_a?(::Leap::Committee)
|
22
24
|
@committee = committee
|
23
|
-
|
24
|
-
@
|
25
|
+
@quorum = quorum
|
26
|
+
@conclusion = conclusion
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
data/lib/leap/subject.rb
CHANGED
@@ -50,16 +50,20 @@ module Leap
|
|
50
50
|
decisions[goal] = ::Leap::Decision.new goal, options
|
51
51
|
Blockenspiel.invoke(blk, decisions[goal])
|
52
52
|
define_method goal do |*considerations|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
Leap.instrument.decision goal do
|
54
|
+
@deliberations ||= {}
|
55
|
+
decision = self.class.decisions[goal]
|
56
|
+
characteristics = send(decision.signature_method)
|
57
|
+
@deliberations[goal] = decision.make(characteristics, *considerations)
|
58
|
+
if decision.mastered? and @deliberations[goal][goal].nil?
|
59
|
+
raise ::Leap::NoSolutionError, :goal => goal, :deliberation => @deliberations[goal]
|
60
|
+
elsif decision.mastered?
|
61
|
+
Leap.log.decision "Success", goal
|
62
|
+
@deliberations[goal][goal]
|
63
|
+
else
|
64
|
+
Leap.log.decision "Success", goal
|
65
|
+
@deliberations[goal]
|
66
|
+
end
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
data/lib/leap/version.rb
CHANGED
data/lib/leap/whip.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module Leap
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
# Begin instrumenting Leap activity. Automatically enables logging.
|
5
|
+
def instrument!
|
6
|
+
Leap.log! unless Leap.log?
|
7
|
+
@@whip = Whip.new
|
8
|
+
end
|
9
|
+
module_function :instrument!
|
10
|
+
|
11
|
+
# Returns the instrumentation object if enabled
|
12
|
+
def instrument?
|
13
|
+
defined?(@@whip)
|
14
|
+
end
|
15
|
+
module_function :instrument?
|
16
|
+
|
17
|
+
# Returns the instrumentation object--or a "pass-through" substitute if not enabled
|
18
|
+
def instrument(&blk)
|
19
|
+
instrument? ? @@whip : @@bystander ||= Bystander.new
|
20
|
+
end
|
21
|
+
module_function :instrument
|
22
|
+
|
23
|
+
# Facilitates the instrumentation of Leap activity
|
24
|
+
class Whip
|
25
|
+
# Instrument a Leap decision
|
26
|
+
#
|
27
|
+
# @param [String, Symbol] name The decision's name
|
28
|
+
# @param [Proc] blk A proc wrapping the decision to instrument
|
29
|
+
def decision(name, &blk)
|
30
|
+
Leap.log.decision instrument(&blk), name
|
31
|
+
end
|
32
|
+
|
33
|
+
# Instrument Leap committee activity
|
34
|
+
#
|
35
|
+
# @param [String, Symbol] name The committee's name
|
36
|
+
# @param [Proc] blk A proc wrapping the committee convention to instrument
|
37
|
+
def committee(name, &blk)
|
38
|
+
Leap.log.committee instrument(&blk), name
|
39
|
+
end
|
40
|
+
|
41
|
+
# Instrument Leap quorum activity
|
42
|
+
#
|
43
|
+
# @param [String, Symbol] name The quorum's name
|
44
|
+
# @param [Proc] blk A proc wrapping the quorum activity to instrument
|
45
|
+
def quorum(name, &blk)
|
46
|
+
Leap.log.quorum instrument(&blk), name
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def instrument(&blk)
|
52
|
+
'Completed in ' + Benchmark.measure(&blk).format('%10.6r').gsub(/[()]/,'').strip + 's'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Allows Leap activity to continue uninstrumented
|
57
|
+
class Bystander
|
58
|
+
def decision(_, &blk) yield end
|
59
|
+
def committee(_, &blk) yield end
|
60
|
+
def quorum(_, &blk) yield end
|
61
|
+
end
|
62
|
+
end
|
data/lib/leap.rb
CHANGED
@@ -8,7 +8,6 @@ require 'active_support/version'
|
|
8
8
|
end if ActiveSupport::VERSION::MAJOR == 3
|
9
9
|
require 'blockenspiel'
|
10
10
|
|
11
|
-
require 'leap/core_ext'
|
12
11
|
require 'leap/subject'
|
13
12
|
require 'leap/committee'
|
14
13
|
require 'leap/quorum'
|
@@ -19,6 +18,8 @@ require 'leap/implicit_attributes'
|
|
19
18
|
require 'leap/no_solution_error'
|
20
19
|
require 'leap/deliberations_accessor'
|
21
20
|
require 'leap/goal_methods_documentation'
|
21
|
+
require 'leap/register'
|
22
|
+
require 'leap/whip'
|
22
23
|
|
23
24
|
# Leap is a system for: 1) describing decision-making strategies used to determine a potentially non-obvious attribute of an object and 2)
|
24
25
|
# computing that attribute by choosing appropriate strategies given a specific set of input information
|
metadata
CHANGED
@@ -1,137 +1,101 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: leap
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.6
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 5
|
9
|
-
- 5
|
10
|
-
version: 0.5.5
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Andy Rossmeissl
|
14
9
|
- Seamus Abshere
|
15
10
|
- Derek Kastner
|
16
11
|
autorequire:
|
17
12
|
bindir: bin
|
18
13
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
date: 2011-12-15 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
23
17
|
name: charisma
|
24
|
-
|
18
|
+
requirement: &10759248 !ruby/object:Gem::Requirement
|
25
19
|
none: false
|
26
|
-
requirements:
|
20
|
+
requirements:
|
27
21
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 23
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
- 2
|
33
|
-
- 0
|
22
|
+
- !ruby/object:Gem::Version
|
34
23
|
version: 0.2.0
|
35
|
-
prerelease: false
|
36
24
|
type: :development
|
37
|
-
|
38
|
-
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *10759248
|
27
|
+
- !ruby/object:Gem::Dependency
|
39
28
|
name: shoulda
|
40
|
-
|
29
|
+
requirement: &10758996 !ruby/object:Gem::Requirement
|
41
30
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
segments:
|
47
|
-
- 0
|
48
|
-
version: "0"
|
49
|
-
prerelease: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
50
35
|
type: :development
|
51
|
-
|
52
|
-
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *10758996
|
38
|
+
- !ruby/object:Gem::Dependency
|
53
39
|
name: bueller
|
54
|
-
|
40
|
+
requirement: &10758720 !ruby/object:Gem::Requirement
|
55
41
|
none: false
|
56
|
-
requirements:
|
57
|
-
- -
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
|
60
|
-
segments:
|
61
|
-
- 0
|
62
|
-
version: "0"
|
63
|
-
prerelease: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
64
46
|
type: :development
|
65
|
-
|
66
|
-
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *10758720
|
49
|
+
- !ruby/object:Gem::Dependency
|
67
50
|
name: blockenspiel
|
68
|
-
|
51
|
+
requirement: &10758420 !ruby/object:Gem::Requirement
|
69
52
|
none: false
|
70
|
-
requirements:
|
71
|
-
- -
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
hash: 23
|
74
|
-
segments:
|
75
|
-
- 0
|
76
|
-
- 3
|
77
|
-
- 2
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
78
56
|
version: 0.3.2
|
79
|
-
prerelease: false
|
80
57
|
type: :runtime
|
81
|
-
|
82
|
-
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *10758420
|
60
|
+
- !ruby/object:Gem::Dependency
|
83
61
|
name: activesupport
|
84
|
-
|
62
|
+
requirement: &10758120 !ruby/object:Gem::Requirement
|
85
63
|
none: false
|
86
|
-
requirements:
|
87
|
-
- -
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
hash: 11
|
90
|
-
segments:
|
91
|
-
- 2
|
92
|
-
- 3
|
93
|
-
- 4
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
94
67
|
version: 2.3.4
|
95
|
-
prerelease: false
|
96
68
|
type: :runtime
|
97
|
-
|
98
|
-
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: *10758120
|
71
|
+
- !ruby/object:Gem::Dependency
|
99
72
|
name: i18n
|
100
|
-
|
73
|
+
requirement: &10757892 !ruby/object:Gem::Requirement
|
101
74
|
none: false
|
102
|
-
requirements:
|
103
|
-
- -
|
104
|
-
- !ruby/object:Gem::Version
|
105
|
-
|
106
|
-
segments:
|
107
|
-
- 0
|
108
|
-
version: "0"
|
109
|
-
prerelease: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
110
79
|
type: :runtime
|
111
|
-
|
112
|
-
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: *10757892
|
82
|
+
- !ruby/object:Gem::Dependency
|
113
83
|
name: builder
|
114
|
-
|
84
|
+
requirement: &10757616 !ruby/object:Gem::Requirement
|
115
85
|
none: false
|
116
|
-
requirements:
|
117
|
-
- -
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
|
120
|
-
segments:
|
121
|
-
- 0
|
122
|
-
version: "0"
|
123
|
-
prerelease: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
124
90
|
type: :runtime
|
125
|
-
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: *10757616
|
126
93
|
description: Leap to conclusions
|
127
94
|
email: andy@rossmeissl.net
|
128
95
|
executables: []
|
129
|
-
|
130
96
|
extensions: []
|
131
|
-
|
132
97
|
extra_rdoc_files: []
|
133
|
-
|
134
|
-
files:
|
98
|
+
files:
|
135
99
|
- .document
|
136
100
|
- .gitignore
|
137
101
|
- Gemfile
|
@@ -140,7 +104,6 @@ files:
|
|
140
104
|
- leap.gemspec
|
141
105
|
- lib/leap.rb
|
142
106
|
- lib/leap/committee.rb
|
143
|
-
- lib/leap/core_ext.rb
|
144
107
|
- lib/leap/decision.rb
|
145
108
|
- lib/leap/deliberation.rb
|
146
109
|
- lib/leap/deliberations_accessor.rb
|
@@ -148,43 +111,41 @@ files:
|
|
148
111
|
- lib/leap/implicit_attributes.rb
|
149
112
|
- lib/leap/no_solution_error.rb
|
150
113
|
- lib/leap/quorum.rb
|
114
|
+
- lib/leap/register.rb
|
151
115
|
- lib/leap/report.rb
|
152
116
|
- lib/leap/subject.rb
|
153
117
|
- lib/leap/version.rb
|
118
|
+
- lib/leap/whip.rb
|
154
119
|
- test/helper.rb
|
155
120
|
- test/test_leap.rb
|
156
121
|
homepage: http://github.com/rossmeissl/leap
|
157
122
|
licenses: []
|
158
|
-
|
159
123
|
post_install_message:
|
160
124
|
rdoc_options: []
|
161
|
-
|
162
|
-
require_paths:
|
125
|
+
require_paths:
|
163
126
|
- lib
|
164
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
165
128
|
none: false
|
166
|
-
requirements:
|
167
|
-
- -
|
168
|
-
- !ruby/object:Gem::Version
|
169
|
-
|
170
|
-
segments:
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
segments:
|
171
134
|
- 0
|
172
|
-
|
173
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
hash: 744383405
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
137
|
none: false
|
175
|
-
requirements:
|
176
|
-
- -
|
177
|
-
- !ruby/object:Gem::Version
|
178
|
-
|
179
|
-
segments:
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
segments:
|
180
143
|
- 0
|
181
|
-
|
144
|
+
hash: 744383405
|
182
145
|
requirements: []
|
183
|
-
|
184
146
|
rubyforge_project:
|
185
|
-
rubygems_version: 1.8.
|
147
|
+
rubygems_version: 1.8.11
|
186
148
|
signing_key:
|
187
149
|
specification_version: 3
|
188
150
|
summary: A heuristics engine for your Ruby objects
|
189
151
|
test_files: []
|
190
|
-
|
data/lib/leap/core_ext.rb
DELETED