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.
@@ -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