module-import 0.1.0 → 0.2.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 +8 -11
- data/coverage/-var-lib-gems-1_8-gems-rcov-0_8_0_2-lib-rcov_rb.html +1607 -0
- data/coverage/index.html +304 -0
- data/coverage/lib-import_rb.html +658 -0
- data/delete.html +92 -0
- data/doc/created.rid +1 -1
- data/doc/fr_class_index.html +0 -2
- data/doc/fr_file_index.html +0 -1
- data/doc/fr_method_index.html +0 -1
- data/example.rb +48 -0
- data/lib/import.rb +12 -14
- data/pkg/module-import-0.1.0.gem +0 -0
- data/pkg/module-import-0.2.1.gem +0 -0
- data/rakefile +120 -10
- data/spec/import_spec.rb +10 -9
- metadata +10 -2
data/delete.html
ADDED
@@ -0,0 +1,92 @@
|
|
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/doc/created.rid
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
Tue, 11 Mar 2008 13:44:27 -0500
|
data/doc/fr_class_index.html
CHANGED
data/doc/fr_file_index.html
CHANGED
data/doc/fr_method_index.html
CHANGED
data/example.rb
ADDED
@@ -0,0 +1,48 @@
|
|
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/lib/import.rb
CHANGED
@@ -2,28 +2,26 @@ class ImportError < Exception; end
|
|
2
2
|
|
3
3
|
module Kernel
|
4
4
|
|
5
|
-
#
|
5
|
+
# abstraction:: only include the methods given by _meths_
|
6
|
+
# implementation:: includes a duplicate of _mod_ with all uneeded instance methods removed
|
6
7
|
def import(mod, *meths)
|
7
|
-
|
8
|
-
mod_dup = mod.dup
|
9
|
-
mod_dup.module_eval &block if block
|
10
|
-
include mod_dup
|
11
|
-
end
|
8
|
+
mod_dup = mod.dup
|
12
9
|
|
13
|
-
|
14
|
-
include_module_copy.call(nil)
|
10
|
+
unless meths.empty?
|
15
11
|
|
16
|
-
else
|
17
12
|
# get list of methods to remove module
|
18
13
|
ims = mod.instance_methods.map {|m| m.to_sym}
|
19
|
-
|
14
|
+
removes = ims - meths
|
15
|
+
|
16
|
+
if removes.size != (ims.size - meths.size)
|
20
17
|
raise ImportError, "##{(meths - ims).join(' and #')} not found in #{mod}"
|
21
18
|
end
|
22
|
-
ims = ims - meths
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
20
|
+
mod_dup.module_eval do
|
21
|
+
removes.each { |meth| remove_method meth }
|
22
|
+
end
|
27
23
|
end
|
24
|
+
|
25
|
+
include mod_dup
|
28
26
|
end
|
29
27
|
end
|
Binary file
|
Binary file
|
data/rakefile
CHANGED
@@ -1,19 +1,100 @@
|
|
1
1
|
rubyforge_project = "'module import'"
|
2
2
|
project = 'module-import'
|
3
|
-
|
4
|
-
|
3
|
+
|
4
|
+
def exit_msg(msg, code=1)
|
5
|
+
puts msg
|
6
|
+
exit(code)
|
7
|
+
end
|
8
|
+
def run command
|
9
|
+
res = `#{command}`
|
10
|
+
exit_msg res, $?.exitstatus if $?.exitstatus != 0
|
11
|
+
res
|
12
|
+
end
|
13
|
+
|
14
|
+
def __DIR__; "#{File.dirname(__FILE__)}" end
|
15
|
+
class IO
|
16
|
+
def self.write( file, str )
|
17
|
+
self.open( file, 'w' ) { |fh| fh.print str }
|
18
|
+
end
|
19
|
+
def self.read_write( file, write_file=file )
|
20
|
+
self.write(write_file, (yield( self.read( file ))))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def cd_tmp
|
25
|
+
Dir.mkdir 'tmp' unless File.directory? 'tmp'
|
26
|
+
Dir.chdir('tmp') do |dir|
|
27
|
+
yield dir
|
28
|
+
end
|
29
|
+
rm_rf 'tmp'
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "test run all tests"
|
33
|
+
task :test => [:spec, 'test:readme', :rcov]
|
34
|
+
|
35
|
+
namespace :test do
|
36
|
+
# run README through xmp
|
37
|
+
desc "run README code through xmp filter"
|
38
|
+
task :readme do
|
39
|
+
cd_tmp do
|
40
|
+
example_file = "#{__DIR__}/example.rb"
|
41
|
+
|
42
|
+
File.write(example_file, (
|
43
|
+
File.read("#{__DIR__}/lib/import.rb") <<
|
44
|
+
File.readlines('../README').grep(/^ / ).
|
45
|
+
reject {|l| l =~ /^\s*require/ or l.include?('Error')}.
|
46
|
+
join ))
|
47
|
+
|
48
|
+
command = "ruby ../bin/xmpfilter -c #{example_file}"
|
49
|
+
Dir.chdir '/home/greg/src/head/lib' do
|
50
|
+
run "#{command}"
|
51
|
+
end
|
52
|
+
puts "README code successfully evaluated"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "run specs"
|
58
|
+
task :spec do
|
5
59
|
Dir[ 'spec/*' ].each do |file|
|
6
|
-
puts
|
7
|
-
|
60
|
+
(puts (run "spec #{file}"))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
require 'rubygems'
|
65
|
+
require 'spec/rake/spectask'
|
66
|
+
|
67
|
+
desc "verify test coverage with RCov"
|
68
|
+
task :rcov => 'rcov:verify'
|
69
|
+
namespace :rcov do
|
70
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
71
|
+
t.spec_files = ['spec/*.rb']
|
72
|
+
t.rcov = true
|
73
|
+
t.rcov_opts = ['--exclude', 'spec']
|
74
|
+
end
|
75
|
+
|
76
|
+
require 'spec/rake/verify_rcov'
|
77
|
+
# rcov is wrong- I am actually at 100%
|
78
|
+
RCov::VerifyTask.new(:verify => :rcov) do |t|
|
79
|
+
t.threshold = 100 # Make sure you have rcov 0.7 or higher!
|
80
|
+
t.index_html = 'coverage/lib-import_rb.html'
|
8
81
|
end
|
9
82
|
end
|
10
83
|
|
11
84
|
desc "release a new gem to rubyforge"
|
12
|
-
task :release => [:rdoc,:package] do
|
85
|
+
task :release => [:test,:record,:rdoc,:website,:package] do
|
13
86
|
Dir.chdir('pkg') do
|
14
87
|
release = Dir['*.gem'].sort_by {|file| File.mtime(file)}.last
|
15
88
|
release =~ /^[^-]+-([.0-9]+).gem$/
|
16
|
-
`rubyforge login && rubyforge add_release #{project} #{project} #$1 #{release}`
|
89
|
+
(puts (run `rubyforge login && rubyforge add_release #{project} #{project} #$1 #{release}`))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
desc "update website"
|
94
|
+
file :website => ['README','rakefile'] do
|
95
|
+
Dir.chdir '/home/greg/sites/projects/' do
|
96
|
+
(puts (run 'rake projects:update'))
|
97
|
+
(puts (run 'rake deploy:rsync'))
|
17
98
|
end
|
18
99
|
end
|
19
100
|
|
@@ -24,12 +105,14 @@ end
|
|
24
105
|
|
25
106
|
namespace :readme do
|
26
107
|
desc "create html for website using coderay, use --silent option"
|
27
|
-
task :html
|
108
|
+
task :html do
|
109
|
+
rm_rf 'doc'
|
110
|
+
`rdoc --quiet README`
|
28
111
|
require 'hpricot'
|
29
112
|
doc = open( 'doc/files/README.html' ) { |f| Hpricot(f) }
|
30
113
|
# find example code
|
31
|
-
doc.at('#description').search('pre').
|
32
|
-
select {|elem| elem.inner_html =~ /class |module /}.each do |ex|
|
114
|
+
doc.at('#description').search('pre').each do |ex|
|
115
|
+
#select {|elem| elem.inner_html =~ /class |module /}.each do |ex|
|
33
116
|
# add coderay and undo what rdoc has done in the example code
|
34
117
|
ex.swap("<coderay lang='ruby'>#{ex.inner_html.gsub('"', '"').gsub('>','>')}</coderay>")
|
35
118
|
end
|
@@ -37,13 +120,24 @@ namespace :readme do
|
|
37
120
|
end
|
38
121
|
end
|
39
122
|
|
123
|
+
desc 'git add and push'
|
124
|
+
task :record do
|
125
|
+
unless `git diff`.chomp.empty?
|
126
|
+
ARGV.clear
|
127
|
+
puts "enter commit message"
|
128
|
+
(puts (run "git commit -a -m #{Kernel.gets}"))
|
129
|
+
puts "committed! now pushing.. "
|
130
|
+
(puts (run 'git push origin master'))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
40
134
|
require 'rubygems'
|
41
135
|
require 'rake/gempackagetask'
|
42
136
|
|
43
137
|
spec = Gem::Specification.new do |s|
|
44
138
|
s.name = project
|
45
139
|
s.rubyforge_project = project
|
46
|
-
s.version = "0.
|
140
|
+
s.version = "0.2.2"
|
47
141
|
s.author = "Greg Weber"
|
48
142
|
s.email = "greg@gregweber.info"
|
49
143
|
s.homepage = "http://projects.gregweber.info/#{project}"
|
@@ -58,3 +152,19 @@ end
|
|
58
152
|
Rake::GemPackageTask.new(spec) do |pkg|
|
59
153
|
pkg.need_tar = false
|
60
154
|
end
|
155
|
+
|
156
|
+
desc "run this once to set up the project"
|
157
|
+
task :setup do
|
158
|
+
cd_tmp do
|
159
|
+
unless File.exist? 'index.html'
|
160
|
+
File.write('index.html', <<-EOF
|
161
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
162
|
+
<html><head>
|
163
|
+
<meta http-equiv="REFRESH" content="0;url=http://projects.gregweber.info/#{project}"></head>
|
164
|
+
</html>
|
165
|
+
EOF
|
166
|
+
)
|
167
|
+
end
|
168
|
+
run "scp index.html gregwebs@rubyforge.org:/var/www/gforge-projects/#{project}"
|
169
|
+
end
|
170
|
+
end
|
data/spec/import_spec.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../lib/import'
|
2
2
|
|
3
|
+
# testing helpers
|
3
4
|
def module_with_new
|
4
5
|
Module.new do
|
5
|
-
def self.new
|
6
|
-
(Class.new.send :include, self
|
6
|
+
def self.new
|
7
|
+
(Class.new.send :include, self).new
|
7
8
|
end
|
8
9
|
end
|
9
10
|
end
|
@@ -19,7 +20,7 @@ def class_with_super(superclass)
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def class_and_module(times=nil)
|
22
|
-
if
|
23
|
+
if not times or times == 1
|
23
24
|
[Class.new, module_with_new()]
|
24
25
|
else
|
25
26
|
[(0...times).map{|i| Class.new}, (0...times).map{|i| module_with_new()}]
|
@@ -74,13 +75,13 @@ describe "import" do
|
|
74
75
|
|
75
76
|
it 'should not be effected by changes to the module' do
|
76
77
|
class_and_module(2).each do |imp,inc|
|
77
|
-
|
78
|
+
bar = Module.new do
|
78
79
|
def foo; 'foo' end
|
79
80
|
end
|
80
|
-
bar_orig_ims =
|
81
|
+
bar_orig_ims = bar.instance_methods
|
81
82
|
|
82
|
-
imp.send :import,
|
83
|
-
inc.send :include,
|
83
|
+
imp.send :import, bar
|
84
|
+
inc.send :include, bar
|
84
85
|
|
85
86
|
imp.instance_methods.sort.should == inc.instance_methods.sort
|
86
87
|
(bar_orig_ims - imp.instance_methods).should be_empty
|
@@ -91,7 +92,7 @@ describe "import" do
|
|
91
92
|
lambda{k.bar}.should raise_error(NoMethodError)
|
92
93
|
end
|
93
94
|
|
94
|
-
|
95
|
+
bar.module_eval do
|
95
96
|
def extra_method; fail end
|
96
97
|
|
97
98
|
def bar; 'bar' end
|
@@ -107,7 +108,7 @@ describe "import" do
|
|
107
108
|
lambda{imp.new.bar}.should raise_error(NoMethodError)
|
108
109
|
|
109
110
|
(imp.instance_methods - inc.instance_methods).should == ['foo']
|
110
|
-
(inc.instance_methods - imp.instance_methods).sort.should == (
|
111
|
+
(inc.instance_methods - imp.instance_methods).sort.should == (bar.instance_methods - bar_orig_ims).sort
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
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.2.2
|
7
|
+
date: 2008-03-11 00:00:00 -05:00
|
8
8
|
summary: selectively import methods from modules
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -35,6 +35,9 @@ files:
|
|
35
35
|
- ./spec
|
36
36
|
- ./README
|
37
37
|
- ./rakefile
|
38
|
+
- ./example.rb
|
39
|
+
- ./coverage
|
40
|
+
- ./delete.html
|
38
41
|
- doc/files
|
39
42
|
- doc/index.html
|
40
43
|
- doc/rdoc-style.css
|
@@ -44,7 +47,12 @@ files:
|
|
44
47
|
- doc/created.rid
|
45
48
|
- doc/classes
|
46
49
|
- lib/import.rb
|
50
|
+
- pkg/module-import-0.1.0.gem
|
51
|
+
- pkg/module-import-0.2.1.gem
|
47
52
|
- spec/import_spec.rb
|
53
|
+
- coverage/index.html
|
54
|
+
- coverage/-var-lib-gems-1_8-gems-rcov-0_8_0_2-lib-rcov_rb.html
|
55
|
+
- coverage/lib-import_rb.html
|
48
56
|
- README
|
49
57
|
test_files: []
|
50
58
|
|