base 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,5 @@
1
+ # base Changelog
2
+
3
+ ### 0.0.1 / 2011-09-01
4
+
5
+ * Project Created
@@ -0,0 +1,6 @@
1
+ CHANGELOG.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ lib/base.rb
6
+ spec/base_spec.rb
@@ -0,0 +1,39 @@
1
+ # Base
2
+
3
+ * http://github.com/garybernhardt/base
4
+
5
+ ## DESCRIPTION:
6
+
7
+ People love Base classes! They have tons of methods waiting to be used. Just check out ActiveRecord::Base's method list:
8
+
9
+ >> ActiveRecord::Base.methods.length
10
+ => 530
11
+
12
+ But why stop there? Why not have even more methods? In fact, let's put EVERY METHOD on one Base class!
13
+
14
+ So I did. It's called Base. Just subclass it and feel free to directly reference any class method, instance method, or constant defined on any module or class in the system. Like this:
15
+
16
+ class Cantaloupe < Base
17
+ def embiggen
18
+ encode64(deflate(SEPARATOR))
19
+ end
20
+ end
21
+
22
+ >> Cantaloupe.new.embiggen
23
+ => "eJzTBwAAMAAw\n"
24
+
25
+ See that `embiggen` method calling encode64 and deflate methods? Those come from the `Base64` and `Zlib` modules. And the `SEPARATOR` constant is defined in `File`. Base don't care where it's defined! Base will call it!
26
+
27
+ By the way, remember those 530 ActiveRecord methods? That's amateur stuff. Check out Base loaded inside a Rails app:
28
+
29
+ >> Base.new.methods.count
30
+ => 6947
31
+
32
+ It's so badass that it takes FIVE SECONDS just to answer that question!
33
+
34
+ ## SHOULD I USE THIS IN MY SYSTEM?
35
+
36
+ Yes. I am being completely serious. You should.
37
+
38
+ Definitely.
39
+
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+
4
+ Hoe.plugin :git, :doofus, :seattlerb
5
+
6
+ Hoe.spec 'base' do
7
+ developer 'Gary Bernhardt', 'gary.bernhardt@gmail.com'
8
+
9
+ ### Use markdown for changelog and readme
10
+ self.history_file = 'CHANGELOG.md'
11
+ self.readme_file = 'README.md'
12
+
13
+ ### Test with rspec
14
+ self.extra_dev_deps << [ 'rspec', '>= 2.1.0' ]
15
+ self.testlib = :rspec
16
+
17
+ ### build zip files too
18
+ self.need_zip = true
19
+ end
20
+
21
+ # add pointer so gem test works. bleh.
22
+ task :test => [:spec]
23
+
@@ -0,0 +1,95 @@
1
+ class Base
2
+ VERSION = "0.0.1"
3
+
4
+ def initialize *args, &block
5
+ super *args, &block
6
+ end
7
+
8
+ def self.const_missing name
9
+ name = name.to_s
10
+ all_modules.each do |mod|
11
+ mod.constants.each do |constant|
12
+ return mod.const_get(constant) if constant == name
13
+ end
14
+ end
15
+ super
16
+ end
17
+
18
+ def self.all_modules
19
+ modules = []
20
+ ObjectSpace.each_object(Module) do |mod|
21
+ modules << mod if should_extract_from?(mod)
22
+ end
23
+ modules << Kernel
24
+ modules
25
+ end
26
+
27
+ def self.should_extract_from?(mod)
28
+ return false if (mod < Base || mod == Base || mod.is_a?(Base))
29
+ return mod.is_a?(Module) && mod != Kernel
30
+ end
31
+
32
+ def self.method_missing name, *args, &block
33
+ call_method(self, name, args, block)
34
+ end
35
+
36
+ def method_missing name, *args, &block
37
+ self.class.call_method(self, name, args, block)
38
+ end
39
+
40
+ def self.call_method(object, name, args, block)
41
+ name_string = name.to_s
42
+
43
+ all_modules.each do |mod|
44
+ if mod.respond_to?(name)
45
+ return mod.send name, *args, &block
46
+ elsif mod.instance_methods.include?(name_string)
47
+ return call_instance_method(mod, name, args, block)
48
+ end
49
+ end
50
+
51
+ # 1. The world is all that is the case.
52
+ # 2. We failed to find a method to call.
53
+ # 2.1. So we need to call method_missing.
54
+ # 2.1.1. We can't just super it because we're not in method_missing.
55
+ # 2.1.1.1. We're not in method_missing because there are two of them
56
+ # (self and instance) that need to share this code.
57
+ # 2.1.1.2. We need to call the method that would be called if we said
58
+ # "super" in the object's method_missing.
59
+ # 2.1.1.2.1. Which is its class's superclass's method_missing method
60
+ # object.
61
+ Object.instance_method(:method_missing).bind(object).call(name, *args, &block)
62
+ end
63
+
64
+ def self.call_instance_method(mod, name, args, block)
65
+ if mod.is_a? Class
66
+ klass = Class.new(mod)
67
+ else
68
+ klass = Class.new { include mod }
69
+ end
70
+ return klass.new.send name, *args, &block
71
+ end
72
+
73
+ def self.methods
74
+ (giant_method_list_including_object(self) + super).uniq
75
+ end
76
+
77
+ def methods
78
+ (self.class.giant_method_list_including_object(self) + super).uniq
79
+ end
80
+
81
+ # INHERIT ALL THE METHODS!
82
+ def self.giant_method_list_including_object(object)
83
+ methods = []
84
+ all_modules.each_with_index do |m, i|
85
+ # Don't recurse into other Base objects' "methods" method
86
+ if m.is_a?(Base) || m < Base || m == Base
87
+ []
88
+ else
89
+ methods += m.methods + m.instance_methods
90
+ end
91
+ end
92
+ methods
93
+ end
94
+ end
95
+
@@ -0,0 +1,77 @@
1
+ require 'lib/base'
2
+
3
+ module NormalModule
4
+ Something = 5
5
+
6
+ def self.a_class_method; 6; end
7
+ def a_module_method; 7; end
8
+ end
9
+
10
+ class NormalClass
11
+ def an_instance_method; 8; end
12
+ end
13
+
14
+ class InheritsFromBase < Base
15
+ end
16
+
17
+ describe Base do
18
+ it "should have other modules' constants" do
19
+ InheritsFromBase::Something.should == NormalModule::Something
20
+ end
21
+
22
+ it "still throws NameError if the constant doesn't exist" do
23
+ expect do
24
+ InheritsFromBase::SomethingElse
25
+ end.to raise_error NameError
26
+ end
27
+
28
+ it "should have other modules' class methods" do
29
+ InheritsFromBase.a_class_method.should == 6
30
+ end
31
+
32
+ it "should have other modules' instance methods" do
33
+ InheritsFromBase.a_module_method.should == 7
34
+ end
35
+
36
+ it "should have other classes' instance methods" do
37
+ InheritsFromBase.an_instance_method.should == 8
38
+ end
39
+
40
+ it "still throws NoMethodError if the method doesn't exist" do
41
+ expect do
42
+ InheritsFromBase.not_a_method
43
+ end.to raise_error NoMethodError
44
+ end
45
+
46
+ it "should have other modules' methods as instance methods" do
47
+ InheritsFromBase.new.a_class_method.should == 6
48
+ end
49
+
50
+ it "includes methods from the standard library" do
51
+ InheritsFromBase.inflate(InheritsFromBase.deflate("x")).should == "x"
52
+ end
53
+
54
+ it "checks Kernel last" do
55
+ InheritsFromBase.all_modules.last.should == Kernel
56
+ end
57
+
58
+ its "instance NoMethodErrors should reference the instance" do
59
+ expect do
60
+ InheritsFromBase.new.not_a_method
61
+ end.to raise_error(NoMethodError, /undefined method `not_a_method' for #<InheritsFromBase/)
62
+ end
63
+
64
+ it "lists a lot of class methods" do
65
+ InheritsFromBase.methods.count.should > 1500
66
+ end
67
+
68
+ it "lists a lot of instance methods" do
69
+ InheritsFromBase.new.methods.count.should > 1500
70
+ end
71
+
72
+ it "doesn't list duplicate methods" do
73
+ methods = InheritsFromBase.methods
74
+ methods.uniq.should == methods
75
+ end
76
+ end
77
+
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: base
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Gary Bernhardt
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-09-02 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 11
29
+ segments:
30
+ - 2
31
+ - 1
32
+ - 0
33
+ version: 2.1.0
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: hoe
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 27
45
+ segments:
46
+ - 2
47
+ - 12
48
+ version: "2.12"
49
+ type: :development
50
+ version_requirements: *id002
51
+ description: |-
52
+ People love Base classes! They have tons of methods waiting to be used. Just check out ActiveRecord::Base's method list:
53
+
54
+ >> ActiveRecord::Base.methods.length
55
+ => 530
56
+
57
+ But why stop there? Why not have even more methods? In fact, let's put EVERY METHOD on one Base class!
58
+
59
+ So I did. It's called Base. Just subclass it and feel free to directly reference any class method, instance method, or constant defined on any module or class in the system. Like this:
60
+
61
+ class Cantaloupe < Base
62
+ def embiggen
63
+ encode64(deflate(SEPARATOR))
64
+ end
65
+ end
66
+
67
+ >> Cantaloupe.new.embiggen
68
+ => "eJzTBwAAMAAw\n"
69
+
70
+ See that `embiggen` method calling encode64 and deflate methods? Those come from the `Base64` and `Zlib` modules. And the `SEPARATOR` constant is defined in `File`. Base don't care where it's defined! Base will call it!
71
+
72
+ By the way, remember those 530 ActiveRecord methods? That's amateur stuff. Check out Base loaded inside a Rails app:
73
+
74
+ >> Base.new.methods.count
75
+ => 6947
76
+
77
+ It's so badass that it takes FIVE SECONDS just to answer that question!
78
+ email:
79
+ - gary.bernhardt@gmail.com
80
+ executables: []
81
+
82
+ extensions: []
83
+
84
+ extra_rdoc_files:
85
+ - Manifest.txt
86
+ files:
87
+ - CHANGELOG.md
88
+ - Manifest.txt
89
+ - README.md
90
+ - Rakefile
91
+ - lib/base.rb
92
+ - spec/base_spec.rb
93
+ - .gemtest
94
+ homepage: http://github.com/garybernhardt/base
95
+ licenses: []
96
+
97
+ post_install_message:
98
+ rdoc_options:
99
+ - --main
100
+ - README.md
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project: base
124
+ rubygems_version: 1.8.8
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: People love Base classes! They have tons of methods waiting to be used
128
+ test_files: []
129
+