real_include 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -28,7 +28,7 @@ specification = Gem::Specification.new do |s|
28
28
  s.extensions = ["ext/real_include/extconf.rb"]
29
29
  s.files = ["Rakefile", "README.markdown", "CHANGELOG",
30
30
  "lib/real_include.rb", "lib/real_include/version.rb"] +
31
- # ["lib/1.9/real_include.so", "lib/1.8/real_include.so"] +
31
+ # ["lib/1.9/real_include.so", "lib/1.8/real_include.so"] +
32
32
  FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "test/**/*.rb"].to_a
33
33
  end
34
34
 
@@ -1,4 +1,5 @@
1
1
  /* (c) 2010 John Mair (banisterfiend), MIT license */
2
+ /* */
2
3
  /* include a module (and its singleton) into an inheritance chain */
3
4
  /* only includes a single module, see real_include.rb for multi-module version */
4
5
 
@@ -59,10 +60,15 @@ include_class_new(VALUE module, VALUE super)
59
60
  NEWOBJ(klass, struct RClass);
60
61
  OBJSETUP(klass, rb_singleton_class(rb_cModule), T_ICLASS);
61
62
  #endif
62
- /* we want a fresh ivtbl */
63
- RCLASS_IV_TBL(klass) = st_init_numtable();
64
63
 
65
- /* we want to copy the mtbl */
64
+ /* if the module hasn't yet got an ivtbl, create it */
65
+ if (!RCLASS_IV_TBL(module))
66
+ RCLASS_IV_TBL(module) = st_init_numtable();
67
+
68
+ /* we want to point to the original ivtbl for normal modules, so that we bring in constants */
69
+ RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
70
+
71
+ /* we want to point to the original module's mtbl */
66
72
  RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
67
73
  RCLASS_SUPER(klass) = super;
68
74
 
@@ -79,6 +85,9 @@ include_class_new(VALUE module, VALUE super)
79
85
  /* set it as a singleton */
80
86
  FL_SET(meta, FL_SINGLETON);
81
87
 
88
+ /* we want a fresh ivtbl for singleton classes (so we can redefine __attached__) */
89
+ RCLASS_IV_TBL(meta) = st_init_numtable();
90
+
82
91
  /* attach singleton to module */
83
92
  rb_iv_set(meta, "__attached__", (VALUE)klass);
84
93
 
@@ -87,7 +96,7 @@ include_class_new(VALUE module, VALUE super)
87
96
  }
88
97
  /* assign the metaclass to module's klass */
89
98
  KLASS_OF(klass) = meta;
90
-
99
+
91
100
  OBJ_INFECT(klass, module);
92
101
  OBJ_INFECT(klass, super);
93
102
 
@@ -19,7 +19,7 @@ require "#{direc}/real_include/version"
19
19
 
20
20
  class Module
21
21
 
22
- # include multiple modules (and their singletons) into an
22
+ # include modules (and their singletons) into an
23
23
  # inheritance chain
24
24
  # @param [Module] mods Modules to real_include
25
25
  # @return Returns the receiver
@@ -40,3 +40,24 @@ class Module
40
40
  self
41
41
  end
42
42
  end
43
+
44
+ class Object
45
+
46
+ # extend modules (and their singletons) into an
47
+ # inheritance chain
48
+ # @param [Module] mods Modules to real_extend
49
+ # @return Returns the receiver
50
+ # @example
51
+ # module M
52
+ # def self.hello
53
+ # puts "hello"
54
+ # end
55
+ # end
56
+ # o = Object.new
57
+ # o.real_extend M
58
+ # end
59
+ # o.singleton_class.hello #=> "hello"
60
+ def real_extend(*mods)
61
+ class << self; self; end.send(:real_include, *mods)
62
+ end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module RealInclude
2
- VERSION = "0.1.9"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -14,6 +14,8 @@ describe 'Including a module into a class using real_include' do
14
14
  end
15
15
  }
16
16
 
17
+ @m::CONST = :const
18
+
17
19
  @c = Class.new
18
20
 
19
21
  @c.send(:real_include, @m)
@@ -27,6 +29,10 @@ describe 'Including a module into a class using real_include' do
27
29
  obj = @c.new
28
30
  obj.instance_method.should.equal :instance_method
29
31
  end
32
+
33
+ it 'should make constants accessible to the class' do
34
+ lambda { @c::CONST }.should.not.raise NameError
35
+ end
30
36
  end
31
37
 
32
38
 
@@ -42,6 +48,8 @@ describe 'Including a module into a module and then into a class using real_incl
42
48
  end
43
49
  }
44
50
 
51
+ @m1::CONST1 = :const1
52
+
45
53
  @m2 = Module.new {
46
54
  def self.class_method2
47
55
  :class_method2
@@ -53,6 +61,8 @@ describe 'Including a module into a module and then into a class using real_incl
53
61
  }
54
62
  @m2.send(:real_include, @m1)
55
63
 
64
+ @m2::CONST2 = :const2
65
+
56
66
  @c = Class.new
57
67
 
58
68
  @c.send(:real_include, @m2)
@@ -62,6 +72,12 @@ describe 'Including a module into a module and then into a class using real_incl
62
72
  @m2.class_method1.should.equal :class_method1
63
73
  end
64
74
 
75
+ it 'should make constants on m1 and m2 accessible to class' do
76
+ lambda { @c::CONST1 == :const1 }.should.not.raise NameError
77
+ lambda { @m2::CONST1 == :const1 }.should.not.raise NameError
78
+ lambda { @c::CONST2 == :const2 }.should.not.raise NameError
79
+ end
80
+
65
81
  it 'should make class methods on modules m1 and m2 accessible to class' do
66
82
  @c.class_method1.should.equal :class_method1
67
83
  @c.class_method2.should.equal :class_method2
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: real_include
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 9
10
- version: 0.1.9
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Mair (banisterfiend)
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-16 00:00:00 +13:00
18
+ date: 2010-10-21 00:00:00 +13:00
19
19
  default_executable:
20
20
  dependencies: []
21
21