use 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +8 -0
- data/README +20 -12
- data/examples/example_use.rb +56 -0
- data/lib/use.rb +177 -159
- data/test/sample_data.rb +66 -64
- data/test/test_use.rb +102 -96
- metadata +22 -15
- data/Rakefile +0 -23
- data/use.gemspec +0 -24
data/CHANGES
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 1.3.0 - 30-Jul-2009
|
2
|
+
* Compatibility fixes for Ruby 1.9.x
|
3
|
+
* Added structured_warnings as a dependency, and now emits a
|
4
|
+
MethodRedefinedWarning in $VERBOSE mode if a method is redefined.
|
5
|
+
* Changed license to Artistic 2.0.
|
6
|
+
* Fixed a bug with regards to aliased methods (which you probably
|
7
|
+
never noticed).
|
8
|
+
|
1
9
|
== 1.2.2 - 16-Sep-2008
|
2
10
|
* Fixed a bug where methods already defined prior to the inclusion
|
3
11
|
of a module could be accidentally undefined.
|
data/README
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
== Description
|
2
|
-
The 'use'
|
3
|
-
module.
|
2
|
+
The 'use' library allows you to selectively mixin methods from a given
|
3
|
+
module and alias them on the fly if desired.
|
4
4
|
|
5
5
|
== Prerequisites
|
6
6
|
Ruby 1.8.0 or later
|
7
|
-
|
7
|
+
structured_warnings 0.1.1 or later
|
8
|
+
|
8
9
|
== Installation
|
9
10
|
=== Standard
|
10
11
|
rake test (optional)
|
11
12
|
rake install
|
12
|
-
|
13
|
+
|
13
14
|
=== Gem install
|
14
15
|
rake test (optional)
|
15
16
|
rake install_gem
|
@@ -46,7 +47,7 @@
|
|
46
47
|
|
47
48
|
# Using the new keywords
|
48
49
|
class MyKlass
|
49
|
-
use Foo :alias => {:bar
|
50
|
+
use Foo :alias => {:bar => :test}
|
50
51
|
end
|
51
52
|
|
52
53
|
m = MyKlass.new
|
@@ -55,7 +56,12 @@
|
|
55
56
|
|
56
57
|
== Constants
|
57
58
|
USE_VERSION
|
58
|
-
|
59
|
+
The version of this library. This is a string.
|
60
|
+
|
61
|
+
== Notes
|
62
|
+
In $VERBOSE mode this library will issue a MethodRedefinedWarning if you
|
63
|
+
shadow an existing method. See the documentation for structured_warnings
|
64
|
+
for more details.
|
59
65
|
|
60
66
|
== Acknowledgements
|
61
67
|
Thanks go to Ara Howard for providing the original solution and to
|
@@ -63,8 +69,11 @@ USE_VERSION
|
|
63
69
|
in order to implement fine-grained mixins.
|
64
70
|
|
65
71
|
== Known Bugs
|
66
|
-
|
67
|
-
|
72
|
+
Some versions of Ruby 1.9.x may emit a warning in verbose mode. This is a
|
73
|
+
bug in Ruby 1.9.x and can be ignored.
|
74
|
+
|
75
|
+
If you find any bugs please log them on the project page at
|
76
|
+
http://www.rubyforge.org/projects/shards.
|
68
77
|
|
69
78
|
== Questions?
|
70
79
|
Please post your comment or question on one of the forums on the project
|
@@ -72,13 +81,12 @@ USE_VERSION
|
|
72
81
|
link.
|
73
82
|
|
74
83
|
== License
|
75
|
-
|
84
|
+
Artistic 2.0
|
76
85
|
|
77
86
|
== Copyright
|
78
|
-
(C) 2005-
|
87
|
+
(C) 2005-2009, Daniel J. Berger
|
79
88
|
All Rights Reserved
|
80
89
|
|
81
90
|
== Author
|
82
91
|
Daniel J. Berger
|
83
|
-
djberg96 at gmail dot com
|
84
|
-
IRC nickname: imperator/mok (freenode)
|
92
|
+
djberg96 at nospam at gmail dot com
|
@@ -0,0 +1,56 @@
|
|
1
|
+
Dir.chdir("..") if File.basename(Dir.pwd) == "examples"
|
2
|
+
$LOAD_PATH.unshift(Dir.pwd + "/lib")
|
3
|
+
|
4
|
+
require "use"
|
5
|
+
|
6
|
+
module Mod_A
|
7
|
+
def meth_a
|
8
|
+
"hello"
|
9
|
+
end
|
10
|
+
def meth_b
|
11
|
+
"world"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Mod_B
|
16
|
+
def meth_a
|
17
|
+
"goodbye"
|
18
|
+
end
|
19
|
+
def meth_b
|
20
|
+
"new york"
|
21
|
+
end
|
22
|
+
def meth_c
|
23
|
+
"adios"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Various ways to mixin methods using 'use'. Note that I am intentionally
|
28
|
+
# putting multiple 'use' statements within the classes for the sake of brevity
|
29
|
+
# and demonstration. In practice, you would not use more than one per module.
|
30
|
+
#
|
31
|
+
class Foo
|
32
|
+
use Mod_A # include all methods from Mod_A
|
33
|
+
use Mod_A, :meth_a # or, include only meth_a from Mod_A
|
34
|
+
use Mod_A, include => :meth_a # same as above
|
35
|
+
end
|
36
|
+
|
37
|
+
class Bar
|
38
|
+
use Mod_B, :include => [:meth_b, :meth_c] # include only meth_a and meth_b
|
39
|
+
use Mod_B, :exclude => :meth_c # same net result as above
|
40
|
+
end
|
41
|
+
|
42
|
+
class Baz
|
43
|
+
use Mod_A, :meth_a # mixin meth_a from Mod_A
|
44
|
+
use Mod_B, :alias => {:meth_a, :meth_z} # mixin meth_a from Mod_B, but as meth_z
|
45
|
+
end
|
46
|
+
|
47
|
+
# Alias every method from Mod_B, as well as mixin Mod_A's meth_b.
|
48
|
+
class Zap
|
49
|
+
use Mod_B, :alias => {
|
50
|
+
:meth_a => :meth_x,
|
51
|
+
:meth_b => :meth_y,
|
52
|
+
:meth_c => :meth_z
|
53
|
+
}
|
54
|
+
|
55
|
+
use Mod_A, :meth_b
|
56
|
+
end
|
data/lib/use.rb
CHANGED
@@ -1,159 +1,177 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
#
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
end
|
1
|
+
require 'structured_warnings'
|
2
|
+
|
3
|
+
unless defined? MethodRedefinedWarning
|
4
|
+
# Warning raised in $VERBOSE mode if a method is shadowed.
|
5
|
+
class MethodRedefinedWarning < Warning
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Class
|
10
|
+
# The version of the 'use' library
|
11
|
+
USE_VERSION = '1.3.0'
|
12
|
+
|
13
|
+
# Allows you to include mixins in a fine grained manner. Instead of
|
14
|
+
# including all methods from a given module, you can can instead mixin
|
15
|
+
# only those methods you want through a combination of the :include,
|
16
|
+
# :exclude, and :alias options.
|
17
|
+
#
|
18
|
+
# Examples:
|
19
|
+
#
|
20
|
+
# # Defines a 'bar' and 'baz' method
|
21
|
+
# module Foo
|
22
|
+
# def bar
|
23
|
+
# "hello"
|
24
|
+
# end
|
25
|
+
# def baz
|
26
|
+
# "world"
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # Defines a 'bar', 'blah', and 'zap' methods
|
31
|
+
# module Test
|
32
|
+
# def bar
|
33
|
+
# "goodbye"
|
34
|
+
# end
|
35
|
+
# def blah
|
36
|
+
# "new york"
|
37
|
+
# end
|
38
|
+
# def zap
|
39
|
+
# "zap"
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# # From the Foo module, only mixin the 'bar' method. From the Test
|
44
|
+
# # module exclude the 'bar' and 'zap' methods.
|
45
|
+
# class Zap
|
46
|
+
# use Foo, :bar
|
47
|
+
# use Test, :exclude => [:bar, :zap]
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# z = Zap.new
|
51
|
+
#
|
52
|
+
# z.bar # => "hello"
|
53
|
+
# z.baz # => NoMethodError - wasn't mixed in
|
54
|
+
# z.zap # => NoMethodError - wasn't mixed in
|
55
|
+
# z.blah # =>"new york"
|
56
|
+
#
|
57
|
+
# # Alias a method on the fly
|
58
|
+
# class MyKlass
|
59
|
+
# use Foo :alias => {:bar, :test}
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# m = MyKlass.new
|
63
|
+
# m.test # => "hello"
|
64
|
+
# m.bar # => NoMethodError - was aliased to 'test'
|
65
|
+
#
|
66
|
+
# If no options follow the module name this method is identical
|
67
|
+
# to a standard include.
|
68
|
+
#--
|
69
|
+
# Designer's note: Most of the explicit .to_s calls on method lists are
|
70
|
+
# here to deal with the fact that Ruby 1.8 returns strings for method
|
71
|
+
# lists while Ruby 1.9 returns symbols. To ensure compatibility, and
|
72
|
+
# preserve my sanity, all method names are converted to strings.
|
73
|
+
#
|
74
|
+
def use(*args)
|
75
|
+
valid_keys = %w/include exclude alias/
|
76
|
+
excluded_methods = []
|
77
|
+
included_methods = []
|
78
|
+
aliased_methods = []
|
79
|
+
|
80
|
+
mod = args.shift.clone
|
81
|
+
|
82
|
+
# If no arguments follow the module name, treat it as a standard include
|
83
|
+
if args.empty?
|
84
|
+
included_methods.concat(mod.instance_methods)
|
85
|
+
end
|
86
|
+
|
87
|
+
m = Module.new
|
88
|
+
|
89
|
+
args.each{ |arg|
|
90
|
+
if arg.kind_of?(Hash)
|
91
|
+
arg.each{ |key, val|
|
92
|
+
case key.to_s
|
93
|
+
when 'include'
|
94
|
+
if val.respond_to?(:each)
|
95
|
+
val.each{ |element| included_methods << element.to_s }
|
96
|
+
else
|
97
|
+
included_methods << val.to_s
|
98
|
+
end
|
99
|
+
when 'exclude'
|
100
|
+
if val.respond_to?(:each)
|
101
|
+
val.each{ |element| excluded_methods << element.to_s }
|
102
|
+
else
|
103
|
+
excluded_methods << val.to_s
|
104
|
+
end
|
105
|
+
when 'alias'
|
106
|
+
aliased_methods.push(val)
|
107
|
+
else
|
108
|
+
raise "invalid key '#{key}'"
|
109
|
+
end
|
110
|
+
}
|
111
|
+
else
|
112
|
+
included_methods.push(arg.to_s)
|
113
|
+
end
|
114
|
+
}
|
115
|
+
|
116
|
+
unless included_methods.empty? || excluded_methods.empty?
|
117
|
+
err = 'you cannot include and exclude in the same statement'
|
118
|
+
raise ArgumentError, err
|
119
|
+
end
|
120
|
+
|
121
|
+
local_instance_methods = mod.instance_methods.map{ |e| e.to_s }
|
122
|
+
|
123
|
+
excluded_methods.map!{ |e| e.to_s }
|
124
|
+
|
125
|
+
# Remove excluded_methods methods
|
126
|
+
unless excluded_methods.empty?
|
127
|
+
(local_instance_methods & excluded_methods).each{ |meth|
|
128
|
+
mod.module_eval{ remove_method(meth) }
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
# Alias methods. All aliased methods are automatically included.
|
133
|
+
aliased_methods.each{ |pair|
|
134
|
+
pair.each{ |old_method, new_method|
|
135
|
+
included_methods << new_method
|
136
|
+
mod.module_eval{
|
137
|
+
alias_method(new_method, old_method)
|
138
|
+
remove_method(old_method) rescue nil
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
included_methods.map!{ |e| e.to_s }
|
144
|
+
|
145
|
+
# Remove all methods not specifically included. The rescue was needed
|
146
|
+
# for those cases where a module included another module. Also, don't
|
147
|
+
# remove methods from classes that already exist unless specifically
|
148
|
+
# included.
|
149
|
+
unless included_methods.empty?
|
150
|
+
(local_instance_methods - included_methods).each{ |meth|
|
151
|
+
if superclass.instance_methods.include?(meth)
|
152
|
+
if included_methods.include?(meth)
|
153
|
+
mod.module_eval{ undef_method(meth) rescue nil }
|
154
|
+
else
|
155
|
+
mod.module_eval{ remove_method(meth) rescue nil }
|
156
|
+
end
|
157
|
+
else
|
158
|
+
mod.module_eval{ undef_method(meth) rescue nil }
|
159
|
+
end
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
m.module_eval{ include mod }
|
164
|
+
|
165
|
+
# Raise a warning if methods are shadowed (in $VERBOSE mode)
|
166
|
+
if $VERBOSE
|
167
|
+
local_instance_methods = instance_methods(true)
|
168
|
+
m.instance_methods.each{ |meth|
|
169
|
+
next unless local_instance_methods.include?(meth)
|
170
|
+
msg = "method '#{meth}' aliased, shadows old '#{meth}'"
|
171
|
+
warn MethodRedefinedWarning, msg
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
include m
|
176
|
+
end
|
177
|
+
end
|
data/test/sample_data.rb
CHANGED
@@ -1,64 +1,66 @@
|
|
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
|
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,
|
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,
|
64
|
+
:alias => {:meth_a => :meth_x, :meth_c => :meth_z},
|
65
|
+
:exclude => :meth_b
|
66
|
+
end
|
data/test/test_use.rb
CHANGED
@@ -1,96 +1,102 @@
|
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
def
|
91
|
-
@
|
92
|
-
@
|
93
|
-
@
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
+
# Convert symbols to strings for 1.9.x
|
21
|
+
def assert_methods(array, methods)
|
22
|
+
methods = methods.map{ |m| m.to_s }
|
23
|
+
assert_equal(array, methods)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_version
|
27
|
+
assert_equal('1.3.0', Class::USE_VERSION)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_mod_a_methods
|
31
|
+
assert_methods(['meth_a', 'meth_b', 'meth_c'], ModA.instance_methods.sort)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_mod_b_methods
|
35
|
+
assert_methods(['meth_a', 'meth_b', 'meth_c'], ModB.instance_methods.sort)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_mod_c_methods
|
39
|
+
assert_methods(['meth_x', 'meth_y', 'meth_z'], ModC.instance_methods.sort)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_class_a_methods
|
43
|
+
assert_respond_to(@a, :meth_a)
|
44
|
+
assert_equal('ModA#meth_a', @a.meth_a)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_class_a_expected_errors
|
48
|
+
assert_raise(NoMethodError){ @a.meth_b }
|
49
|
+
assert_raise(NoMethodError){ @a.meth_c }
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_class_b_methods
|
53
|
+
assert_respond_to(@b, :meth_c)
|
54
|
+
assert_respond_to(@b, :meth_z)
|
55
|
+
assert_equal('ModA#meth_c', @b.meth_c)
|
56
|
+
assert_equal('ModB#meth_b', @b.meth_z)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_class_b_expected_errors
|
60
|
+
assert_raise(NoMethodError){ @b.meth_a }
|
61
|
+
assert_raise(NoMethodError){ @b.meth_b }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_class_c_methods
|
65
|
+
assert_respond_to(@c, :meth_a)
|
66
|
+
assert_respond_to(@c, :meth_c)
|
67
|
+
assert_respond_to(@c, :meth_x)
|
68
|
+
assert_respond_to(@c, :meth_y)
|
69
|
+
assert_respond_to(@c, :meth_z)
|
70
|
+
|
71
|
+
assert_equal('ModA#meth_a', @c.meth_a)
|
72
|
+
assert_equal('ClassC#meth_c', @c.meth_c)
|
73
|
+
assert_equal('ModC#meth_x', @c.meth_x)
|
74
|
+
assert_equal('ModC#meth_y', @c.meth_y)
|
75
|
+
assert_equal('ModC#meth_z', @c.meth_z)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_class_c_expected_errors
|
79
|
+
assert_raise(NoMethodError){ @c.meth_b }
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_class_d_methods
|
83
|
+
assert_respond_to(@d, :meth_x)
|
84
|
+
assert_respond_to(@d, :meth_z)
|
85
|
+
|
86
|
+
assert_equal('ModA#meth_a', @d.meth_x)
|
87
|
+
assert_equal('ModA#meth_c', @d.meth_z)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_class_d_expected_errors
|
91
|
+
assert_raise(NoMethodError){ @d.meth_a }
|
92
|
+
assert_raise(NoMethodError){ @d.meth_b }
|
93
|
+
assert_raise(NoMethodError){ @d.meth_c }
|
94
|
+
end
|
95
|
+
|
96
|
+
def teardown
|
97
|
+
@a = nil
|
98
|
+
@b = nil
|
99
|
+
@c = nil
|
100
|
+
@d = nil
|
101
|
+
end
|
102
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: use
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -9,11 +9,20 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-07-30 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: structured_warnings
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.1.1
|
24
|
+
version:
|
25
|
+
description: " The use library solves the multi-mixin problem by allowing you to\n selectively mixin specific methods from a module rather than mixing\n in all of them. In addition, you can alias methods on the fly as they\n are mixed in, effectively allowing you to change the name of the mixin\n method.\n"
|
17
26
|
email: djberg96@gmail.com
|
18
27
|
executables: []
|
19
28
|
|
@@ -24,19 +33,17 @@ extra_rdoc_files:
|
|
24
33
|
- README
|
25
34
|
- CHANGES
|
26
35
|
files:
|
36
|
+
- examples/example_use.rb
|
27
37
|
- lib/use.rb
|
28
|
-
- CHANGES
|
29
|
-
- examples
|
30
|
-
- lib
|
31
|
-
- MANIFEST
|
32
|
-
- Rakefile
|
33
|
-
- README
|
34
|
-
- test
|
35
|
-
- use.gemspec
|
36
38
|
- test/sample_data.rb
|
37
39
|
- test/test_use.rb
|
40
|
+
- MANIFEST
|
41
|
+
- README
|
42
|
+
- CHANGES
|
38
43
|
has_rdoc: true
|
39
44
|
homepage: http://www.rubyforge.org/projects/shards
|
45
|
+
licenses:
|
46
|
+
- Artistic 2.0
|
40
47
|
post_install_message:
|
41
48
|
rdoc_options: []
|
42
49
|
|
@@ -57,9 +64,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
64
|
requirements: []
|
58
65
|
|
59
66
|
rubyforge_project: shards
|
60
|
-
rubygems_version: 1.
|
67
|
+
rubygems_version: 1.3.5
|
61
68
|
signing_key:
|
62
|
-
specification_version:
|
69
|
+
specification_version: 3
|
63
70
|
summary: Selectively mixin methods from a given module
|
64
71
|
test_files:
|
65
72
|
- test/test_use.rb
|
data/Rakefile
DELETED
@@ -1,23 +0,0 @@
|
|
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/use.gemspec
DELETED
@@ -1,24 +0,0 @@
|
|
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
|