module-import 0.1.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,92 @@
1
+ <html>
2
+ <body>
3
+ &lt;div id=<span class="s"><span class="dl">&quot;</span><span class="k">description</span><span class="dl">&quot;</span></span>&gt;
4
+ &lt;h2&gt;<span class="co">Summary</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">h2&gt;
5
+ &lt;p&gt;
6
+ selectively include module methods
7
+ &lt;</span><span class="dl">/</span></span>p&gt;
8
+ &lt;h2&gt;<span class="co">Author</span> <span class="r">and</span> <span class="co">License</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">h2&gt;
9
+ &lt;p&gt;
10
+ Copyright (c) 2008 Greg Weber, &lt;a href=&quot;http:</span><span class="dl">/</span></span>/gregweber.info<span class="s"><span class="dl">&quot;</span><span class="k">&gt;gregweber.info&lt;/a&gt; Licensed under the MIT
11
+ license
12
+ &lt;/p&gt;
13
+ &lt;h2&gt;Usage&lt;/h2&gt;
14
+ &lt;coderay lang=</span><span class="dl">&quot;</span></span>ruby<span class="s"><span class="dl">&quot;</span><span class="k">&gt;
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 # =&gt; 'bar'
27
+ Importer.new.foo # =&gt; # NoMethodError
28
+
29
+ class Importer
30
+ import Foo, :not_defined # =&gt; #not_defined not found in Foo (ImportError)
31
+ end
32
+ &lt;/coderay&gt;
33
+ &lt;p&gt;
34
+ Giving no methods (or all methods) should behave the same as a normal
35
+ include
36
+ &lt;/p&gt;
37
+ &lt;coderay lang=</span><span class="dl">&quot;</span></span>ruby<span class="s"><span class="dl">&quot;</span><span class="k">&gt;
38
+ class Importer2
39
+ import Foo # same as import Foo, :foo, :bar
40
+ end
41
+ Importer2.new.bar # =&gt; 'bar'
42
+ Importer2.new.foo # =&gt; 'foo'
43
+ &lt;/coderay&gt;
44
+ &lt;p&gt;
45
+ However, there is one important difference. New changes in the included
46
+ module will not effect the class.
47
+ &lt;/p&gt;
48
+ &lt;coderay lang=</span><span class="dl">&quot;</span></span>ruby<span class="s"><span class="dl">&quot;</span><span class="k">&gt;
49
+ module Foo
50
+ undef_method :foo
51
+ def bar; fail end
52
+ end
53
+ Importer2.new.bar # =&gt; 'bar'
54
+ Importer2.new.foo # =&gt; 'foo'
55
+ &lt;/coderay&gt;
56
+ &lt;h2&gt;Install&lt;/h2&gt;
57
+ &lt;p&gt;
58
+ gem install module-import
59
+ &lt;/p&gt;
60
+ &lt;h2&gt;Source&lt;/h2&gt;
61
+ &lt;h3&gt;browser&lt;/h3&gt;
62
+ &lt;p&gt;
63
+ &lt;a href=</span><span class="dl">&quot;</span></span>http<span class="sy">:/</span>/github.com/gregwebs/<span class="r">module</span>-import/tree/master<span class="s"><span class="dl">&quot;</span><span class="k">&gt;github.com/gregwebs/module-import/tree/master&lt;/a&gt;
64
+ &lt;/p&gt;
65
+ &lt;h3&gt;repository&lt;/h3&gt;
66
+ &lt;p&gt;
67
+ git clone git://github.com/gregwebs/module-import.git
68
+ &lt;/p&gt;
69
+ &lt;h2&gt;Homepage&lt;/h2&gt;
70
+ &lt;p&gt;
71
+ &lt;a href=</span><span class="dl">&quot;</span></span>http<span class="sy">:/</span>/gregweber.info/projects/<span class="r">module</span>-import.html<span class="s"><span class="dl">&quot;</span><span class="k">&gt;gregweber.info/projects/module-import.html&lt;/a&gt;
72
+ &lt;/p&gt;
73
+ &lt;h2&gt;RDoc documentation&lt;/h2&gt;
74
+ &lt;p&gt;
75
+ included with the gem
76
+ &lt;/p&gt;
77
+ &lt;h2&gt;Notes&lt;/h2&gt;
78
+ &lt;h3&gt;Testing&lt;/h3&gt;
79
+ &lt;p&gt;
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
+ &lt;/p&gt;
84
+ &lt;h3&gt;Implementation&lt;/h3&gt;
85
+ &lt;p&gt;
86
+ Includes a duplicate of the module that has methods removed
87
+ &lt;/p&gt;
88
+
89
+ &lt;/div&gt;
90
+ </span></span>
91
+ </body>
92
+ </html>
@@ -1 +1 @@
1
- Sun, 09 Mar 2008 12:30:11 -0500
1
+ Tue, 11 Mar 2008 13:44:27 -0500
@@ -20,8 +20,6 @@
20
20
  <div id="index">
21
21
  <h1 class="section-bar">Classes</h1>
22
22
  <div id="index-entries">
23
- <a href="classes/ImportError.html">ImportError</a><br />
24
- <a href="classes/Kernel.html">Kernel</a><br />
25
23
  </div>
26
24
  </div>
27
25
  </body>
@@ -21,7 +21,6 @@
21
21
  <h1 class="section-bar">Files</h1>
22
22
  <div id="index-entries">
23
23
  <a href="files/README.html">README</a><br />
24
- <a href="files/lib/import_rb.html">lib/import.rb</a><br />
25
24
  </div>
26
25
  </div>
27
26
  </body>
@@ -20,7 +20,6 @@
20
20
  <div id="index">
21
21
  <h1 class="section-bar">Methods</h1>
22
22
  <div id="index-entries">
23
- <a href="classes/Kernel.html#M000001">import (Kernel)</a><br />
24
23
  </div>
25
24
  </div>
26
25
  </body>
@@ -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'
@@ -2,28 +2,26 @@ class ImportError < Exception; end
2
2
 
3
3
  module Kernel
4
4
 
5
- # include a duplicate of the module with all uneeded instance methods removed
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
- include_module_copy = lambda do |block|
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
- if meths.size == 0
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
- if (ims & meths).size != meths.size
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
- include_module_copy.call( lambda do
25
- ims.each { |meth| remove_method meth }
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
data/rakefile CHANGED
@@ -1,19 +1,100 @@
1
1
  rubyforge_project = "'module import'"
2
2
  project = 'module-import'
3
- desc "test"
4
- task :test do
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 `spec #{file}`
7
- exit $?.exitstatus if $?.exitstatus != 0
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 => :rdoc do
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('&quot;', '"').gsub('&gt;','>')}</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.1.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
@@ -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 *args
6
- (Class.new.send :include, self, *args).new
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 !times or times == 1
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
- Bar = Module.new do
78
+ bar = Module.new do
78
79
  def foo; 'foo' end
79
80
  end
80
- bar_orig_ims = Bar.instance_methods
81
+ bar_orig_ims = bar.instance_methods
81
82
 
82
- imp.send :import, Bar
83
- inc.send :include, Bar
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
- Bar.module_eval do
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 == (Bar.instance_methods - bar_orig_ims).sort
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.1.0
7
- date: 2008-03-09 00:00:00 -06:00
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