overrides 0.1.0 → 0.10.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/.travis.yml +6 -0
- data/README.md +83 -0
- data/Rakefile +7 -0
- data/lib/overrides.rb +32 -11
- data/lib/overrides/for_all.rb +2 -0
- data/lib/overrides/version.rb +1 -1
- data/overrides.gemspec +4 -1
- data/test/overrides_test.rb +178 -0
- metadata +29 -6
data/.travis.yml
ADDED
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Overrides
|
2
|
+
|
3
|
+
An #overrides annotation for your (Ruby) methods.
|
4
|
+
|
5
|
+
Inspired by Java's [@Override][1].
|
6
|
+
|
7
|
+
|
8
|
+
## Install
|
9
|
+
|
10
|
+
$ gem install overrides
|
11
|
+
|
12
|
+
or add this line to your application's *Gemfile* (and `bundle`) :
|
13
|
+
|
14
|
+
gem 'overrides'
|
15
|
+
|
16
|
+
optionally add `:require => 'overrides/for_all'` to have `overrides` available
|
17
|
+
in all classes/modules as a built-in (singleton) method.
|
18
|
+
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
Let's have a base class with `Overrides` pulled in :
|
23
|
+
|
24
|
+
class Message
|
25
|
+
extend Overrides
|
26
|
+
|
27
|
+
def self.deliver(msg); end
|
28
|
+
|
29
|
+
def do_send; end
|
30
|
+
def sent_at; end
|
31
|
+
def reply?; end
|
32
|
+
end
|
33
|
+
|
34
|
+
a notice would be a message sub-type, note how `overrides` gets used :
|
35
|
+
|
36
|
+
class Notice < Message
|
37
|
+
overrides
|
38
|
+
def do_send; super; end
|
39
|
+
|
40
|
+
def reply?; nil; end
|
41
|
+
def sent_at; nil; end
|
42
|
+
|
43
|
+
overrides :reply?, :sent_at
|
44
|
+
end
|
45
|
+
|
46
|
+
without args (before method) works with singleton methods as well :
|
47
|
+
|
48
|
+
class Notice < Message
|
49
|
+
overrides
|
50
|
+
def self.deliver(msg); end
|
51
|
+
end
|
52
|
+
|
53
|
+
**NOTE:** there's no global name-space pollution by default, thus you'll need
|
54
|
+
to hook up the `Overrides` module (or extend `Object` to pull it in for all).
|
55
|
+
|
56
|
+
### "Java"
|
57
|
+
|
58
|
+
Here's how you use it with JRuby to "annotate" method overrides :
|
59
|
+
|
60
|
+
require 'overrides/for_all'
|
61
|
+
|
62
|
+
class NonEmptyList < java.util.ArrayList
|
63
|
+
|
64
|
+
def initialize
|
65
|
+
super(); add nil
|
66
|
+
end
|
67
|
+
|
68
|
+
overrides
|
69
|
+
def clear; super; add nil; end
|
70
|
+
|
71
|
+
def isEmpty; false; end
|
72
|
+
overrides :isEmpty
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
## Copyright
|
78
|
+
|
79
|
+
Copyright (c) 2013 [Karol Bucek](http://kares.org).
|
80
|
+
See LICENSE.txt (http://en.wikipedia.org/wiki/MIT_License) for details.
|
81
|
+
|
82
|
+
[0]: https://github.com/kares/overrides
|
83
|
+
[1]: http://docs.oracle.com/javase/7/docs/api/java/lang/Override.html
|
data/Rakefile
CHANGED
data/lib/overrides.rb
CHANGED
@@ -2,10 +2,11 @@ require 'overrides/version'
|
|
2
2
|
|
3
3
|
# Allows for an #overrides annotation for your methods.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
# expected to
|
5
|
+
# This might help during refactoring (method renaming) to assure methods
|
6
|
+
# expected to be overriding another (and calling super) fail early during
|
7
|
+
# definition time instead of when called.
|
7
8
|
#
|
8
|
-
#
|
9
|
+
# Usage :
|
9
10
|
#
|
10
11
|
# class Message
|
11
12
|
# extend Overrides
|
@@ -26,7 +27,7 @@ require 'overrides/version'
|
|
26
27
|
# end
|
27
28
|
#
|
28
29
|
#
|
29
|
-
# Without arguments works with singleton methods as well :
|
30
|
+
# Without arguments (before method) works with singleton methods as well :
|
30
31
|
#
|
31
32
|
# class Message
|
32
33
|
# extend Overrides
|
@@ -47,13 +48,19 @@ require 'overrides/version'
|
|
47
48
|
#
|
48
49
|
module Overrides
|
49
50
|
|
50
|
-
|
51
|
+
# Custom (missing method error) raised from {#overrides}.
|
52
|
+
class Error < NoMethodError; end
|
51
53
|
|
52
54
|
def overrides(*names)
|
53
|
-
if names.empty? # next method
|
55
|
+
if names.empty? # next method def - singleton or instance
|
54
56
|
@_override = true
|
55
57
|
else
|
56
|
-
names.each do |name|
|
58
|
+
names.each do |name| # only for instance methods
|
59
|
+
unless Overrides.includes_method? self.instance_methods(false), name
|
60
|
+
msg = "(instance) method #{name.inspect} not found in "
|
61
|
+
raise NoMethodError,
|
62
|
+
msg << ( self.is_a?(Class) ? 'class ' : 'module ' ) << self.inspect
|
63
|
+
end
|
57
64
|
unless Overrides.overriden?(self, name)
|
58
65
|
raise Error, "previous (instance) method #{name.inspect} not found"
|
59
66
|
end
|
@@ -61,6 +68,7 @@ module Overrides
|
|
61
68
|
end
|
62
69
|
end
|
63
70
|
|
71
|
+
# @private
|
64
72
|
def method_added(name)
|
65
73
|
return super unless (@_override ||= nil); @_override = false
|
66
74
|
unless Overrides.overriden?(self, name, true)
|
@@ -69,6 +77,7 @@ module Overrides
|
|
69
77
|
super
|
70
78
|
end
|
71
79
|
|
80
|
+
# @private
|
72
81
|
def singleton_method_added(name)
|
73
82
|
return super unless (@_override ||= nil); @_override = false
|
74
83
|
unless Overrides.overriden?(self, name, false)
|
@@ -77,20 +86,32 @@ module Overrides
|
|
77
86
|
super
|
78
87
|
end
|
79
88
|
|
89
|
+
# Checks if a method was previously available in the given module's method
|
90
|
+
# resolution chain. Assumes instance methods by default.
|
80
91
|
def self.overriden?(klass, method, instance = true)
|
81
92
|
if instance
|
82
93
|
klass.included_modules.each do |mod|
|
83
|
-
return true if mod.instance_methods(true)
|
94
|
+
return true if includes_method? mod.instance_methods(true), method
|
84
95
|
end
|
85
96
|
return false unless klass.is_a?(Class) # "only" a Module ...
|
86
|
-
return klass.superclass.instance_methods(true)
|
97
|
+
return includes_method? klass.superclass.instance_methods(true), method
|
87
98
|
else
|
88
99
|
(class << klass; self; end).included_modules.each do |mod|
|
89
|
-
return true if mod.instance_methods(true)
|
100
|
+
return true if includes_method? mod.instance_methods(true), method
|
90
101
|
end
|
91
102
|
return false unless klass.is_a?(Class) # "only" a Module ...
|
92
|
-
return klass.superclass.methods(true)
|
103
|
+
return includes_method? klass.superclass.methods(true), method
|
93
104
|
end
|
94
105
|
end
|
95
106
|
|
107
|
+
# @private
|
108
|
+
def self.includes_method?(methods, name)
|
109
|
+
methods.include? name
|
110
|
+
end
|
111
|
+
|
112
|
+
# @private
|
113
|
+
def self.includes_method?(methods, name)
|
114
|
+
methods.include? name.to_s
|
115
|
+
end if RUBY_VERSION < '1.9'
|
116
|
+
|
96
117
|
end
|
data/lib/overrides/version.rb
CHANGED
data/overrides.gemspec
CHANGED
@@ -9,7 +9,9 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.authors = ["Karol Bucek"]
|
10
10
|
gem.email = ["self@kares.org"]
|
11
11
|
gem.summary = %q{an #overrides annotation for your methods}
|
12
|
-
gem.description = %q{
|
12
|
+
gem.description = %q{Helps during refactoring (method renaming) to assure
|
13
|
+
methods expected to be overriding another (and calling super) fail early during
|
14
|
+
definition time instead of when called.}
|
13
15
|
gem.homepage = "http://github.com/kares/overrides"
|
14
16
|
gem.license = "MIT"
|
15
17
|
|
@@ -18,6 +20,7 @@ Gem::Specification.new do |gem|
|
|
18
20
|
gem.test_files = gem.files.grep(%r{^(test)/})
|
19
21
|
gem.require_paths = ["lib"]
|
20
22
|
|
23
|
+
gem.add_development_dependency "minitest", "~> 3.0"
|
21
24
|
gem.add_development_dependency "bundler", "~> 1.3"
|
22
25
|
gem.add_development_dependency "rake", "~> 10.1"
|
23
26
|
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'bundler/setup' # if RUBY_VERSION < '1.9'
|
2
|
+
|
3
|
+
require 'overrides'
|
4
|
+
|
5
|
+
require 'minitest/autorun'
|
6
|
+
|
7
|
+
class OverridesTest < MiniTest::Unit::TestCase; end
|
8
|
+
|
9
|
+
# ========================================
|
10
|
+
|
11
|
+
class Ferko
|
12
|
+
|
13
|
+
extend Overrides
|
14
|
+
|
15
|
+
def kuk; 'ferko-kuk'; end
|
16
|
+
def muk; 'ferko-muk'; end
|
17
|
+
|
18
|
+
overrides
|
19
|
+
def to_s
|
20
|
+
'ferko' + super.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.hoja; 'hoja-ferko'; end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
OverridesTest.class_eval do
|
28
|
+
|
29
|
+
def test_overrides_builtin_method
|
30
|
+
assert Ferko.new.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_methods_stay_the_same
|
34
|
+
assert_equal 'ferko-kuk', Ferko.new.kuk
|
35
|
+
assert_equal 'hoja-ferko', Ferko.hoja
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
# ========================================
|
41
|
+
|
42
|
+
class Jozko < Ferko
|
43
|
+
|
44
|
+
overrides
|
45
|
+
def kuk; super; 'jozko-kuk'; end
|
46
|
+
|
47
|
+
def muk; 'jozko-muk'; end
|
48
|
+
def tuk; 'jozko-tuk'; end
|
49
|
+
|
50
|
+
overrides :muk
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
OverridesTest.class_eval do
|
55
|
+
|
56
|
+
def test_overrides_inherited_methods
|
57
|
+
assert_equal 'jozko-kuk', Jozko.new.kuk
|
58
|
+
assert_equal 'jozko-muk', Jozko.new.muk
|
59
|
+
assert_equal 'jozko-tuk', Jozko.new.tuk
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
# ========================================
|
65
|
+
|
66
|
+
class Jozko
|
67
|
+
|
68
|
+
overrides
|
69
|
+
def self.hoja; super; 'hoja-jozko'; end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
OverridesTest.class_eval do
|
74
|
+
|
75
|
+
def test_overrides_singleton_method
|
76
|
+
assert_equal 'hoja-jozko', Jozko.hoja
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
# ========================================
|
82
|
+
|
83
|
+
class Janko < Ferko
|
84
|
+
|
85
|
+
def kuk; super; 'janko-kuk'; end
|
86
|
+
def muk; super; 'janko-muk'; end
|
87
|
+
|
88
|
+
overrides :muk, :kuk
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
OverridesTest.class_eval do
|
93
|
+
|
94
|
+
def test_overrides_multiple_at_once
|
95
|
+
assert_equal 'janko-kuk', Janko.new.kuk
|
96
|
+
assert_equal 'janko-muk', Janko.new.muk
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
# ========================================
|
102
|
+
|
103
|
+
class Jozko
|
104
|
+
|
105
|
+
def jak; 'jozko-jak'; end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
OverridesTest.class_eval do
|
110
|
+
|
111
|
+
def test_uses_no_method_error
|
112
|
+
assert_kind_of NoMethodError, Overrides::Error.new
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_fails_when_override_not_met
|
116
|
+
assert_raises Overrides::Error do
|
117
|
+
Jozko.class_eval do
|
118
|
+
overrides :jak
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
assert_raises Overrides::Error do
|
123
|
+
Jozko.class_eval do
|
124
|
+
overrides
|
125
|
+
def tak; end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
assert_raises Overrides::Error do
|
130
|
+
Jozko.class_eval do
|
131
|
+
overrides
|
132
|
+
def self.kuk; end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
# ========================================
|
140
|
+
|
141
|
+
class Ferko
|
142
|
+
def sak; end
|
143
|
+
end
|
144
|
+
|
145
|
+
class Petko < Ferko
|
146
|
+
end
|
147
|
+
|
148
|
+
OverridesTest.class_eval do
|
149
|
+
|
150
|
+
def test_fails_when_method_not_defined
|
151
|
+
assert_raises NoMethodError do
|
152
|
+
Petko.class_eval do
|
153
|
+
overrides :sak
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
# ========================================
|
161
|
+
|
162
|
+
class Otakar
|
163
|
+
def coje; 'tha-nic'; end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Bohuslav < Otakar; end
|
167
|
+
|
168
|
+
OverridesTest.class_eval do
|
169
|
+
|
170
|
+
def test_works_for_all_when_required
|
171
|
+
require 'overrides/for_all'
|
172
|
+
Bohuslav.class_eval do
|
173
|
+
overrides
|
174
|
+
def coje; 'ta-daco'; end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: overrides
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: bundler
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,7 +59,9 @@ dependencies:
|
|
43
59
|
- - ~>
|
44
60
|
- !ruby/object:Gem::Version
|
45
61
|
version: '10.1'
|
46
|
-
description: !
|
62
|
+
description: ! "Helps during refactoring (method renaming) to assure\n methods expected
|
63
|
+
to be overriding another (and calling super) fail early during\n definition time
|
64
|
+
instead of when called."
|
47
65
|
email:
|
48
66
|
- self@kares.org
|
49
67
|
executables: []
|
@@ -51,12 +69,16 @@ extensions: []
|
|
51
69
|
extra_rdoc_files: []
|
52
70
|
files:
|
53
71
|
- .gitignore
|
72
|
+
- .travis.yml
|
54
73
|
- Gemfile
|
55
74
|
- LICENSE.txt
|
75
|
+
- README.md
|
56
76
|
- Rakefile
|
57
77
|
- lib/overrides.rb
|
78
|
+
- lib/overrides/for_all.rb
|
58
79
|
- lib/overrides/version.rb
|
59
80
|
- overrides.gemspec
|
81
|
+
- test/overrides_test.rb
|
60
82
|
homepage: http://github.com/kares/overrides
|
61
83
|
licenses:
|
62
84
|
- MIT
|
@@ -72,7 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
94
|
version: '0'
|
73
95
|
segments:
|
74
96
|
- 0
|
75
|
-
hash:
|
97
|
+
hash: 3588119150367271522
|
76
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
99
|
none: false
|
78
100
|
requirements:
|
@@ -81,11 +103,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
103
|
version: '0'
|
82
104
|
segments:
|
83
105
|
- 0
|
84
|
-
hash:
|
106
|
+
hash: 3588119150367271522
|
85
107
|
requirements: []
|
86
108
|
rubyforge_project:
|
87
109
|
rubygems_version: 1.8.25
|
88
110
|
signing_key:
|
89
111
|
specification_version: 3
|
90
112
|
summary: ! 'an #overrides annotation for your methods'
|
91
|
-
test_files:
|
113
|
+
test_files:
|
114
|
+
- test/overrides_test.rb
|