module-import 0.3.0 → 0.4.0
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 +6 -1
- data/Rakefile +2 -2
- data/coverage/-var-lib-gems-1_8-gems-rcov-0_8_0_2-lib-rcov_rb.html +1 -1
- data/coverage/index.html +11 -11
- data/coverage/lib-module-import_rb.html +35 -23
- data/doc/created.rid +1 -1
- data/lib/module-import.rb +17 -5
- data/spec/import_spec.rb +52 -7
- metadata +2 -5
- data/delete.html +0 -92
- data/example.rb +0 -48
- data/module-import.rb +0 -0
data/README
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
== Summary
|
2
|
-
selectively include module methods
|
2
|
+
selectively include module methods with Kernel#import
|
3
3
|
|
4
4
|
== Author and License
|
5
5
|
Copyright (c) 2008 Greg Weber, http://gregweber.info
|
@@ -42,6 +42,11 @@ However, there is one important difference. New changes in the included module
|
|
42
42
|
Importer2.new.bar # => 'bar'
|
43
43
|
Importer2.new.foo # => 'foo'
|
44
44
|
|
45
|
+
== WARNING!
|
46
|
+
There is no way for Kernel#import to track dependencies between methods! To help with this, by default, all private methods from the module will be imported unless the option :import_private is set to false
|
47
|
+
To write a module that works with this system well, your public methods should depend only on private methods.
|
48
|
+
To use this on someone else's module, you should either import the full module or write tests or inspect the source code of the module you are importing.
|
49
|
+
|
45
50
|
== Install
|
46
51
|
gem install module-import
|
47
52
|
|
data/Rakefile
CHANGED
@@ -82,7 +82,7 @@ namespace :rcov do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
desc "release a new gem to rubyforge"
|
85
|
-
task :release => [:test,:rdoc,:website,:package] do
|
85
|
+
task :release => [:test,:record,:rdoc,:website,:package] do
|
86
86
|
Dir.chdir('pkg') do
|
87
87
|
release = Dir['*.gem'].sort_by {|file| File.mtime(file)}.last
|
88
88
|
release =~ /^[^-]+-([.0-9]+).gem$/
|
@@ -137,7 +137,7 @@ require 'rake/gempackagetask'
|
|
137
137
|
spec = Gem::Specification.new do |s|
|
138
138
|
s.name = project
|
139
139
|
s.rubyforge_project = project
|
140
|
-
s.version = "0.
|
140
|
+
s.version = "0.4.0"
|
141
141
|
s.author = "Greg Weber"
|
142
142
|
s.email = "greg@gregweber.info"
|
143
143
|
s.homepage = "http://projects.gregweber.info/#{project}"
|
@@ -556,7 +556,7 @@ span.run100 {
|
|
556
556
|
</head>
|
557
557
|
<body>
|
558
558
|
<h3>C0 code coverage information</h3>
|
559
|
-
<p>Generated on
|
559
|
+
<p>Generated on Fri Mar 14 20:30:48 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
|
560
560
|
</p>
|
561
561
|
<hr /><pre><span class='marked0'>Code reported as executed by Ruby looks like this...
|
562
562
|
</span><span class='marked1'>and this: this line is also marked as covered.
|
data/coverage/index.html
CHANGED
@@ -151,7 +151,7 @@ table.report tr.dark {
|
|
151
151
|
</head>
|
152
152
|
<body>
|
153
153
|
<h3>C0 code coverage information</h3>
|
154
|
-
<p>Generated on
|
154
|
+
<p>Generated on Fri Mar 14 20:30:48 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
|
155
155
|
</p>
|
156
156
|
<hr /> <table class='report'>
|
157
157
|
<thead>
|
@@ -167,21 +167,21 @@ table.report tr.dark {
|
|
167
167
|
<tr class='light'>
|
168
168
|
<td>TOTAL</td>
|
169
169
|
<td class='lines_total'>
|
170
|
-
<tt>
|
170
|
+
<tt>1015</tt>
|
171
171
|
</td>
|
172
172
|
<td class='lines_code'>
|
173
|
-
<tt>
|
173
|
+
<tt>624</tt>
|
174
174
|
</td>
|
175
175
|
<td>
|
176
176
|
<table cellspacing='0' cellpadding='0' align='right'>
|
177
177
|
<tr>
|
178
178
|
<td>
|
179
|
-
<tt class='coverage_total'>
|
179
|
+
<tt class='coverage_total'>7.1%</tt> </td>
|
180
180
|
<td>
|
181
181
|
<table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
|
182
182
|
<tr>
|
183
|
-
<td class='covered' width='
|
184
|
-
<td class='uncovered' width='
|
183
|
+
<td class='covered' width='7' />
|
184
|
+
<td class='uncovered' width='93' />
|
185
185
|
</tr>
|
186
186
|
</table>
|
187
187
|
</td>
|
@@ -192,12 +192,12 @@ table.report tr.dark {
|
|
192
192
|
<table cellspacing='0' cellpadding='0' align='right'>
|
193
193
|
<tr>
|
194
194
|
<td>
|
195
|
-
<tt class='coverage_code'>
|
195
|
+
<tt class='coverage_code'>7.4%</tt> </td>
|
196
196
|
<td>
|
197
197
|
<table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
|
198
198
|
<tr>
|
199
|
-
<td class='covered' width='
|
200
|
-
<td class='uncovered' width='
|
199
|
+
<td class='covered' width='7' />
|
200
|
+
<td class='uncovered' width='93' />
|
201
201
|
</tr>
|
202
202
|
</table>
|
203
203
|
</td>
|
@@ -253,10 +253,10 @@ table.report tr.dark {
|
|
253
253
|
<a href='lib-module-import_rb.html'>lib/module-import.rb</a>
|
254
254
|
</td>
|
255
255
|
<td class='lines_total'>
|
256
|
-
<tt>
|
256
|
+
<tt>39</tt>
|
257
257
|
</td>
|
258
258
|
<td class='lines_code'>
|
259
|
-
<tt>
|
259
|
+
<tt>29</tt>
|
260
260
|
</td>
|
261
261
|
<td>
|
262
262
|
<table cellspacing='0' cellpadding='0' align='right'>
|
@@ -556,7 +556,7 @@ span.run100 {
|
|
556
556
|
</head>
|
557
557
|
<body>
|
558
558
|
<h3>C0 code coverage information</h3>
|
559
|
-
<p>Generated on
|
559
|
+
<p>Generated on Fri Mar 14 20:30:48 -0500 2008 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
|
560
560
|
</p>
|
561
561
|
<hr /><pre><span class='marked0'>Code reported as executed by Ruby looks like this...
|
562
562
|
</span><span class='marked1'>and this: this line is also marked as covered.
|
@@ -580,10 +580,10 @@ span.run100 {
|
|
580
580
|
<a href='lib-module-import_rb.html'>lib/module-import.rb</a>
|
581
581
|
</td>
|
582
582
|
<td class='lines_total'>
|
583
|
-
<tt>
|
583
|
+
<tt>39</tt>
|
584
584
|
</td>
|
585
585
|
<td class='lines_code'>
|
586
|
-
<tt>
|
586
|
+
<tt>29</tt>
|
587
587
|
</td>
|
588
588
|
<td>
|
589
589
|
<table cellspacing='0' cellpadding='0' align='right'>
|
@@ -624,28 +624,40 @@ span.run100 {
|
|
624
624
|
</span><span class="marked1"><a name="line3" /> 3 module Kernel
|
625
625
|
</span><span class="inferred0"><a name="line4" /> 4
|
626
626
|
</span><span class="inferred1"><a name="line5" /> 5 # abstraction:: only include the methods given by _meths_
|
627
|
-
</span><span class="inferred0"><a name="line6" /> 6 # implementation:: includes a duplicate of _mod_ with
|
628
|
-
</span><span class="marked1"><a name="line7" /> 7 def import(mod, *
|
627
|
+
</span><span class="inferred0"><a name="line6" /> 6 # implementation:: includes a duplicate of _mod_ with only the specified instance methods included. By default, all private methods will be included unless the option :import_private is set to false. If no methods are given,
|
628
|
+
</span><span class="marked1"><a name="line7" /> 7 def import(mod, *methods_or_options)
|
629
629
|
</span><span class="marked0"><a name="line8" /> 8 mod_dup = mod.dup
|
630
630
|
</span><span class="inferred1"><a name="line9" /> 9
|
631
|
-
</span><span class="marked0"><a name="line10" />10 unless
|
632
|
-
</span><span class="
|
633
|
-
</span><span class="inferred0"><a name="line12" />12
|
634
|
-
</span><span class="
|
635
|
-
</span><span class="marked0"><a name="line14" />14
|
636
|
-
</span><span class="
|
637
|
-
</span><span class="marked0"><a name="line16" />16
|
638
|
-
</span><span class="marked1"><a name="line17" />17
|
639
|
-
</span><span class="inferred0"><a name="line18" />18
|
640
|
-
</span><span class="inferred1"><a name="line19" />19
|
641
|
-
</span><span class="marked0"><a name="line20" />20
|
642
|
-
</span><span class="marked1"><a name="line21" />21
|
643
|
-
</span><span class="inferred0"><a name="line22" />22
|
644
|
-
</span><span class="inferred1"><a name="line23" />23
|
645
|
-
</span><span class="
|
646
|
-
</span><span class="marked1"><a name="line25" />25
|
647
|
-
</span><span class="inferred0"><a name="line26" />26
|
648
|
-
</span><span class="
|
631
|
+
</span><span class="marked0"><a name="line10" />10 unless methods_or_options.empty?
|
632
|
+
</span><span class="marked1"><a name="line11" />11 options, meths = methods_or_options.partition {|m| m.is_a?(Hash)}
|
633
|
+
</span><span class="inferred0"><a name="line12" />12
|
634
|
+
</span><span class="inferred1"><a name="line13" />13 # get list of methods to remove module
|
635
|
+
</span><span class="marked0"><a name="line14" />14 ims = mod.instance_methods
|
636
|
+
</span><span class="marked1"><a name="line15" />15 if options.first
|
637
|
+
</span><span class="marked0"><a name="line16" />16 if meths.empty?
|
638
|
+
</span><span class="marked1"><a name="line17" />17 fail ArgumentError,
|
639
|
+
</span><span class="inferred0"><a name="line18" />18 "methods arguments required with options flags"
|
640
|
+
</span><span class="inferred1"><a name="line19" />19 end
|
641
|
+
</span><span class="marked0"><a name="line20" />20 if options.first[:import_private] == false
|
642
|
+
</span><span class="marked1"><a name="line21" />21 ims += mod.private_instance_methods
|
643
|
+
</span><span class="inferred0"><a name="line22" />22 end
|
644
|
+
</span><span class="inferred1"><a name="line23" />23 end
|
645
|
+
</span><span class="marked0"><a name="line24" />24 ims.map! {|m| m.to_sym}
|
646
|
+
</span><span class="marked1"><a name="line25" />25 removes = ims - meths
|
647
|
+
</span><span class="inferred0"><a name="line26" />26
|
648
|
+
</span><span class="marked1"><a name="line27" />27 if removes.size != (ims.size - meths.size)
|
649
|
+
</span><span class="marked0"><a name="line28" />28 raise ImportError,
|
650
|
+
</span><span class="marked1"><a name="line29" />29 "##{(meths - ims).join(' and #')} not found in #{mod}"
|
651
|
+
</span><span class="inferred0"><a name="line30" />30 end
|
652
|
+
</span><span class="inferred1"><a name="line31" />31
|
653
|
+
</span><span class="marked0"><a name="line32" />32 mod_dup.module_eval do
|
654
|
+
</span><span class="marked1"><a name="line33" />33 removes.each { |meth| remove_method meth }
|
655
|
+
</span><span class="inferred0"><a name="line34" />34 end
|
656
|
+
</span><span class="inferred1"><a name="line35" />35 end
|
657
|
+
</span><span class="inferred0"><a name="line36" />36
|
658
|
+
</span><span class="marked1"><a name="line37" />37 include mod_dup
|
659
|
+
</span><span class="inferred0"><a name="line38" />38 end
|
660
|
+
</span><span class="inferred1"><a name="line39" />39 end
|
649
661
|
</span></pre><hr /> <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a> version 0.8.0.</p><p>
|
650
662
|
<a href='http://validator.w3.org/check/referer'>
|
651
663
|
<img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88' />
|
data/doc/created.rid
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
Fri, 14 Mar 2008 20:30:52 -0500
|
data/lib/module-import.rb
CHANGED
@@ -3,18 +3,30 @@ class ImportError < Exception; end
|
|
3
3
|
module Kernel
|
4
4
|
|
5
5
|
# abstraction:: only include the methods given by _meths_
|
6
|
-
# implementation:: includes a duplicate of _mod_ with
|
7
|
-
def import(mod, *
|
6
|
+
# implementation:: includes a duplicate of _mod_ with only the specified instance methods included. By default, all private methods will be included unless the option :import_private is set to false. If no methods are given,
|
7
|
+
def import(mod, *methods_or_options)
|
8
8
|
mod_dup = mod.dup
|
9
9
|
|
10
|
-
unless
|
10
|
+
unless methods_or_options.empty?
|
11
|
+
options, meths = methods_or_options.partition {|m| m.is_a?(Hash)}
|
11
12
|
|
12
13
|
# get list of methods to remove module
|
13
|
-
ims = mod.instance_methods
|
14
|
+
ims = mod.instance_methods
|
15
|
+
if options.first
|
16
|
+
if meths.empty?
|
17
|
+
fail ArgumentError,
|
18
|
+
"methods arguments required with options flags"
|
19
|
+
end
|
20
|
+
if options.first[:import_private] == false
|
21
|
+
ims += mod.private_instance_methods
|
22
|
+
end
|
23
|
+
end
|
24
|
+
ims.map! {|m| m.to_sym}
|
14
25
|
removes = ims - meths
|
15
26
|
|
16
27
|
if removes.size != (ims.size - meths.size)
|
17
|
-
raise ImportError,
|
28
|
+
raise ImportError,
|
29
|
+
"##{(meths - ims).join(' and #')} not found in #{mod}"
|
18
30
|
end
|
19
31
|
|
20
32
|
mod_dup.module_eval do
|
data/spec/import_spec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../lib/module-import'
|
2
|
-
|
3
2
|
# testing helpers
|
4
3
|
def module_with_new
|
5
4
|
Module.new do
|
@@ -27,14 +26,40 @@ def class_and_module(times=nil)
|
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
29
|
+
module ModuleDependencies
|
30
|
+
def self.included(mod)
|
31
|
+
mod.module_eval do
|
32
|
+
@@instance_method_dependencies = Hash.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def mod.import_dependencies set=nil
|
36
|
+
if set
|
37
|
+
@@instance_method_dependencies = set
|
38
|
+
else
|
39
|
+
@@instance_method_dependencies
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
30
45
|
|
31
46
|
# testing uses this module
|
32
47
|
module Foo
|
33
48
|
def extra_method; fail end
|
34
49
|
|
35
|
-
def foo;
|
36
|
-
def bar;
|
50
|
+
def foo; foo_dependency() end
|
51
|
+
def bar; bar_dependency end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def protected_method
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def foo_dependency; 'foo' end
|
59
|
+
def bar_dependency; 'bar' end
|
60
|
+
def private_extra_method; fail end
|
37
61
|
|
62
|
+
public
|
38
63
|
def another_extra_method; fail end
|
39
64
|
end
|
40
65
|
|
@@ -63,10 +88,6 @@ describe "import" do
|
|
63
88
|
c.new.foo.should == 'foo'
|
64
89
|
c.new.bar.should == 'bar'
|
65
90
|
|
66
|
-
b = c.class.new
|
67
|
-
b.send :import, Foo, *(Foo.private_instance_methods)
|
68
|
-
c.instance_methods.sort.should == b.instance_methods.sort
|
69
|
-
|
70
91
|
a = c.class.new
|
71
92
|
a.send :include, Foo
|
72
93
|
a.instance_methods.sort.should == c.instance_methods.sort
|
@@ -134,4 +155,28 @@ describe "import" do
|
|
134
155
|
b.new.foo.should == 'foo'
|
135
156
|
end
|
136
157
|
end
|
158
|
+
|
159
|
+
it "should remove private methods when :import_private is false" do
|
160
|
+
class_and_module.each do |a|
|
161
|
+
b = Class.new do
|
162
|
+
import Foo, :foo, :import_private => false
|
163
|
+
end
|
164
|
+
lambda{b.new.foo}.should raise_error(NoMethodError, /foo_dependency/)
|
165
|
+
|
166
|
+
c = Class.new do
|
167
|
+
import Foo, :foo, :foo_dependency, :import_private => false
|
168
|
+
end
|
169
|
+
lambda{c.new.foo}.should_not raise_error
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should fail when no methods given with :import_private flag" do
|
174
|
+
class_and_module.each do |a|
|
175
|
+
[true,false].each do |tf|
|
176
|
+
lambda{ Class.new do
|
177
|
+
import Foo, :import_private => tf
|
178
|
+
end }.should raise_error(ArgumentError)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
137
182
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: module-import
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2008-03-
|
6
|
+
version: 0.4.0
|
7
|
+
date: 2008-03-14 00:00:00 -05:00
|
8
8
|
summary: selectively import methods from modules
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -34,10 +34,7 @@ files:
|
|
34
34
|
- ./spec
|
35
35
|
- ./Rakefile
|
36
36
|
- ./README
|
37
|
-
- ./example.rb
|
38
37
|
- ./coverage
|
39
|
-
- ./delete.html
|
40
|
-
- ./module-import.rb
|
41
38
|
- doc/files
|
42
39
|
- doc/index.html
|
43
40
|
- doc/rdoc-style.css
|
data/delete.html
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
<html>
|
2
|
-
<body>
|
3
|
-
<div id=<span class="s"><span class="dl">"</span><span class="k">description</span><span class="dl">"</span></span>>
|
4
|
-
<h2><span class="co">Summary</span><<span class="rx"><span class="dl">/</span><span class="k">h2>
|
5
|
-
<p>
|
6
|
-
selectively include module methods
|
7
|
-
<</span><span class="dl">/</span></span>p>
|
8
|
-
<h2><span class="co">Author</span> <span class="r">and</span> <span class="co">License</span><<span class="rx"><span class="dl">/</span><span class="k">h2>
|
9
|
-
<p>
|
10
|
-
Copyright (c) 2008 Greg Weber, <a href="http:</span><span class="dl">/</span></span>/gregweber.info<span class="s"><span class="dl">"</span><span class="k">>gregweber.info</a> Licensed under the MIT
|
11
|
-
license
|
12
|
-
</p>
|
13
|
-
<h2>Usage</h2>
|
14
|
-
<coderay lang=</span><span class="dl">"</span></span>ruby<span class="s"><span class="dl">"</span><span class="k">>
|
15
|
-
require 'rubygems'
|
16
|
-
require 'module-import'
|
17
|
-
|
18
|
-
module Foo
|
19
|
-
def foo; 'foo' end
|
20
|
-
def bar; 'bar' end
|
21
|
-
end
|
22
|
-
|
23
|
-
class Importer
|
24
|
-
import Foo, :bar
|
25
|
-
end
|
26
|
-
Importer.new.bar # => 'bar'
|
27
|
-
Importer.new.foo # => # NoMethodError
|
28
|
-
|
29
|
-
class Importer
|
30
|
-
import Foo, :not_defined # => #not_defined not found in Foo (ImportError)
|
31
|
-
end
|
32
|
-
</coderay>
|
33
|
-
<p>
|
34
|
-
Giving no methods (or all methods) should behave the same as a normal
|
35
|
-
include
|
36
|
-
</p>
|
37
|
-
<coderay lang=</span><span class="dl">"</span></span>ruby<span class="s"><span class="dl">"</span><span class="k">>
|
38
|
-
class Importer2
|
39
|
-
import Foo # same as import Foo, :foo, :bar
|
40
|
-
end
|
41
|
-
Importer2.new.bar # => 'bar'
|
42
|
-
Importer2.new.foo # => 'foo'
|
43
|
-
</coderay>
|
44
|
-
<p>
|
45
|
-
However, there is one important difference. New changes in the included
|
46
|
-
module will not effect the class.
|
47
|
-
</p>
|
48
|
-
<coderay lang=</span><span class="dl">"</span></span>ruby<span class="s"><span class="dl">"</span><span class="k">>
|
49
|
-
module Foo
|
50
|
-
undef_method :foo
|
51
|
-
def bar; fail end
|
52
|
-
end
|
53
|
-
Importer2.new.bar # => 'bar'
|
54
|
-
Importer2.new.foo # => 'foo'
|
55
|
-
</coderay>
|
56
|
-
<h2>Install</h2>
|
57
|
-
<p>
|
58
|
-
gem install module-import
|
59
|
-
</p>
|
60
|
-
<h2>Source</h2>
|
61
|
-
<h3>browser</h3>
|
62
|
-
<p>
|
63
|
-
<a href=</span><span class="dl">"</span></span>http<span class="sy">:/</span>/github.com/gregwebs/<span class="r">module</span>-import/tree/master<span class="s"><span class="dl">"</span><span class="k">>github.com/gregwebs/module-import/tree/master</a>
|
64
|
-
</p>
|
65
|
-
<h3>repository</h3>
|
66
|
-
<p>
|
67
|
-
git clone git://github.com/gregwebs/module-import.git
|
68
|
-
</p>
|
69
|
-
<h2>Homepage</h2>
|
70
|
-
<p>
|
71
|
-
<a href=</span><span class="dl">"</span></span>http<span class="sy">:/</span>/gregweber.info/projects/<span class="r">module</span>-import.html<span class="s"><span class="dl">"</span><span class="k">>gregweber.info/projects/module-import.html</a>
|
72
|
-
</p>
|
73
|
-
<h2>RDoc documentation</h2>
|
74
|
-
<p>
|
75
|
-
included with the gem
|
76
|
-
</p>
|
77
|
-
<h2>Notes</h2>
|
78
|
-
<h3>Testing</h3>
|
79
|
-
<p>
|
80
|
-
4:1 test:code ratio, I think I have all the corner cases covered. In
|
81
|
-
particular, this does not break inheritance and everything works the same
|
82
|
-
for importing into a module instead of a class.
|
83
|
-
</p>
|
84
|
-
<h3>Implementation</h3>
|
85
|
-
<p>
|
86
|
-
Includes a duplicate of the module that has methods removed
|
87
|
-
</p>
|
88
|
-
|
89
|
-
</div>
|
90
|
-
</span></span>
|
91
|
-
</body>
|
92
|
-
</html>
|
data/example.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
class ImportError < Exception; end
|
2
|
-
|
3
|
-
module Kernel
|
4
|
-
|
5
|
-
# abstraction:: only include the methods given by _meths_
|
6
|
-
# implementation:: includes a duplicate of _mod_ with all uneeded instance methods removed
|
7
|
-
def import(mod, *meths)
|
8
|
-
mod_dup = mod.dup
|
9
|
-
|
10
|
-
unless meths.empty?
|
11
|
-
|
12
|
-
# get list of methods to remove module
|
13
|
-
ims = mod.instance_methods.map {|m| m.to_sym}
|
14
|
-
removes = ims - meths
|
15
|
-
|
16
|
-
if removes.size != (ims.size - meths.size)
|
17
|
-
raise ImportError, "##{(meths - ims).join(' and #')} not found in #{mod}"
|
18
|
-
end
|
19
|
-
|
20
|
-
mod_dup.module_eval do
|
21
|
-
removes.each { |meth| remove_method meth }
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
include mod_dup
|
26
|
-
end
|
27
|
-
end
|
28
|
-
module Foo
|
29
|
-
def foo; 'foo' end
|
30
|
-
def bar; 'bar' end
|
31
|
-
end
|
32
|
-
class Importer
|
33
|
-
import Foo, :bar
|
34
|
-
end
|
35
|
-
Importer.new.bar # => 'bar'
|
36
|
-
class Importer
|
37
|
-
end
|
38
|
-
class Importer2
|
39
|
-
import Foo # same as import Foo, :foo, :bar
|
40
|
-
end
|
41
|
-
Importer2.new.bar # => 'bar'
|
42
|
-
Importer2.new.foo # => 'foo'
|
43
|
-
module Foo
|
44
|
-
undef_method :foo
|
45
|
-
def bar; fail end
|
46
|
-
end
|
47
|
-
Importer2.new.bar # => 'bar'
|
48
|
-
Importer2.new.foo # => 'foo'
|
data/module-import.rb
DELETED
File without changes
|