base 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 +27 -7
- data/lib/base.rb +23 -30
- data/spec/base_spec.rb +19 -6
- metadata +13 -11
data/README.md
CHANGED
@@ -4,12 +4,12 @@
|
|
4
4
|
|
5
5
|
## DESCRIPTION:
|
6
6
|
|
7
|
-
People love Base classes! They have tons of methods waiting to be used. Just check out ActiveRecord::Base's method list:
|
7
|
+
People love Base classes! They have tons of methods waiting to be used. Just check out `ActiveRecord::Base`'s method list:
|
8
8
|
|
9
9
|
>> ActiveRecord::Base.methods.length
|
10
|
-
=> 530
|
10
|
+
=> 530
|
11
11
|
|
12
|
-
But why stop there? Why not have even more methods? In fact, let's put
|
12
|
+
But why stop there? Why not have even more methods? In fact, let's put *every method* on one Base class!
|
13
13
|
|
14
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
15
|
|
@@ -20,16 +20,36 @@ So I did. It's called Base. Just subclass it and feel free to directly reference
|
|
20
20
|
end
|
21
21
|
|
22
22
|
>> Cantaloupe.new.embiggen
|
23
|
-
=> "eJzTBwAAMAAw\n"
|
23
|
+
=> "eJzTBwAAMAAw\n"
|
24
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
|
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 calls what it wants!
|
26
26
|
|
27
27
|
By the way, remember those 530 ActiveRecord methods? That's amateur stuff. Check out Base loaded inside a Rails app:
|
28
28
|
|
29
29
|
>> Base.new.methods.count
|
30
|
-
=> 6947
|
30
|
+
=> 6947
|
31
31
|
|
32
|
-
It's so badass that it takes
|
32
|
+
It's so badass that it takes *five seconds* just to answer that question!
|
33
|
+
|
34
|
+
Base is just craaazzy! It's the most fearless class in all of Ruby. Base doesn't afraid of anything!
|
35
|
+
|
36
|
+
## PRAISE FOR BASE
|
37
|
+
|
38
|
+
> @garybernhardt @kantrn ... Can't tell if joke or just Ruby.
|
39
|
+
|
40
|
+
\- @[shazow](https://twitter.com/#!/shazow/status/109464406739521536)
|
41
|
+
|
42
|
+
> @garybernhardt y u troll soooo good? ;-)
|
43
|
+
|
44
|
+
\- @[amerine](https://twitter.com/#!/amerine/status/109453913572392960)
|
45
|
+
|
46
|
+
> @garybernhardt Imagine all the things you could have done doing not that
|
47
|
+
|
48
|
+
\- @[mrb_bk](https://twitter.com/#!/mrb_bk/status/109452972966154240)
|
49
|
+
|
50
|
+
> @garybernhardt I hate you.
|
51
|
+
|
52
|
+
\- @[jmazzi](https://twitter.com/#!/jmazzi/status/109451655040352256)
|
33
53
|
|
34
54
|
## SHOULD I USE THIS IN MY SYSTEM?
|
35
55
|
|
data/lib/base.rb
CHANGED
@@ -1,24 +1,16 @@
|
|
1
1
|
class Base
|
2
|
-
VERSION = "0.0.
|
3
|
-
|
4
|
-
def initialize *args, &block
|
5
|
-
super *args, &block
|
6
|
-
end
|
2
|
+
VERSION = "0.0.2"
|
7
3
|
|
8
4
|
def self.const_missing name
|
9
|
-
name = name.to_s
|
10
5
|
all_modules.each do |mod|
|
11
|
-
mod.
|
12
|
-
return mod.const_get(constant) if constant == name
|
13
|
-
end
|
6
|
+
return mod.const_get(name) if mod.const_defined?(name)
|
14
7
|
end
|
15
8
|
super
|
16
9
|
end
|
17
10
|
|
18
11
|
def self.all_modules
|
19
|
-
modules =
|
20
|
-
|
21
|
-
modules << mod if should_extract_from?(mod)
|
12
|
+
modules = ObjectSpace.each_object(Module).select do |mod|
|
13
|
+
should_extract_from?(mod)
|
22
14
|
end
|
23
15
|
modules << Kernel
|
24
16
|
modules
|
@@ -30,11 +22,11 @@ class Base
|
|
30
22
|
end
|
31
23
|
|
32
24
|
def self.method_missing name, *args, &block
|
33
|
-
call_method(self, name, args, block)
|
25
|
+
call_method(self, name, args, block) { super }
|
34
26
|
end
|
35
27
|
|
36
28
|
def method_missing name, *args, &block
|
37
|
-
self.class.call_method(self, name, args, block)
|
29
|
+
self.class.call_method(self, name, args, block) { super }
|
38
30
|
end
|
39
31
|
|
40
32
|
def self.call_method(object, name, args, block)
|
@@ -50,15 +42,8 @@ class Base
|
|
50
42
|
|
51
43
|
# 1. The world is all that is the case.
|
52
44
|
# 2. We failed to find a method to call.
|
53
|
-
# 2.1.
|
54
|
-
|
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)
|
45
|
+
# 2.1. call "super" in the context of the method_missing caller
|
46
|
+
yield
|
62
47
|
end
|
63
48
|
|
64
49
|
def self.call_instance_method(mod, name, args, block)
|
@@ -67,7 +52,18 @@ class Base
|
|
67
52
|
else
|
68
53
|
klass = Class.new { include mod }
|
69
54
|
end
|
70
|
-
|
55
|
+
|
56
|
+
object = self.instantiate_regardless_of_argument_count(klass)
|
57
|
+
return object.send name, *args, &block
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.instantiate_regardless_of_argument_count(klass)
|
61
|
+
(0..100).each do |arg_count|
|
62
|
+
begin
|
63
|
+
return klass.new(*[nil] * arg_count)
|
64
|
+
rescue ArgumentError
|
65
|
+
end
|
66
|
+
end
|
71
67
|
end
|
72
68
|
|
73
69
|
def self.methods
|
@@ -81,13 +77,10 @@ class Base
|
|
81
77
|
# INHERIT ALL THE METHODS!
|
82
78
|
def self.giant_method_list_including_object(object)
|
83
79
|
methods = []
|
84
|
-
all_modules.
|
80
|
+
all_modules.each do |mod|
|
85
81
|
# Don't recurse into other Base objects' "methods" method
|
86
|
-
if
|
87
|
-
|
88
|
-
else
|
89
|
-
methods += m.methods + m.instance_methods
|
90
|
-
end
|
82
|
+
next if mod.is_a?(Base) || mod < Base || mod == Base
|
83
|
+
methods.concat(mod.methods).concat(mod.instance_methods)
|
91
84
|
end
|
92
85
|
methods
|
93
86
|
end
|
data/spec/base_spec.rb
CHANGED
@@ -11,11 +11,20 @@ class NormalClass
|
|
11
11
|
def an_instance_method; 8; end
|
12
12
|
end
|
13
13
|
|
14
|
+
class ClassWithTwoConstructorArgs
|
15
|
+
def initialize(x, y)
|
16
|
+
end
|
17
|
+
|
18
|
+
def some_method
|
19
|
+
"constructor args worked!"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
14
23
|
class InheritsFromBase < Base
|
15
24
|
end
|
16
25
|
|
17
26
|
describe Base do
|
18
|
-
it "
|
27
|
+
it "has other modules' constants" do
|
19
28
|
InheritsFromBase::Something.should == NormalModule::Something
|
20
29
|
end
|
21
30
|
|
@@ -25,15 +34,15 @@ describe Base do
|
|
25
34
|
end.to raise_error NameError
|
26
35
|
end
|
27
36
|
|
28
|
-
it "
|
37
|
+
it "has other modules' class methods" do
|
29
38
|
InheritsFromBase.a_class_method.should == 6
|
30
39
|
end
|
31
40
|
|
32
|
-
it "
|
41
|
+
it "has other modules' instance methods" do
|
33
42
|
InheritsFromBase.a_module_method.should == 7
|
34
43
|
end
|
35
44
|
|
36
|
-
it "
|
45
|
+
it "has other classes' instance methods" do
|
37
46
|
InheritsFromBase.an_instance_method.should == 8
|
38
47
|
end
|
39
48
|
|
@@ -43,7 +52,7 @@ describe Base do
|
|
43
52
|
end.to raise_error NoMethodError
|
44
53
|
end
|
45
54
|
|
46
|
-
it "
|
55
|
+
it "has other modules' methods as instance methods" do
|
47
56
|
InheritsFromBase.new.a_class_method.should == 6
|
48
57
|
end
|
49
58
|
|
@@ -55,7 +64,7 @@ describe Base do
|
|
55
64
|
InheritsFromBase.all_modules.last.should == Kernel
|
56
65
|
end
|
57
66
|
|
58
|
-
its "instance NoMethodErrors
|
67
|
+
its "instance NoMethodErrors reference the instance" do
|
59
68
|
expect do
|
60
69
|
InheritsFromBase.new.not_a_method
|
61
70
|
end.to raise_error(NoMethodError, /undefined method `not_a_method' for #<InheritsFromBase/)
|
@@ -73,5 +82,9 @@ describe Base do
|
|
73
82
|
methods = InheritsFromBase.methods
|
74
83
|
methods.uniq.should == methods
|
75
84
|
end
|
85
|
+
|
86
|
+
it "instantiates objects with the correct number of arguments" do
|
87
|
+
InheritsFromBase.new.some_method.should == "constructor args worked!"
|
88
|
+
end
|
76
89
|
end
|
77
90
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Gary Bernhardt
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-03 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rspec
|
@@ -49,12 +49,12 @@ dependencies:
|
|
49
49
|
type: :development
|
50
50
|
version_requirements: *id002
|
51
51
|
description: |-
|
52
|
-
People love Base classes! They have tons of methods waiting to be used. Just check out ActiveRecord::Base's method list:
|
52
|
+
People love Base classes! They have tons of methods waiting to be used. Just check out `ActiveRecord::Base`'s method list:
|
53
53
|
|
54
54
|
>> ActiveRecord::Base.methods.length
|
55
|
-
=> 530
|
55
|
+
=> 530
|
56
56
|
|
57
|
-
But why stop there? Why not have even more methods? In fact, let's put
|
57
|
+
But why stop there? Why not have even more methods? In fact, let's put *every method* on one Base class!
|
58
58
|
|
59
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
60
|
|
@@ -65,16 +65,18 @@ description: |-
|
|
65
65
|
end
|
66
66
|
|
67
67
|
>> Cantaloupe.new.embiggen
|
68
|
-
=> "eJzTBwAAMAAw\n"
|
68
|
+
=> "eJzTBwAAMAAw\n"
|
69
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
|
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 calls what it wants!
|
71
71
|
|
72
72
|
By the way, remember those 530 ActiveRecord methods? That's amateur stuff. Check out Base loaded inside a Rails app:
|
73
73
|
|
74
74
|
>> Base.new.methods.count
|
75
|
-
=> 6947
|
75
|
+
=> 6947
|
76
76
|
|
77
|
-
It's so badass that it takes
|
77
|
+
It's so badass that it takes *five seconds* just to answer that question!
|
78
|
+
|
79
|
+
Base is just craaazzy! It's the most fearless class in all of Ruby. Base doesn't afraid of anything!
|
78
80
|
email:
|
79
81
|
- gary.bernhardt@gmail.com
|
80
82
|
executables: []
|