overridable 0.3.0
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/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.markdown +147 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/lib/overridable.rb +146 -0
- data/test/modulemixin_test.rb +48 -0
- data/test/overridable_test.rb +164 -0
- data/test/teststrap.rb +7 -0
- metadata +86 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 梁智敏
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# Overridable
|
2
|
+
|
3
|
+
Overridable is a pure ruby library which helps you to make your methods which are defined in classes to be able to be overrided by mixed-in modules.
|
4
|
+
|
5
|
+
## Why?
|
6
|
+
|
7
|
+
We all know that it's impossible for modules to override methods that are defined in classes when they are included. For example:
|
8
|
+
class Thing
|
9
|
+
def foo
|
10
|
+
'Thing.foo'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Redef
|
15
|
+
def foo
|
16
|
+
'Redef.foo'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Thing.send :include, Redef
|
21
|
+
Thing.new.foo #=> Thing.foo # not Redef.foo
|
22
|
+
|
23
|
+
Usually, in order to achieve that goal, we will write the Redef module like this:
|
24
|
+
module Redef
|
25
|
+
def foo_with_redef
|
26
|
+
'Redef.foo'
|
27
|
+
end
|
28
|
+
# you can also do this by: alias_method_chain :foo, :redef, if you use ActiveSupport.
|
29
|
+
alias foo_without_redef foo
|
30
|
+
alias foo foo_with_redef
|
31
|
+
end
|
32
|
+
|
33
|
+
Thing.send :include, Redef
|
34
|
+
Thing.new.foo #=> Redef.foo
|
35
|
+
|
36
|
+
So it will likely become a with/without hell in your code ( you can find dozens of such methods in Rails' code ). And *overridable* is a library that provides a neat mean to resolve this problem.
|
37
|
+
|
38
|
+
## How?
|
39
|
+
|
40
|
+
There are two ways to do this with *overridable*: in class or in module.
|
41
|
+
|
42
|
+
### In class
|
43
|
+
|
44
|
+
Remember Thing and Redef in our first example? Let's make some changes:
|
45
|
+
require 'overridable'
|
46
|
+
|
47
|
+
Thing.class_eval {
|
48
|
+
include Overridable
|
49
|
+
overrides :foo
|
50
|
+
|
51
|
+
include Redef
|
52
|
+
}
|
53
|
+
|
54
|
+
Thing.new.foo #=> Redef.foo
|
55
|
+
That's it! You can specify which methods can be overrided by `overrides` method. One more example based on the previous one:
|
56
|
+
Thing.class_eval {
|
57
|
+
def bar; 'Thing.bar' end
|
58
|
+
def baz; 'Thing.baz' end
|
59
|
+
def id; 'Thing' end
|
60
|
+
|
61
|
+
overrides :bar, :baz
|
62
|
+
}
|
63
|
+
|
64
|
+
Redef.module_eval {
|
65
|
+
def bar; 'Redef.bar' end
|
66
|
+
def baz; 'Redef baz' end
|
67
|
+
def id; 'Redef' end
|
68
|
+
}
|
69
|
+
|
70
|
+
thing = Thing.new
|
71
|
+
thing.bar #=> 'Redef.bar'
|
72
|
+
thing.baz #=> 'Redef.baz'
|
73
|
+
thing.id #=> 'Thing'
|
74
|
+
Of course it's not the end of our story ;) How could I call this *override* if we cannot use `super`? Continue our example:
|
75
|
+
Redef.module_eval {
|
76
|
+
def bar
|
77
|
+
parent = super
|
78
|
+
me = 'Redef.bar'
|
79
|
+
"I'm #{me} and I overrided #{parent}"
|
80
|
+
end
|
81
|
+
}
|
82
|
+
|
83
|
+
Thing.new.bar => I'm Redef.bar and I overrided Thing.bar
|
84
|
+
|
85
|
+
### In module
|
86
|
+
|
87
|
+
If you have many methods in your module and find that it's too annoying to use `overrides`, then you can mix Overridable::ModuleMixin in your module. Example ( we all like examples, don't we? ):
|
88
|
+
class Thing
|
89
|
+
def method_one; ... end
|
90
|
+
def method_two; ... end
|
91
|
+
...
|
92
|
+
def method_n; ... end
|
93
|
+
end
|
94
|
+
|
95
|
+
module Redef
|
96
|
+
include Overridable::ModuleMixin
|
97
|
+
|
98
|
+
def method_one; ... end
|
99
|
+
def method_two; ... end
|
100
|
+
...
|
101
|
+
def method_n; ... end
|
102
|
+
end
|
103
|
+
|
104
|
+
Thing.send :include, Redef #=> method_one, method_two, ..., method_n are all overrided.
|
105
|
+
|
106
|
+
## Install
|
107
|
+
|
108
|
+
gem source -a http://gemcutter.org # you neednot do this if you have already had gemcutter in your source list
|
109
|
+
gem install overridable
|
110
|
+
|
111
|
+
## Dependencies
|
112
|
+
|
113
|
+
* Ruby >= 1.8.7
|
114
|
+
* riot >= 0.10.0 just for test
|
115
|
+
* yard >= 0.4.0 just for generating document
|
116
|
+
|
117
|
+
## Test
|
118
|
+
|
119
|
+
$> cd $GEM_HOME/gems/overridable-x.y.z
|
120
|
+
$> rake test # requires riot
|
121
|
+
|
122
|
+
## TODO
|
123
|
+
|
124
|
+
These features **only** will be added when they are asked for.
|
125
|
+
|
126
|
+
* :all and :except for overrides
|
127
|
+
overrides :all, :except => [:whatever, :excepts]
|
128
|
+
* override with block
|
129
|
+
override :foo do |*args|
|
130
|
+
super # or not
|
131
|
+
# any other stuff
|
132
|
+
end
|
133
|
+
* tell me what's missing.
|
134
|
+
|
135
|
+
## Note on Patches/Pull Requests
|
136
|
+
|
137
|
+
* Fork the project.
|
138
|
+
* Make your feature addition or bug fix.
|
139
|
+
* Add tests for it. This is important so I don't break it in a
|
140
|
+
future version unintentionally.
|
141
|
+
* Commit, do not mess with rakefile, version, or history.
|
142
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
143
|
+
* Send me a pull request. Bonus points for topic branches.
|
144
|
+
|
145
|
+
## Copyright
|
146
|
+
|
147
|
+
Copyright (c) 2009 梁智敏. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#--*-- encoding: UTF-8 --*--
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gem|
|
8
|
+
gem.name = "overridable"
|
9
|
+
gem.summary = %Q{Override methods without method alias.}
|
10
|
+
gem.description = %Q{Overridable is a pure ruby library which helps you to make your methods which are defined in classes to be able to be overrided by mixed-in modules.}
|
11
|
+
gem.email = "liang.gimi@gmail.com"
|
12
|
+
gem.homepage = "http://github.com/Gimi/overridable"
|
13
|
+
gem.authors = ["梁智敏(Gimi Liang)"]
|
14
|
+
gem.add_development_dependency "riot", ">= 0.10.0"
|
15
|
+
gem.add_development_dependency "yard", ">= 0.4.0"
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
Rake::TestTask.new(:test) do |test|
|
25
|
+
test.libs << 'lib' << 'test'
|
26
|
+
test.pattern = 'test/**/*_test.rb'
|
27
|
+
test.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
require 'rcov/rcovtask'
|
32
|
+
Rcov::RcovTask.new do |test|
|
33
|
+
test.libs << 'test'
|
34
|
+
test.pattern = 'test/**/*_test.rb'
|
35
|
+
test.verbose = true
|
36
|
+
end
|
37
|
+
rescue LoadError
|
38
|
+
task :rcov do
|
39
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
task :test => :check_dependencies
|
44
|
+
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
begin
|
48
|
+
require 'yard'
|
49
|
+
YARD::Rake::YardocTask.new
|
50
|
+
rescue LoadError
|
51
|
+
task :yardoc do
|
52
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
53
|
+
end
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/lib/overridable.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
# Including this module in your class will give your class the ability to make its methods to be overridable by included modules. Let's look at some examples for easier understanding.
|
2
|
+
# @example
|
3
|
+
# class Thing
|
4
|
+
# def foo
|
5
|
+
# puts 'Thing.foo'
|
6
|
+
# end
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# module Foo
|
10
|
+
# def foo
|
11
|
+
# puts 'Foo.foo'
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # If you don't use Overridable, you will get:
|
16
|
+
# Thing.send :include, Foo
|
17
|
+
# Thing.new.foo #=> print: Thing.foo\n
|
18
|
+
#
|
19
|
+
# # If you use Overridable *before* you include the module, things will become to be:
|
20
|
+
# Thing.class_eval {
|
21
|
+
# include Overridable
|
22
|
+
# overrides :foo # specifies which methods can be overrided.
|
23
|
+
# include Foo
|
24
|
+
# }
|
25
|
+
# Thing.new.foo => print: Foo.foo\n
|
26
|
+
#
|
27
|
+
# You are not just limited to write a brandnew method, but also call the original method by `super`.
|
28
|
+
# @example
|
29
|
+
# # Let's change the Foo module in the previous example:
|
30
|
+
# module Foo
|
31
|
+
# def foo
|
32
|
+
# super
|
33
|
+
# puts 'Foo.foo'
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# Thing.new.foo #=> print: Thing.foo\nFoo.foo\n
|
38
|
+
#
|
39
|
+
# Thanks to this feature, you don't need method chains any more! ;)
|
40
|
+
#
|
41
|
+
# You can also use Overridable::ModuleMixin to make things even a bit easier for some situations. See Overridable::ModuleMixin for details.
|
42
|
+
module Overridable
|
43
|
+
|
44
|
+
# If your module includes this module, then classes which include your module
|
45
|
+
# will make their methods which also defined in your module overridable.
|
46
|
+
# Let's watch an example:
|
47
|
+
# @example
|
48
|
+
# module YourModule
|
49
|
+
# include Overridable::ModuleMixin
|
50
|
+
#
|
51
|
+
# def foo
|
52
|
+
# super
|
53
|
+
# puts "foo in your module"
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# class YourClass
|
58
|
+
# def foo
|
59
|
+
# puts "foo in your class"
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# YourClass.new.foo #=> print: foo in your class\n
|
64
|
+
#
|
65
|
+
# YourClass.send :include, YourModule
|
66
|
+
#
|
67
|
+
# YourClass.new.foo #=> print: foo in your class\nfoo in your module\n
|
68
|
+
#
|
69
|
+
# __NOTE__: If you need a custom `append_features` method in your module,
|
70
|
+
# define that method before include this module in yours, or this is not
|
71
|
+
# going to work.
|
72
|
+
# @example
|
73
|
+
# module YourModule
|
74
|
+
# def self.append_features mod
|
75
|
+
# # things ...
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# include Overridable::ModuleMixin
|
79
|
+
# end
|
80
|
+
module ModuleMixin
|
81
|
+
def self.append_features mod #:nodoc:
|
82
|
+
class << mod
|
83
|
+
include Overridable
|
84
|
+
overrides :append_features
|
85
|
+
include ClassMethods
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
module ClassMethods
|
90
|
+
def append_features mod #:nodoc:
|
91
|
+
# these must be done in `append_features`, not `included`
|
92
|
+
mod.send :include, Overridable
|
93
|
+
mod.overrides *(
|
94
|
+
public_instance_methods +
|
95
|
+
protected_instance_methods +
|
96
|
+
private_instance_methods
|
97
|
+
)
|
98
|
+
super
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.included mod #:nodoc:
|
104
|
+
mod.extend ClassMethods
|
105
|
+
end
|
106
|
+
|
107
|
+
module ClassMethods #:nodoc:
|
108
|
+
# Specifies which methods can be overrided.
|
109
|
+
# @param [Symbol,String] method_names specifies one or more methods which can be overrided.
|
110
|
+
# @return nil
|
111
|
+
def overrides *method_names
|
112
|
+
return unless self.is_a?(Class) # do nothing if it's a module
|
113
|
+
methods =
|
114
|
+
method_names.map { |m| instance_method m rescue nil } \
|
115
|
+
.compact \
|
116
|
+
.select { |m| m.owner == self }
|
117
|
+
unless methods.empty?
|
118
|
+
# All overrided methods are defined in the same module
|
119
|
+
is_module_defined =
|
120
|
+
if method(:const_defined?).arity > 0 # 1.8.x
|
121
|
+
self.const_defined?(:OverridedMethods)
|
122
|
+
else # 1.9
|
123
|
+
self.const_defined?(:OverridedMethods, false)
|
124
|
+
end
|
125
|
+
|
126
|
+
unless is_module_defined
|
127
|
+
self.const_set(:OverridedMethods, Module.new)
|
128
|
+
include self.const_get(:OverridedMethods)
|
129
|
+
end
|
130
|
+
mod = const_get(:OverridedMethods)
|
131
|
+
|
132
|
+
old_verbose, $VERBOSE = $VERBOSE, nil # supress warnings
|
133
|
+
methods.each { |m|
|
134
|
+
remove_method m.name
|
135
|
+
mod.send :define_method, m.name do |*args, &blk|
|
136
|
+
m.bind(self).call(*args, &blk)
|
137
|
+
end
|
138
|
+
}
|
139
|
+
$VERBOSE = old_verbose
|
140
|
+
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "A module which includes Overridable::ModuleMixin has some methods defined in it." do
|
4
|
+
setup {
|
5
|
+
module SomeModule
|
6
|
+
include Overridable::ModuleMixin
|
7
|
+
|
8
|
+
def foo
|
9
|
+
'SomeModule.foo'
|
10
|
+
end
|
11
|
+
|
12
|
+
def bar a
|
13
|
+
super + 'SomeModule.bar'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
SomeModule
|
18
|
+
}
|
19
|
+
|
20
|
+
context "A class which has the same methods that are defined in that module," do
|
21
|
+
setup {
|
22
|
+
class SomeClass
|
23
|
+
def foo
|
24
|
+
'SomeClass.foo'
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def bar a
|
29
|
+
'SomeClass.bar'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
SomeClass
|
34
|
+
}
|
35
|
+
|
36
|
+
context "includes that module." do
|
37
|
+
setup { topic.send :include, SomeModule; topic }
|
38
|
+
|
39
|
+
asserts("foo should be overrided.") {
|
40
|
+
topic.new.foo
|
41
|
+
}.equals('SomeModule.foo')
|
42
|
+
asserts("bar should be overrided.") {
|
43
|
+
#topic.new.send :bar, :whatever
|
44
|
+
topic.new.bar :whatever
|
45
|
+
}.equals('SomeClass.bar' + 'SomeModule.bar')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
|
3
|
+
context "a classes with some methods defined in it" do
|
4
|
+
setup {
|
5
|
+
class Thing
|
6
|
+
def no_arguments
|
7
|
+
'This is Thing.'
|
8
|
+
end
|
9
|
+
|
10
|
+
def one_argument a
|
11
|
+
a
|
12
|
+
end
|
13
|
+
|
14
|
+
def any_arguments *args
|
15
|
+
args.join('-')
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_block *args, &blk
|
19
|
+
blk.call(*args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def keep_unchanged
|
23
|
+
'unchanged'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Thing
|
28
|
+
}
|
29
|
+
|
30
|
+
context "includes a module which has the sames methods" do
|
31
|
+
setup {
|
32
|
+
module ModuleA
|
33
|
+
def no_arguments
|
34
|
+
'This is ModuleA.'
|
35
|
+
end
|
36
|
+
|
37
|
+
def one_argument a
|
38
|
+
a * 10
|
39
|
+
end
|
40
|
+
|
41
|
+
def any_arguments *args
|
42
|
+
args.join('_')
|
43
|
+
end
|
44
|
+
|
45
|
+
def with_block *args, &blk
|
46
|
+
blk.call(*args.map! { |a| a * 10 })
|
47
|
+
end
|
48
|
+
|
49
|
+
def keep_unchanged
|
50
|
+
'changed'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
topic.send :include, ModuleA
|
55
|
+
topic
|
56
|
+
}
|
57
|
+
|
58
|
+
# If these tests fail, that means we don't need this library any more ;)
|
59
|
+
asserts("no_arguments should not be overrided") { topic.new.no_arguments } \
|
60
|
+
.equals('This is Thing.')
|
61
|
+
asserts("one_argument should not be overrided") { topic.new.one_argument(10) } \
|
62
|
+
.equals(10)
|
63
|
+
asserts("any_arguments should not be overrided") { topic.new.any_arguments('a', 'b', 'c') } \
|
64
|
+
.equals(%w[a b c].join('-'))
|
65
|
+
asserts("with_block should not be overrided") { topic.new.with_block('a', 'b', 'c') { |*args| args.join('-') } } \
|
66
|
+
.equals(%w[a b c].join('-'))
|
67
|
+
asserts("keep_unchanged should not be overrided") { topic.new.keep_unchanged } \
|
68
|
+
.equals('unchanged')
|
69
|
+
end
|
70
|
+
|
71
|
+
context "includes Overridable and specifies methods to be overrided," do
|
72
|
+
setup {
|
73
|
+
topic.class_eval {
|
74
|
+
include Overridable
|
75
|
+
overrides :no_arguments, :one_argument, :any_arguments, :with_block
|
76
|
+
}
|
77
|
+
|
78
|
+
topic
|
79
|
+
}
|
80
|
+
|
81
|
+
context "then includes a module which has the same methods" do
|
82
|
+
setup {
|
83
|
+
module ModuleB
|
84
|
+
def no_arguments
|
85
|
+
'This is ModuleB.'
|
86
|
+
end
|
87
|
+
|
88
|
+
def one_argument a
|
89
|
+
a * 10
|
90
|
+
end
|
91
|
+
|
92
|
+
def any_arguments *args
|
93
|
+
args.join('_')
|
94
|
+
end
|
95
|
+
|
96
|
+
def with_block *args, &blk
|
97
|
+
blk.call(*args.map! { |a| a * 10 })
|
98
|
+
end
|
99
|
+
|
100
|
+
def keep_unchanged
|
101
|
+
'changed'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
topic.send :include, ModuleB
|
106
|
+
topic
|
107
|
+
}
|
108
|
+
|
109
|
+
asserts("no_arguments have been overrided") { topic.new.no_arguments } \
|
110
|
+
.equals('This is ModuleB.')
|
111
|
+
asserts("one_argument have been overrided") { topic.new.one_argument(10) } \
|
112
|
+
.equals(10 * 10)
|
113
|
+
asserts("any_arguments have been overrided") { topic.new.any_arguments('a', 'b', 'c') } \
|
114
|
+
.equals(%w[a b c].join('_'))
|
115
|
+
asserts("with_block have been overrided") { topic.new.with_block('a', 'b', 'c') { |*args| args.join('-') } } \
|
116
|
+
.equals(%w[a b c].map! { |e| e * 10 }.join('-'))
|
117
|
+
asserts("keep_unchanged should not be overrided") { topic.new.keep_unchanged } \
|
118
|
+
.equals('unchanged')
|
119
|
+
end
|
120
|
+
|
121
|
+
context "then includes a module with the same methods which call super in their bodies." do
|
122
|
+
setup {
|
123
|
+
module ModuleC
|
124
|
+
def no_arguments
|
125
|
+
super +
|
126
|
+
'This is ModuleC.'
|
127
|
+
end
|
128
|
+
|
129
|
+
def one_argument a
|
130
|
+
super + 123
|
131
|
+
end
|
132
|
+
|
133
|
+
def any_arguments *args
|
134
|
+
[super, args.join('_')].join('@')
|
135
|
+
end
|
136
|
+
|
137
|
+
def with_block *args, &blk
|
138
|
+
super(*args.map! { |e| "|#{e}|" }, &blk)
|
139
|
+
end
|
140
|
+
|
141
|
+
def keep_unchanged
|
142
|
+
super
|
143
|
+
'changed'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
topic.send :include, ModuleC
|
148
|
+
topic
|
149
|
+
}
|
150
|
+
|
151
|
+
asserts("no_arguments have been overrided and work properly.") { topic.new.no_arguments } \
|
152
|
+
.equals('This is Thing.' + 'This is ModuleC.')
|
153
|
+
asserts("one_argument have been overrided and work properly.") { topic.new.one_argument(10) } \
|
154
|
+
.equals(10 + 123)
|
155
|
+
asserts("any_arguments have been overrided and work properly.") { topic.new.any_arguments('a', 'b', 'c') } \
|
156
|
+
.equals([%w[a b c].join('-'), %w[a b c].join('_')].join('@'))
|
157
|
+
asserts("with_block have been overrided and work properly.") { topic.new.with_block('a', 'b', 'c') { |*args| args.join('-') } } \
|
158
|
+
.equals(%w[a b c].map! { |e| "|#{e}|" }.join('-'))
|
159
|
+
asserts("keep_unchanged should not be overrided") { topic.new.keep_unchanged } \
|
160
|
+
.equals('unchanged')
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
data/test/teststrap.rb
ADDED
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: overridable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "\xE6\xA2\x81\xE6\x99\xBA\xE6\x95\x8F(Gimi Liang)"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-24 00:00:00 +08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: riot
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.10.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yard
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.0
|
34
|
+
version:
|
35
|
+
description: Overridable is a pure ruby library which helps you to make your methods which are defined in classes to be able to be overrided by mixed-in modules.
|
36
|
+
email: liang.gimi@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.markdown
|
44
|
+
files:
|
45
|
+
- .document
|
46
|
+
- .gitignore
|
47
|
+
- LICENSE
|
48
|
+
- README.markdown
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- lib/overridable.rb
|
52
|
+
- test/modulemixin_test.rb
|
53
|
+
- test/overridable_test.rb
|
54
|
+
- test/teststrap.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/Gimi/overridable
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --charset=UTF-8
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.3.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Override methods without method alias.
|
83
|
+
test_files:
|
84
|
+
- test/overridable_test.rb
|
85
|
+
- test/modulemixin_test.rb
|
86
|
+
- test/teststrap.rb
|