footing 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+
3
+ group :development do
4
+ gem "pry"
5
+ gem "yard"
6
+ end
@@ -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
@@ -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,5 @@
1
+ module Footing
2
+ module Kernel
3
+
4
+ end
5
+ end
@@ -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
@@ -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: