include_complete 0.1.2-i386-mswin32 → 0.1.3-i386-mswin32
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.markdown +82 -10
- data/lib/include_complete.rb +1 -0
- data/lib/include_complete/version.rb +1 -1
- data/test/stress_test.rb +5 -4
- metadata +5 -2
data/README.markdown
CHANGED
@@ -1,21 +1,20 @@
|
|
1
1
|
Include Complete
|
2
2
|
----------------
|
3
3
|
|
4
|
-
(c) John Mair (banisterfiend)
|
4
|
+
(c) John Mair (banisterfiend) 2010
|
5
5
|
MIT license
|
6
6
|
|
7
|
-
|
8
|
-
bring in singleton classes from modules. No more ugly ClassMethods and
|
9
|
-
included() hook hacks.
|
7
|
+
_Removes the shackles from Module#include_
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
Use `Module#include_complete` to bring in singleton classes from
|
10
|
+
modules. No more ugly ClassMethods and included() hook hacks.
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
example:
|
12
|
+
* Install the [gem](https://rubygems.org/gems/include_complete): `gem install include_complete`
|
13
|
+
* Read the [documentation](http://rdoc.info/github/banister/include_complete/master/file/README.markdown)
|
14
|
+
* See the [source code](http://github.com/banister/include_complete)
|
18
15
|
|
16
|
+
example: include_complete():
|
17
|
+
----------------------------
|
19
18
|
module M
|
20
19
|
# class method
|
21
20
|
def self.hello
|
@@ -38,3 +37,76 @@ example:
|
|
38
37
|
# invoke instance method
|
39
38
|
A.new.bye #=> bye!
|
40
39
|
|
40
|
+
Motivation
|
41
|
+
-----------
|
42
|
+
|
43
|
+
When a class inherits from another class it inherits both the
|
44
|
+
instance methods and class methods from its superclass.
|
45
|
+
|
46
|
+
Module inclusion does not work this way, only the module's instance methods
|
47
|
+
are mixed into the receiver's ancestor chain. This shortcoming
|
48
|
+
necessitates the `ClassMethods` included-hook-hack.
|
49
|
+
|
50
|
+
In my opinion this behaviour of modules violates the principle of
|
51
|
+
least surprise, though I'm aware not everyone agrees with this.
|
52
|
+
|
53
|
+
`include_complete` was written to make module inclusion work more like
|
54
|
+
class inheritance.
|
55
|
+
|
56
|
+
The extend_complete method
|
57
|
+
--------------------------
|
58
|
+
|
59
|
+
For completeness the `extend_complete` method has also been
|
60
|
+
implemented. Like traditional `extend` it mixes the module's instance
|
61
|
+
methods into the singleton class of the receiver. But where do the
|
62
|
+
singleton methods on the module end up? On the singleton class of the
|
63
|
+
singleton class of the receiver ;)
|
64
|
+
|
65
|
+
module M
|
66
|
+
def self.hello
|
67
|
+
:hello
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class C
|
72
|
+
extend_complete M
|
73
|
+
|
74
|
+
class << self
|
75
|
+
hello #=> :hello
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
As a result of this, it is unlikely `extend_complete` will be of much
|
80
|
+
use to anyone :)
|
81
|
+
|
82
|
+
How does it work?
|
83
|
+
-----------------
|
84
|
+
|
85
|
+
`include_complete` is a C extension that implements a highly modified
|
86
|
+
`rb_include_module()` function. Traditional module inclusion uses the
|
87
|
+
class pointer of the Included Module to point to the original module;
|
88
|
+
`include_complete` instead uses the class pointer to point to a
|
89
|
+
wrapped version of the singleton class of the module and stores the original module in a
|
90
|
+
hidden `__module__` instance variable. This wrapped singleton class is
|
91
|
+
then injected into the ancestor chain of the receiver's singleton
|
92
|
+
class.
|
93
|
+
|
94
|
+
Limitations
|
95
|
+
------------
|
96
|
+
|
97
|
+
`include_complete` uses a recursive function to generate the
|
98
|
+
Included Modules, and the base case of this recursion is reached when the singleton class of Module is
|
99
|
+
encountered. In the case where the module has a meta-meta class the recursive
|
100
|
+
function will not terminate and the program will hang.
|
101
|
+
|
102
|
+
It is highly unlikely and, as far as I know, next to useless for
|
103
|
+
a module to possess any higher order metaclasses so this limitation is
|
104
|
+
unlikely to be a problem in practice.
|
105
|
+
|
106
|
+
Contact
|
107
|
+
-------
|
108
|
+
|
109
|
+
Problems or questions contact me at [github](http://github.com/banister)
|
110
|
+
|
111
|
+
|
112
|
+
|
data/lib/include_complete.rb
CHANGED
data/test/stress_test.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
|
1
|
+
direc = File.dirname(__FILE__)
|
2
|
+
require "#{direc}/../lib/include_complete"
|
2
3
|
|
3
4
|
5000.times {
|
4
5
|
m = Module.new
|
5
6
|
n = Module.new
|
6
7
|
k = Module.new
|
7
|
-
n.
|
8
|
-
k.
|
8
|
+
n.include_complete m
|
9
|
+
k.include_complete n
|
9
10
|
|
10
11
|
c = Class.new
|
11
|
-
c.
|
12
|
+
c.include_complete k
|
12
13
|
}
|
13
14
|
|
14
15
|
"stress test passed!".display
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: include_complete
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
10
11
|
platform: i386-mswin32
|
11
12
|
authors:
|
12
13
|
- John Mair (banisterfiend)
|
@@ -55,6 +56,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
56
|
requirements:
|
56
57
|
- - ">="
|
57
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
58
60
|
segments:
|
59
61
|
- 0
|
60
62
|
version: "0"
|
@@ -63,6 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
65
|
requirements:
|
64
66
|
- - ">="
|
65
67
|
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
66
69
|
segments:
|
67
70
|
- 0
|
68
71
|
version: "0"
|