footing 0.0.1 → 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.
- data/README.md +23 -9
- data/lib/extensions/numeric.rb +4 -0
- data/lib/extensions/object.rb +5 -0
- data/lib/extensions/string.rb +5 -0
- data/lib/footing.rb +26 -42
- metadata +2 -2
data/README.md
CHANGED
@@ -2,33 +2,39 @@
|
|
2
2
|
|
3
3
|
#### NOTE: this lib is experimental at the moment
|
4
4
|
|
5
|
-
|
5
|
+
Footing provides some sanity for monkey patching practices.
|
6
|
+
It's also a utility lib that contains additional functionality for core objects that you might find useful.
|
6
7
|
|
7
8
|
## No implicit monkey patching
|
8
9
|
|
9
|
-
**No surprises here.** You must explicitly
|
10
|
+
**No surprises here.** You must explicitly patch.
|
10
11
|
|
11
12
|
```ruby
|
12
13
|
# some examples of explicit patching
|
13
|
-
Footing.patch!
|
14
|
+
Footing.patch! String, Footing::String
|
15
|
+
Footing.patch! Numeric, Footing::Numeric
|
16
|
+
```
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
# instrospect the changes
|
14
20
|
String.ancestors
|
15
21
|
[
|
16
22
|
String,
|
17
23
|
Footing::String::InstanceMethods,
|
24
|
+
Footing::String,
|
18
25
|
Comparable,
|
19
26
|
Object,
|
20
|
-
PP::ObjectMixin,
|
21
27
|
Kernel,
|
22
28
|
BasicObject
|
23
29
|
]
|
24
30
|
|
25
|
-
|
31
|
+
Numeric.ancestors
|
26
32
|
[
|
27
33
|
Numeric,
|
28
34
|
Footing::Numeric::InstanceMethods,
|
35
|
+
Footing::Numeric,
|
29
36
|
Comparable,
|
30
37
|
Object,
|
31
|
-
PP::ObjectMixin,
|
32
38
|
Kernel,
|
33
39
|
BasicObject
|
34
40
|
]
|
@@ -36,19 +42,27 @@ Footing.patch!(Numeric)
|
|
36
42
|
|
37
43
|
## Instance patching
|
38
44
|
|
39
|
-
If you don't want to corrupt
|
45
|
+
If you don't want to corrupt the entire runtime, you can patch an instance.
|
40
46
|
|
41
47
|
```ruby
|
42
48
|
s = "foo"
|
43
|
-
Footing.patch!
|
49
|
+
Footing.patch! s, Footing::String
|
44
50
|
s.respond_to? :escape # => true
|
45
51
|
"foo".respond_to? :escape # => false
|
46
52
|
```
|
47
53
|
|
54
|
+
## Shotgun patching
|
55
|
+
|
56
|
+
For the lazy and brave, you can also patch everything at once.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
Footing.patch_all!
|
60
|
+
```
|
61
|
+
|
48
62
|
## Kick the tires
|
49
63
|
|
50
64
|
* `git clone git://github.com/hopsoft/footing.git`
|
51
65
|
* `cd /path/to/footing`
|
52
66
|
* `bundle`
|
53
67
|
* `./console`
|
54
|
-
* `Footing.patch
|
68
|
+
* `Footing.patch String, Footing::String`
|
data/lib/extensions/numeric.rb
CHANGED
data/lib/extensions/object.rb
CHANGED
data/lib/extensions/string.rb
CHANGED
data/lib/footing.rb
CHANGED
@@ -1,55 +1,39 @@
|
|
1
1
|
module Footing
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
# Applies all Footing patches.
|
4
|
+
def self.patch_all!
|
5
|
+
list = [
|
6
|
+
"Kernel",
|
7
|
+
"Object",
|
8
|
+
"String",
|
9
|
+
"Numeric"
|
10
|
+
]
|
11
|
+
|
12
|
+
list.each do |name|
|
13
|
+
context = Object.const_get(name)
|
14
|
+
footing = Footing.const_get(name)
|
15
|
+
patch! context, footing
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Patches a Module or instance with the given extension.
|
20
|
+
# @param [Module, Object] obj The Module or instance to patch.
|
21
|
+
# @param [Module] extension The Module that contains the patches.
|
22
|
+
def self.patch!(obj, extension)
|
23
|
+
context = obj if obj.is_a? Module
|
24
|
+
if context.nil?
|
13
25
|
begin
|
14
|
-
|
26
|
+
context = class << obj
|
15
27
|
self
|
16
28
|
end
|
17
29
|
rescue Exception => ex
|
18
30
|
end
|
19
|
-
|
20
|
-
raise "#{obj.class.name} doesn't support instance patching!" unless eigen
|
21
|
-
violate(eigen)
|
22
31
|
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
def self.violate(obj)
|
30
|
-
chain = obj.ancestors.reduce({}) do |memo, ancestor|
|
31
|
-
memo[ancestor] = ancestor.name.split("::")
|
32
|
-
memo
|
33
|
-
end
|
34
|
-
chain[obj] = obj.name.split("::") if obj.name
|
35
|
-
|
36
|
-
chain.each do |ancestor, names|
|
37
|
-
context = obj
|
38
|
-
footing_context = Footing
|
39
|
-
|
40
|
-
names.each do |name|
|
41
|
-
const = context.const_get(name)
|
42
|
-
footing_const = footing_context.const_get(name) if footing_context.const_defined?(name) break unless footing_const.name =~ /^Footing/
|
43
|
-
break if footing_const.name =~ /^(Footing|Footing::Object)$/
|
44
|
-
const.extend footing_const::ClassMethods if defined?(footing_const::ClassMethods)
|
45
|
-
const.send :include, footing_const::InstanceMethods if defined?(footing_const::InstanceMethods)
|
46
|
-
context = const
|
47
|
-
footing_context = footing_const
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
true
|
33
|
+
raise "#{obj.class.name} doesn't support patching!" unless context
|
34
|
+
context.send :include, extension
|
52
35
|
end
|
36
|
+
|
53
37
|
end
|
54
38
|
|
55
39
|
Dir[File.expand_path(File.join(File.dirname(__FILE__), "**/*.rb"))].each do |file|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: footing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ cert_chain: []
|
|
12
12
|
date: 2012-07-23 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! " Footing provides some sanity for monkey patching practices.\n
|
15
|
-
\ It also
|
15
|
+
\ It's also a utility lib that contains additional functionality for core objects
|
16
16
|
that you might find useful.\n"
|
17
17
|
email:
|
18
18
|
- natehop@gmail.com
|