footing 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/Gemfile.lock +18 -0
- data/README.md +54 -0
- data/lib/extensions/kernel.rb +5 -0
- data/lib/extensions/numeric.rb +26 -0
- data/lib/extensions/object.rb +21 -0
- data/lib/extensions/string.rb +15 -0
- data/lib/footing.rb +62 -0
- metadata +57 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
coderay (1.0.7)
|
5
|
+
method_source (0.8)
|
6
|
+
pry (0.9.10)
|
7
|
+
coderay (~> 1.0.5)
|
8
|
+
method_source (~> 0.8)
|
9
|
+
slop (~> 3.3.1)
|
10
|
+
slop (3.3.2)
|
11
|
+
yard (0.8.2.1)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
ruby
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
pry
|
18
|
+
yard
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Footing
|
2
|
+
|
3
|
+
#### NOTE: this lib is experimental at the moment
|
4
|
+
|
5
|
+
This lib extends native objects with additional functionality.
|
6
|
+
|
7
|
+
## No implicit monkey patching
|
8
|
+
|
9
|
+
**No surprises here.** You must explicitly ask for Footing goodness to be added to your objects.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# some examples of explicit patching
|
13
|
+
Footing.patch!(String)
|
14
|
+
String.ancestors
|
15
|
+
[
|
16
|
+
String,
|
17
|
+
Footing::String::InstanceMethods,
|
18
|
+
Comparable,
|
19
|
+
Object,
|
20
|
+
PP::ObjectMixin,
|
21
|
+
Kernel,
|
22
|
+
BasicObject
|
23
|
+
]
|
24
|
+
|
25
|
+
Footing.patch!(Numeric)
|
26
|
+
[
|
27
|
+
Numeric,
|
28
|
+
Footing::Numeric::InstanceMethods,
|
29
|
+
Comparable,
|
30
|
+
Object,
|
31
|
+
PP::ObjectMixin,
|
32
|
+
Kernel,
|
33
|
+
BasicObject
|
34
|
+
]
|
35
|
+
```
|
36
|
+
|
37
|
+
## Instance patching
|
38
|
+
|
39
|
+
If you don't want to corrupt your entire runtime, you can patch an instance.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
s = "foo"
|
43
|
+
Footing.patch!(s)
|
44
|
+
s.respond_to? :escape # => true
|
45
|
+
"foo".respond_to? :escape # => false
|
46
|
+
```
|
47
|
+
|
48
|
+
## Kick the tires
|
49
|
+
|
50
|
+
* `git clone git://github.com/hopsoft/footing.git`
|
51
|
+
* `cd /path/to/footing`
|
52
|
+
* `bundle`
|
53
|
+
* `./console`
|
54
|
+
* `Footing.patch(String)`
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Footing
|
2
|
+
module Numeric
|
3
|
+
|
4
|
+
module InstanceMethods
|
5
|
+
|
6
|
+
# Returns the percentage that this number is of the passed number.
|
7
|
+
# @example
|
8
|
+
# 8.percent_of(10) # => 80.0
|
9
|
+
# @param [Numeric] number The number to calculate the percentage with
|
10
|
+
def percent_of(number)
|
11
|
+
percent = (self.to_f / number.to_f) * 100 if number > 0
|
12
|
+
percent ||= 0.0
|
13
|
+
end
|
14
|
+
|
15
|
+
# Rounds the number to a certain number of decimal places.
|
16
|
+
# @example
|
17
|
+
# 1.784329.round_to(1) # => 1.8
|
18
|
+
# @param [Numeric] decimal_places The number of decimal places to round to
|
19
|
+
def round_to(decimal_places)
|
20
|
+
(self * 10**decimal_places).round.to_f / 10**decimal_places
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Footing
|
2
|
+
module Object
|
3
|
+
module InstanceMethods
|
4
|
+
|
5
|
+
# Returns the eigen class for the object.
|
6
|
+
def eigen
|
7
|
+
eigen = class << self
|
8
|
+
self
|
9
|
+
end
|
10
|
+
rescue Exception => ex
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
|
14
|
+
# Indicates if the object has an eigen class.
|
15
|
+
def has_eigen?
|
16
|
+
!eigen.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Footing
|
2
|
+
module String
|
3
|
+
module InstanceMethods
|
4
|
+
|
5
|
+
# Escapes a series of chars in the current string.
|
6
|
+
# NOTE: A new string is returned.
|
7
|
+
def escape(*chars)
|
8
|
+
gsub(/(?<!\\)(#{chars.join("|")})/) do |char|
|
9
|
+
"\\" + char
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/footing.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module Footing
|
2
|
+
|
3
|
+
# Patches the object with all applicable Hopsoft extensions and monkey patches.
|
4
|
+
# Works for Modules, Classes, and instances of objects.
|
5
|
+
# @param [Object] obj The object to patch.
|
6
|
+
def self.patch!(obj)
|
7
|
+
if obj.class == Module || obj.class == Class
|
8
|
+
# patching a Module or Class
|
9
|
+
violate(obj)
|
10
|
+
else
|
11
|
+
# patching an instance
|
12
|
+
eigen = nil
|
13
|
+
begin
|
14
|
+
eigen = class << obj
|
15
|
+
self
|
16
|
+
end
|
17
|
+
rescue Exception => ex
|
18
|
+
end
|
19
|
+
|
20
|
+
raise "#{obj.class.name} doesn't support instance patching!" unless eigen
|
21
|
+
violate(eigen)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Violates the object by applying all applicable Footing extensions and monkey patches.
|
28
|
+
# @param [Object] obj The object to voilate.
|
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
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__), "**/*.rb"))].each do |file|
|
56
|
+
next if file =~ /#{__FILE__.gsub(".", "\.")}$/
|
57
|
+
if ENV["FOOTING_DEV"]
|
58
|
+
load file
|
59
|
+
else
|
60
|
+
require file
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: footing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nathan Hopkins
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-23 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! " Footing provides some sanity for monkey patching practices.\n
|
15
|
+
\ It also is a utility lib that contains additional functionality for core objects
|
16
|
+
that you might find useful.\n"
|
17
|
+
email:
|
18
|
+
- natehop@gmail.com
|
19
|
+
executables: []
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- lib/extensions/kernel.rb
|
24
|
+
- lib/extensions/numeric.rb
|
25
|
+
- lib/extensions/object.rb
|
26
|
+
- lib/extensions/string.rb
|
27
|
+
- lib/footing.rb
|
28
|
+
- Gemfile
|
29
|
+
- Gemfile.lock
|
30
|
+
- README.md
|
31
|
+
homepage: https://github.com/hopsoft/footing
|
32
|
+
licenses:
|
33
|
+
- MIT
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.8.10
|
53
|
+
signing_key:
|
54
|
+
specification_version: 3
|
55
|
+
summary: Foundational patching lib.
|
56
|
+
test_files: []
|
57
|
+
has_rdoc:
|