use 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,13 @@
1
+ == 1.2.2 - 16-Sep-2008
2
+ * Fixed a bug where methods already defined prior to the inclusion
3
+ of a module could be accidentally undefined.
4
+ * Added some inline documentation for the sake of RDoc.
5
+ * Renamed test/test_data.rb to test/sample_data.rb, since it's not an
6
+ actual test file.
7
+ * Renamed test/tc_use.rb to test/test_use.rb to be more in line with what
8
+ both Rake and Test::Unit (and the Ruby community in general) expect.
9
+ * Minor Rakefile update.
10
+
1
11
  == 1.2.1 - 22-May-2007
2
12
  * Added a Rakefile, with tasks for testing and installation.
3
13
  * Removed the install.rb file. Installation is now handled by the 'rake
data/MANIFEST CHANGED
@@ -5,5 +5,5 @@
5
5
  * use.gemspec
6
6
  * examples/example_use.rb
7
7
  * lib/use.rb
8
- * test/tc_use.rb
9
- * test/test_data.rb
8
+ * test/test_use.rb
9
+ * test/sample_data.rb
data/Rakefile CHANGED
@@ -1,24 +1,23 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rbconfig'
4
- include Config
5
-
6
- desc 'Install the use package (non-gem)'
7
- task :install do
8
- sitelibdir = CONFIG["sitelibdir"]
9
- file = "lib/use.rb"
10
- FileUtils.cp(file, sitelibdir, :verbose => true)
11
- end
12
-
13
- task :install_gem do
14
- ruby 'use.gemspec'
15
- file = Dir["*.gem"].first
16
- sh "gem install #{file}"
17
- end
18
-
19
- Rake::TestTask.new do |t|
20
- t.libs << 'test'
21
- t.verbose = true
22
- t.warning = true
23
- t.test_files = FileList['test/tc_use.rb']
24
- end
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rbconfig'
4
+ include Config
5
+
6
+ desc 'Install the use package (non-gem)'
7
+ task :install do
8
+ sitelibdir = CONFIG["sitelibdir"]
9
+ file = "lib/use.rb"
10
+ FileUtils.cp(file, sitelibdir, :verbose => true)
11
+ end
12
+
13
+ task :install_gem do
14
+ ruby 'use.gemspec'
15
+ file = Dir["*.gem"].first
16
+ sh "gem install #{file}"
17
+ end
18
+
19
+ Rake::TestTask.new do |t|
20
+ t.libs << 'test'
21
+ t.verbose = true
22
+ t.warning = true
23
+ end
data/lib/use.rb CHANGED
@@ -1,91 +1,159 @@
1
- class Class
2
- USE_VERSION = '1.2.1'
3
- def use(*args)
4
- valid_keys = %w/include exclude alias/
5
- excluded = []
6
- included = []
7
- aliased = []
8
-
9
- mod = args.shift.clone
10
-
11
- # If no arguments follow the module name, treat it as a standard include
12
- if args.empty?
13
- included.concat(mod.instance_methods)
14
- end
15
-
16
- m = Module.new
17
-
18
- args.each{ |arg|
19
- if arg.kind_of?(Hash)
20
- arg.each{ |key, val|
21
- case key.to_s
22
- when "include"
23
- if val.respond_to?(:each)
24
- val.each{ |arg| included.push(arg.to_s) }
25
- else
26
- included.push(val.to_s)
27
- end
28
- when "exclude"
29
- if val.respond_to?(:each)
30
- val.each{ |arg| excluded.push(arg.to_s) }
31
- else
32
- excluded.push(val.to_s)
33
- end
34
- when "alias"
35
- aliased.push(val)
36
- else
37
- raise "invalid key '#{key}'"
38
- end
39
- }
40
- else
41
- included.push(arg.to_s)
42
- end
43
- }
44
-
45
- unless included.empty? || excluded.empty?
46
- err = "you cannot include and exclude in the same statement"
47
- raise ArgumentError, err
48
- end
49
-
50
- imethods = mod.instance_methods
51
-
52
- # Remove excluded methods
53
- unless excluded.empty?
54
- (imethods & excluded).each{ |meth|
55
- mod.module_eval{ remove_method(meth) }
56
- }
57
- end
58
-
59
- # Alias methods
60
- aliased.each{ |pair|
61
- pair.each{ |old, new|
62
- included.push(old) # Aliased methods automatically included
63
- mod.module_eval{
64
- alias_method(new, old)
65
- remove_method(old)
66
- }
67
- }
68
- }
69
-
70
- # Remove all methods not specifically included. The rescue was needed
71
- # for those cases where a module included another module.
72
- unless included.empty?
73
- (imethods - included).each{ |meth|
74
- mod.module_eval{ undef_method(meth) rescue nil }
75
- }
76
- end
77
-
78
- m.module_eval{ include mod }
79
-
80
- # Raise a warning if methods are shadowed (in $VERBOSE mode)
81
- if $VERBOSE
82
- imethods = instance_methods(true)
83
- m.instance_methods.each{ |meth|
84
- next unless imethods.include?(meth)
85
- warn "method '#{meth}' aliased, shadows old '#{meth}'"
86
- }
87
- end
88
-
89
- include m
90
- end
91
- end
1
+ class Class
2
+ # The version of the 'use' library
3
+ USE_VERSION = '1.2.2'
4
+
5
+ # Allows you to include mixins in a fine grained manner. Instead of
6
+ # including all methods from a given module, you can can instead mixin
7
+ # only those methods you want through a combination of the :include,
8
+ # :exclude, and :alias options.
9
+ #
10
+ # Examples:
11
+ #
12
+ # # Defines a 'bar' and 'baz' method
13
+ # module Foo
14
+ # def bar
15
+ # "hello"
16
+ # end
17
+ # def baz
18
+ # "world"
19
+ # end
20
+ # end
21
+ #
22
+ # # Defines a 'bar', 'blah', and 'zap' methods
23
+ # module Test
24
+ # def bar
25
+ # "goodbye"
26
+ # end
27
+ # def blah
28
+ # "new york"
29
+ # end
30
+ # def zap
31
+ # "zap"
32
+ # end
33
+ # end
34
+ #
35
+ # # From the Foo module, only mixin the 'bar' method. From the Test
36
+ # # module exclude the 'bar' and 'zap' methods.
37
+ # class Zap
38
+ # use Foo, :bar
39
+ # use Test, :exclude => [:bar, :zap]
40
+ # end
41
+ #
42
+ # z = Zap.new
43
+ #
44
+ # z.bar # => "hello"
45
+ # z.baz # => NoMethodError - wasn't mixed in
46
+ # z.zap # => NoMethodError - wasn't mixed in
47
+ # z.blah # =>"new york"
48
+ #
49
+ # # Alias a method on the fly
50
+ # class MyKlass
51
+ # use Foo :alias => {:bar, :test}
52
+ # end
53
+ #
54
+ # m = MyKlass.new
55
+ # m.test # => "hello"
56
+ # m.bar # => NoMethodError - was aliased to 'test'
57
+ #
58
+ # If no options follow the module name this method is identical
59
+ # to a standard include.
60
+ #
61
+ def use(*args)
62
+ valid_keys = %w/include exclude alias/
63
+ excluded = []
64
+ included = []
65
+ aliased = []
66
+
67
+ mod = args.shift.clone
68
+
69
+ # If no arguments follow the module name, treat it as a standard include
70
+ if args.empty?
71
+ included.concat(mod.instance_methods)
72
+ end
73
+
74
+ m = Module.new
75
+
76
+ args.each{ |arg|
77
+ if arg.kind_of?(Hash)
78
+ arg.each{ |key, val|
79
+ case key.to_s
80
+ when "include"
81
+ if val.respond_to?(:each)
82
+ val.each{ |arg| included.push(arg.to_s) }
83
+ else
84
+ included.push(val.to_s)
85
+ end
86
+ when "exclude"
87
+ if val.respond_to?(:each)
88
+ val.each{ |arg| excluded.push(arg.to_s) }
89
+ else
90
+ excluded.push(val.to_s)
91
+ end
92
+ when "alias"
93
+ aliased.push(val)
94
+ else
95
+ raise "invalid key '#{key}'"
96
+ end
97
+ }
98
+ else
99
+ included.push(arg.to_s)
100
+ end
101
+ }
102
+
103
+ unless included.empty? || excluded.empty?
104
+ err = "you cannot include and exclude in the same statement"
105
+ raise ArgumentError, err
106
+ end
107
+
108
+ imethods = mod.instance_methods
109
+
110
+ # Remove excluded methods
111
+ unless excluded.empty?
112
+ (imethods & excluded).each{ |meth|
113
+ mod.module_eval{ remove_method(meth) }
114
+ }
115
+ end
116
+
117
+ # Alias methods
118
+ aliased.each{ |pair|
119
+ pair.each{ |old, new|
120
+ included.push(old) # Aliased methods automatically included
121
+ mod.module_eval{
122
+ alias_method(new, old)
123
+ remove_method(old)
124
+ }
125
+ }
126
+ }
127
+
128
+ # Remove all methods not specifically included. The rescue was needed
129
+ # for those cases where a module included another module. Also, don't
130
+ # remove methods from classes that already exist unless specifically
131
+ # included.
132
+ unless included.empty?
133
+ (imethods - included).each{ |meth|
134
+ if superclass.instance_methods.include?(meth)
135
+ if included.include?(meth)
136
+ mod.module_eval{ undef_method(meth) rescue nil }
137
+ else
138
+ mod.module_eval{ remove_method(meth) rescue nil }
139
+ end
140
+ else
141
+ mod.module_eval{ undef_method(meth) rescue nil }
142
+ end
143
+ }
144
+ end
145
+
146
+ m.module_eval{ include mod }
147
+
148
+ # Raise a warning if methods are shadowed (in $VERBOSE mode)
149
+ if $VERBOSE
150
+ imethods = instance_methods(true)
151
+ m.instance_methods.each{ |meth|
152
+ next unless imethods.include?(meth)
153
+ warn "method '#{meth}' aliased, shadows old '#{meth}'"
154
+ }
155
+ end
156
+
157
+ include m
158
+ end
159
+ end
@@ -1,64 +1,64 @@
1
- ##################################################
2
- # test_data.rb
3
- #
4
- # Test modules and classes for the 'use' package.
5
- ##################################################
6
- module ModA
7
- def meth_a
8
- "ModA#meth_a"
9
- end
10
-
11
- def meth_b
12
- "ModA#meth_b"
13
- end
14
-
15
- def meth_c
16
- "ModA#meth_c"
17
- end
18
- end
19
-
20
- module ModB
21
- include ModA
22
- def meth_a
23
- "ModB#meth_a"
24
- end
25
-
26
- def meth_b
27
- "ModB#meth_b"
28
- end
29
- end
30
-
31
- module ModC
32
- def meth_x
33
- "ModC#meth_x"
34
- end
35
-
36
- def meth_y
37
- "ModC#meth_y"
38
- end
39
-
40
- def meth_z
41
- "ModC#meth_z"
42
- end
43
- end
44
-
45
- class ClassA
46
- use ModA, :meth_a
47
- end
48
-
49
- class ClassB
50
- use ModB, :include => :meth_c, :alias => {:meth_b, :meth_z}
51
- end
52
-
53
- class ClassC
54
- use ModA, :exclude => [:meth_b, :meth_c]
55
- use ModC
56
-
57
- def meth_c
58
- "ClassC#meth_c"
59
- end
60
- end
61
-
62
- class ClassD
63
- use ModA, :alias => {:meth_a, :meth_x, :meth_c, :meth_z}, :exclude => :meth_b
64
- end
1
+ ##################################################
2
+ # test_data.rb
3
+ #
4
+ # Test modules and classes for the 'use' package.
5
+ ##################################################
6
+ module ModA
7
+ def meth_a
8
+ "ModA#meth_a"
9
+ end
10
+
11
+ def meth_b
12
+ "ModA#meth_b"
13
+ end
14
+
15
+ def meth_c
16
+ "ModA#meth_c"
17
+ end
18
+ end
19
+
20
+ module ModB
21
+ include ModA
22
+ def meth_a
23
+ "ModB#meth_a"
24
+ end
25
+
26
+ def meth_b
27
+ "ModB#meth_b"
28
+ end
29
+ end
30
+
31
+ module ModC
32
+ def meth_x
33
+ "ModC#meth_x"
34
+ end
35
+
36
+ def meth_y
37
+ "ModC#meth_y"
38
+ end
39
+
40
+ def meth_z
41
+ "ModC#meth_z"
42
+ end
43
+ end
44
+
45
+ class ClassA
46
+ use ModA, :meth_a
47
+ end
48
+
49
+ class ClassB
50
+ use ModB, :include => :meth_c, :alias => {:meth_b, :meth_z}
51
+ end
52
+
53
+ class ClassC
54
+ use ModA, :exclude => [:meth_b, :meth_c]
55
+ use ModC
56
+
57
+ def meth_c
58
+ "ClassC#meth_c"
59
+ end
60
+ end
61
+
62
+ class ClassD
63
+ use ModA, :alias => {:meth_a, :meth_x, :meth_c, :meth_z}, :exclude => :meth_b
64
+ end
@@ -1,96 +1,96 @@
1
- #######################################################################
2
- # tc_use.rb
3
- #
4
- # Test cases for the 'use' package. The relevant modules and classes
5
- # are stored in the 'test_data.rb' file. This test should be run via
6
- # the 'rake test' task.
7
- #######################################################################
8
- require 'use'
9
- require 'test_data'
10
- require 'test/unit'
11
-
12
- class TC_Use < Test::Unit::TestCase
13
- def setup
14
- @a = ClassA.new
15
- @b = ClassB.new
16
- @c = ClassC.new
17
- @d = ClassD.new
18
- end
19
-
20
- def test_version
21
- assert_equal('1.2.1', Class::USE_VERSION)
22
- end
23
-
24
- def test_mod_a_methods
25
- assert_equal(['meth_a', 'meth_b', 'meth_c'], ModA.instance_methods.sort)
26
- end
27
-
28
- def test_mod_b_methods
29
- assert_equal(['meth_a', 'meth_b', 'meth_c'], ModB.instance_methods.sort)
30
- end
31
-
32
- def test_mod_c_methods
33
- assert_equal(['meth_x', 'meth_y', 'meth_z'], ModC.instance_methods.sort)
34
- end
35
-
36
- def test_class_a_methods
37
- assert_respond_to(@a, :meth_a)
38
- assert_equal('ModA#meth_a', @a.meth_a)
39
- end
40
-
41
- def test_class_a_expected_errors
42
- assert_raises(NoMethodError){ @a.meth_b }
43
- assert_raises(NoMethodError){ @a.meth_c }
44
- end
45
-
46
- def test_class_b_methods
47
- assert_respond_to(@b, :meth_c)
48
- assert_respond_to(@b, :meth_z)
49
- assert_equal('ModA#meth_c', @b.meth_c)
50
- assert_equal('ModB#meth_b', @b.meth_z)
51
- end
52
-
53
- def test_class_b_expected_errors
54
- assert_raises(NoMethodError){ @b.meth_a }
55
- assert_raises(NoMethodError){ @b.meth_b }
56
- end
57
-
58
- def test_class_c_methods
59
- assert_respond_to(@c, :meth_a)
60
- assert_respond_to(@c, :meth_c)
61
- assert_respond_to(@c, :meth_x)
62
- assert_respond_to(@c, :meth_y)
63
- assert_respond_to(@c, :meth_z)
64
-
65
- assert_equal('ModA#meth_a', @c.meth_a)
66
- assert_equal('ClassC#meth_c', @c.meth_c)
67
- assert_equal('ModC#meth_x', @c.meth_x)
68
- assert_equal('ModC#meth_y', @c.meth_y)
69
- assert_equal('ModC#meth_z', @c.meth_z)
70
- end
71
-
72
- def test_class_c_expected_errors
73
- assert_raises(NoMethodError){ @c.meth_b }
74
- end
75
-
76
- def test_class_d_methods
77
- assert_respond_to(@d, :meth_x)
78
- assert_respond_to(@d, :meth_z)
79
-
80
- assert_equal('ModA#meth_a', @d.meth_x)
81
- assert_equal('ModA#meth_c', @d.meth_z)
82
- end
83
-
84
- def test_class_d_expected_errors
85
- assert_raises(NoMethodError){ @d.meth_a }
86
- assert_raises(NoMethodError){ @d.meth_b }
87
- assert_raises(NoMethodError){ @d.meth_c }
88
- end
89
-
90
- def teardown
91
- @a = nil
92
- @b = nil
93
- @c = nil
94
- @d = nil
95
- end
96
- end
1
+ #######################################################################
2
+ # test_use.rb
3
+ #
4
+ # Test cases for the 'use' package. The relevant modules and classes
5
+ # are stored in the 'test_data.rb' file. This test should be run via
6
+ # the 'rake test' task.
7
+ #######################################################################
8
+ require 'use'
9
+ require 'sample_data'
10
+ require 'test/unit'
11
+
12
+ class TC_Use < Test::Unit::TestCase
13
+ def setup
14
+ @a = ClassA.new
15
+ @b = ClassB.new
16
+ @c = ClassC.new
17
+ @d = ClassD.new
18
+ end
19
+
20
+ def test_version
21
+ assert_equal('1.2.2', Class::USE_VERSION)
22
+ end
23
+
24
+ def test_mod_a_methods
25
+ assert_equal(['meth_a', 'meth_b', 'meth_c'], ModA.instance_methods.sort)
26
+ end
27
+
28
+ def test_mod_b_methods
29
+ assert_equal(['meth_a', 'meth_b', 'meth_c'], ModB.instance_methods.sort)
30
+ end
31
+
32
+ def test_mod_c_methods
33
+ assert_equal(['meth_x', 'meth_y', 'meth_z'], ModC.instance_methods.sort)
34
+ end
35
+
36
+ def test_class_a_methods
37
+ assert_respond_to(@a, :meth_a)
38
+ assert_equal('ModA#meth_a', @a.meth_a)
39
+ end
40
+
41
+ def test_class_a_expected_errors
42
+ assert_raises(NoMethodError){ @a.meth_b }
43
+ assert_raises(NoMethodError){ @a.meth_c }
44
+ end
45
+
46
+ def test_class_b_methods
47
+ assert_respond_to(@b, :meth_c)
48
+ assert_respond_to(@b, :meth_z)
49
+ assert_equal('ModA#meth_c', @b.meth_c)
50
+ assert_equal('ModB#meth_b', @b.meth_z)
51
+ end
52
+
53
+ def test_class_b_expected_errors
54
+ assert_raises(NoMethodError){ @b.meth_a }
55
+ assert_raises(NoMethodError){ @b.meth_b }
56
+ end
57
+
58
+ def test_class_c_methods
59
+ assert_respond_to(@c, :meth_a)
60
+ assert_respond_to(@c, :meth_c)
61
+ assert_respond_to(@c, :meth_x)
62
+ assert_respond_to(@c, :meth_y)
63
+ assert_respond_to(@c, :meth_z)
64
+
65
+ assert_equal('ModA#meth_a', @c.meth_a)
66
+ assert_equal('ClassC#meth_c', @c.meth_c)
67
+ assert_equal('ModC#meth_x', @c.meth_x)
68
+ assert_equal('ModC#meth_y', @c.meth_y)
69
+ assert_equal('ModC#meth_z', @c.meth_z)
70
+ end
71
+
72
+ def test_class_c_expected_errors
73
+ assert_raises(NoMethodError){ @c.meth_b }
74
+ end
75
+
76
+ def test_class_d_methods
77
+ assert_respond_to(@d, :meth_x)
78
+ assert_respond_to(@d, :meth_z)
79
+
80
+ assert_equal('ModA#meth_a', @d.meth_x)
81
+ assert_equal('ModA#meth_c', @d.meth_z)
82
+ end
83
+
84
+ def test_class_d_expected_errors
85
+ assert_raises(NoMethodError){ @d.meth_a }
86
+ assert_raises(NoMethodError){ @d.meth_b }
87
+ assert_raises(NoMethodError){ @d.meth_c }
88
+ end
89
+
90
+ def teardown
91
+ @a = nil
92
+ @b = nil
93
+ @c = nil
94
+ @d = nil
95
+ end
96
+ end
data/use.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ require "rubygems"
2
+
3
+ spec = Gem::Specification.new do |gem|
4
+ gem.name = "use"
5
+ gem.version = "1.2.2"
6
+ gem.author = "Daniel J. Berger"
7
+ gem.email = "djberg96@gmail.com"
8
+ gem.homepage = "http://www.rubyforge.org/projects/shards"
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.summary = "Selectively mixin methods from a given module"
11
+ gem.description = "Selectively mixin methods from a given module"
12
+ gem.rubyforge_project = "shards"
13
+ gem.test_file = "test/test_use.rb"
14
+ gem.has_rdoc = true
15
+ gem.files = Dir['lib/*.rb'] + Dir['[A-Z]*'] + Dir['test/*']
16
+ gem.files.reject! { |fn| fn.include? "CVS" }
17
+ gem.require_path = "lib"
18
+ gem.extra_rdoc_files = ["MANIFEST", "README", "CHANGES"]
19
+ end
20
+
21
+ if $0 == __FILE__
22
+ Gem.manage_gems
23
+ Gem::Builder.new(spec).build
24
+ end
metadata CHANGED
@@ -1,54 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
3
- specification_version: 1
4
2
  name: use
5
3
  version: !ruby/object:Gem::Version
6
- version: 1.2.1
7
- date: 2007-05-22 00:00:00 -06:00
8
- summary: Selectively mixin methods from a given module
9
- require_paths:
10
- - lib
11
- email: djberg96@gmail.com
12
- homepage: http://www.rubyforge.org/projects/shards
13
- rubyforge_project:
14
- description: Selectively mixin methods from a given module
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 1.2.2
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Daniel J. Berger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-09-16 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Selectively mixin methods from a given module
17
+ email: djberg96@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - MANIFEST
24
+ - README
25
+ - CHANGES
31
26
  files:
32
27
  - lib/use.rb
33
28
  - CHANGES
29
+ - examples
30
+ - lib
34
31
  - MANIFEST
35
- - README
36
32
  - Rakefile
37
- - test/tc_use.rb
38
- - test/test_data.rb
39
- test_files:
40
- - test/tc_use.rb
41
- rdoc_options: []
42
-
43
- extra_rdoc_files:
44
- - MANIFEST
45
33
  - README
46
- - CHANGES
47
- executables: []
48
-
49
- extensions: []
34
+ - test
35
+ - use.gemspec
36
+ - test/sample_data.rb
37
+ - test/test_use.rb
38
+ has_rdoc: true
39
+ homepage: http://www.rubyforge.org/projects/shards
40
+ post_install_message:
41
+ rdoc_options: []
50
42
 
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
51
57
  requirements: []
52
58
 
53
- dependencies: []
54
-
59
+ rubyforge_project: shards
60
+ rubygems_version: 1.2.0
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: Selectively mixin methods from a given module
64
+ test_files:
65
+ - test/test_use.rb