loverload 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +149 -0
- data/Rakefile +1 -0
- data/lib/loverload.rb +18 -0
- data/lib/loverload/method.rb +49 -0
- data/lib/loverload/version.rb +3 -0
- data/loverload.gemspec +25 -0
- data/spec/loverload/loverload_spec.rb +168 -0
- metadata +121 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Teja Sophista V.R.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# Loverload
|
2
|
+
|
3
|
+
DSL for building method overloading in Ruby.
|
4
|
+
|
5
|
+
Rigid language like Java allow you to create method overloading:
|
6
|
+
|
7
|
+
``` java
|
8
|
+
public void draw(String s) {
|
9
|
+
...
|
10
|
+
}
|
11
|
+
public void draw(int i) {
|
12
|
+
...
|
13
|
+
}
|
14
|
+
public void draw(double f) {
|
15
|
+
...
|
16
|
+
}
|
17
|
+
public void draw(int i, double f) {
|
18
|
+
...
|
19
|
+
}
|
20
|
+
```
|
21
|
+
|
22
|
+
However, in Ruby, we don't have this kind of thing, _do we_?
|
23
|
+
|
24
|
+
``` ruby
|
25
|
+
before_save NameSayer.new
|
26
|
+
before_save :say_my_name
|
27
|
+
before_save {|record| puts "My name is #{record.name}" }
|
28
|
+
before_save 'puts "My name is #{self.name}"'
|
29
|
+
```
|
30
|
+
|
31
|
+
[An Intervention for ActiveRecord](https://speakerdeck.com/erniemiller/an-intervention-for-activerecord) by [Ernie Miller](http://erniemiller.org)
|
32
|
+
|
33
|
+
|
34
|
+
## Installation
|
35
|
+
|
36
|
+
Add this line to your application's Gemfile:
|
37
|
+
|
38
|
+
gem 'loverload'
|
39
|
+
|
40
|
+
And then execute:
|
41
|
+
|
42
|
+
$ bundle
|
43
|
+
|
44
|
+
Or install it yourself as:
|
45
|
+
|
46
|
+
$ gem install loverload
|
47
|
+
|
48
|
+
## Usage
|
49
|
+
|
50
|
+
Simple
|
51
|
+
|
52
|
+
``` ruby
|
53
|
+
class Dummy
|
54
|
+
include Loverload
|
55
|
+
|
56
|
+
def_overload :hello do
|
57
|
+
with_params do
|
58
|
+
"Hello Nobody"
|
59
|
+
end
|
60
|
+
|
61
|
+
with_params do |name|
|
62
|
+
"Hello #{ name }"
|
63
|
+
end
|
64
|
+
|
65
|
+
with_params do |name, age|
|
66
|
+
"Hello #{ name } Age #{ age }"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
dummy = Dummy.new
|
72
|
+
dummy.hello #=> 'Hello Nobody'
|
73
|
+
dummy.hello('Teja') #=> 'Hello Teja'
|
74
|
+
dummy.hello('Teja', 21) #=> 'Hello Teja Age 21'
|
75
|
+
```
|
76
|
+
|
77
|
+
Strict
|
78
|
+
``` ruby
|
79
|
+
class Dummy
|
80
|
+
include Loverload
|
81
|
+
|
82
|
+
def_overload :hello do
|
83
|
+
with_params String do |name|
|
84
|
+
"Hello Name: #{ name }"
|
85
|
+
end
|
86
|
+
|
87
|
+
with_params Fixnum do |age|
|
88
|
+
"Hello Age: #{ age }"
|
89
|
+
end
|
90
|
+
|
91
|
+
with_params String, Fixnum do |name, age|
|
92
|
+
"Hello Name: #{ name } Age: #{ age }"
|
93
|
+
end
|
94
|
+
|
95
|
+
with_params Fixnum, String do |age, name|
|
96
|
+
"Hello Age: #{ age } Name: #{ name }"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
dummy = Dummy.new
|
102
|
+
dummy.hello('Teja') #=> 'Hello Name: Teja'
|
103
|
+
dummy.hello(21) #=> 'Hello Age: 21'
|
104
|
+
dummy.hello('Teja', 21) #=> 'Hello Name: Teja Age: 21'
|
105
|
+
dummy.hello(21, 'Teja') #=> 'Hello Age: 21 Name: Teja'
|
106
|
+
dummy.hello('Teja', 21, true) #=> NoMethodError
|
107
|
+
```
|
108
|
+
|
109
|
+
This is how you do :before_save
|
110
|
+
``` ruby
|
111
|
+
class Dummy
|
112
|
+
include Loverload
|
113
|
+
|
114
|
+
def_overload :before_save do
|
115
|
+
with_params Dummy do |dummy|
|
116
|
+
"Puke rainbow"
|
117
|
+
end
|
118
|
+
|
119
|
+
with_params Symbol do |symbol|
|
120
|
+
"Puke more rainbow"
|
121
|
+
end
|
122
|
+
|
123
|
+
with_params Proc do |proc|
|
124
|
+
"Puke rainbow and leprechaun"
|
125
|
+
end
|
126
|
+
|
127
|
+
with_params String do |string|
|
128
|
+
"Puke rainbow, leprechaun, and gold"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
dummy = Dummy.new
|
134
|
+
dummy.before_save(Dummy.new) #=> "Puke rainbow"
|
135
|
+
dummy.before_save(:symbol) #=> "Puke more rainbow"
|
136
|
+
dummy.before_save(proc{|this| is proc}) #=> "Puke rainbow and leprechaun"
|
137
|
+
dummy.before_save('string') #=> "Puke rainbow, leprechaun, and gold"
|
138
|
+
```
|
139
|
+
|
140
|
+
## TODO
|
141
|
+
- Make it less ugly
|
142
|
+
|
143
|
+
## Contributing
|
144
|
+
|
145
|
+
1. Fork it
|
146
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
147
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
148
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
149
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/loverload.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "loverload/version"
|
2
|
+
require "loverload/method"
|
3
|
+
|
4
|
+
module Loverload
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def def_overload method_name, &with_params_block
|
11
|
+
method = Method.new(self, method_name, &with_params_block)
|
12
|
+
|
13
|
+
define_method method_name do |*args|
|
14
|
+
method.overload(self, *args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Loverload
|
2
|
+
class Method
|
3
|
+
def initialize klass, method_name, &with_params_block
|
4
|
+
@klass = klass
|
5
|
+
@method_name = method_name
|
6
|
+
instance_eval(&with_params_block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def with_params *pars, &block
|
10
|
+
default = "__#{ @method_name }_#{ block.arity }"
|
11
|
+
method_name = "__name_#{ default }_#{ type_signature(pars) }"
|
12
|
+
method_alias = "__alias_#{ default }_#{ alias_signature(pars) }"
|
13
|
+
|
14
|
+
@klass.define_method method_name do |*args|
|
15
|
+
instance_exec(*args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
@klass.send :alias_method, method_alias, method_name
|
19
|
+
@klass.send :alias_method, default, method_name
|
20
|
+
|
21
|
+
[default, method_name, method_alias].each{ |m| @klass.send :private, m }
|
22
|
+
end
|
23
|
+
|
24
|
+
def overload instance, *args
|
25
|
+
default = "__#{ @method_name }_#{ args.size }"
|
26
|
+
method_name = "__name_#{ default }_#{ type_signature(args.map(&:class)) }"
|
27
|
+
method_alias = "__alias_#{ default }_#{ alias_signature(args.map(&:class)) }"
|
28
|
+
|
29
|
+
if instance.respond_to? method_name, true
|
30
|
+
instance.send method_name, *args
|
31
|
+
elsif instance.respond_to? method_alias, true
|
32
|
+
instance.send method_alias, *args
|
33
|
+
elsif instance.respond_to? default, true
|
34
|
+
instance.send default, *args
|
35
|
+
else
|
36
|
+
raise NoMethodError, "Undefined method '#{ @method_name }' for #{ type_signature(args.map(&:class)) }"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def type_signature array_of_class
|
42
|
+
array_of_class.to_s.gsub(/[\[\]]/, '')
|
43
|
+
end
|
44
|
+
|
45
|
+
def alias_signature array_of_class
|
46
|
+
'Object' * array_of_class.size
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/loverload.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'loverload/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "loverload"
|
8
|
+
spec.version = Loverload::VERSION
|
9
|
+
spec.authors = ["Teja Sophista V.R."]
|
10
|
+
spec.email = ["tejanium@yahoo.com"]
|
11
|
+
spec.description = %q{DSL for building method overloading in Ruby more magical}
|
12
|
+
spec.summary = %q{DSL for building method overloading in Ruby}
|
13
|
+
spec.homepage = "http://github.com/tejanium/loverload"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "debugger"
|
25
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'loverload'
|
2
|
+
|
3
|
+
describe Loverload do
|
4
|
+
it "makes your code more magical" do
|
5
|
+
class Dummy
|
6
|
+
include Loverload
|
7
|
+
|
8
|
+
def_overload :hello do
|
9
|
+
with_params do
|
10
|
+
"Hello Nobody"
|
11
|
+
end
|
12
|
+
|
13
|
+
with_params do |name|
|
14
|
+
"Hello #{ name }"
|
15
|
+
end
|
16
|
+
|
17
|
+
with_params do |name, age|
|
18
|
+
"Hello #{ name } Age #{ age }"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
dummy = Dummy.new
|
24
|
+
dummy.hello.should eql 'Hello Nobody'
|
25
|
+
dummy.hello('Teja').should eql 'Hello Teja'
|
26
|
+
dummy.hello('Teja', 21).should eql 'Hello Teja Age 21'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "makes your code even more magical" do
|
30
|
+
class Dummy
|
31
|
+
include Loverload
|
32
|
+
|
33
|
+
def_overload :hello do
|
34
|
+
with_params String do |name|
|
35
|
+
"Hello Name: #{ name }"
|
36
|
+
end
|
37
|
+
|
38
|
+
with_params Fixnum do |age|
|
39
|
+
"Hello Age: #{ age }"
|
40
|
+
end
|
41
|
+
|
42
|
+
with_params String, Fixnum do |name, age|
|
43
|
+
"Hello Name: #{ name } Age: #{ age }"
|
44
|
+
end
|
45
|
+
|
46
|
+
with_params Fixnum, String do |age, name|
|
47
|
+
"Hello Age: #{ age } Name: #{ name }"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
dummy = Dummy.new
|
53
|
+
dummy.hello('Teja').should eql 'Hello Name: Teja'
|
54
|
+
dummy.hello(21).should eql 'Hello Age: 21'
|
55
|
+
dummy.hello('Teja', 21).should eql 'Hello Name: Teja Age: 21'
|
56
|
+
dummy.hello(21, 'Teja').should eql 'Hello Age: 21 Name: Teja'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "makes you puke rainbow" do
|
60
|
+
class Dummy
|
61
|
+
include Loverload
|
62
|
+
|
63
|
+
def_overload :before_save do
|
64
|
+
with_params Dummy do |dummy|
|
65
|
+
"Puke rainbow"
|
66
|
+
end
|
67
|
+
|
68
|
+
with_params Symbol do |symbol|
|
69
|
+
"Puke more rainbow"
|
70
|
+
end
|
71
|
+
|
72
|
+
with_params Proc do |proc|
|
73
|
+
"Puke rainbow and leprechaun"
|
74
|
+
end
|
75
|
+
|
76
|
+
with_params String do |string|
|
77
|
+
"Puke rainbow, leprechaun, and gold"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
dummy = Dummy.new
|
83
|
+
dummy.before_save(Dummy.new).should eql "Puke rainbow"
|
84
|
+
dummy.before_save(:symbol).should eql "Puke more rainbow"
|
85
|
+
dummy.before_save(proc{|this| is proc}).should eql "Puke rainbow and leprechaun"
|
86
|
+
dummy.before_save('string').should eql "Puke rainbow, leprechaun, and gold"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "can call another method" do
|
90
|
+
class Dummy
|
91
|
+
include Loverload
|
92
|
+
|
93
|
+
def another_method
|
94
|
+
'Hello from another method'
|
95
|
+
end
|
96
|
+
|
97
|
+
def_overload :call_another_method do
|
98
|
+
with_params do
|
99
|
+
another_method
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
dummy = Dummy.new
|
105
|
+
|
106
|
+
dummy.call_another_method.should eql 'Hello from another method'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "shared state" do
|
110
|
+
class Dummy
|
111
|
+
include Loverload
|
112
|
+
|
113
|
+
def initialize
|
114
|
+
@hello = 'World'
|
115
|
+
end
|
116
|
+
|
117
|
+
def another_method
|
118
|
+
'Hello from another method'
|
119
|
+
end
|
120
|
+
|
121
|
+
def_overload :call_another_method do
|
122
|
+
with_params do
|
123
|
+
"#@hello, #{ another_method }"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
dummy = Dummy.new
|
129
|
+
|
130
|
+
dummy.call_another_method.should eql 'World, Hello from another method'
|
131
|
+
end
|
132
|
+
|
133
|
+
it "can have two overload methods" do
|
134
|
+
class Dummy
|
135
|
+
include Loverload
|
136
|
+
|
137
|
+
def another_method
|
138
|
+
'Hello from another method'
|
139
|
+
end
|
140
|
+
|
141
|
+
def_overload :method_1 do
|
142
|
+
with_params do
|
143
|
+
'method_1'
|
144
|
+
end
|
145
|
+
|
146
|
+
with_params do |arg|
|
147
|
+
"method_1 with arg"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def_overload :method_2 do
|
152
|
+
with_params do
|
153
|
+
'method_2'
|
154
|
+
end
|
155
|
+
|
156
|
+
with_params do |arg|
|
157
|
+
"method_2 with arg"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
dummy = Dummy.new
|
163
|
+
dummy.method_1.should eql 'method_1'
|
164
|
+
dummy.method_1(1).should eql 'method_1 with arg'
|
165
|
+
dummy.method_2.should eql 'method_2'
|
166
|
+
dummy.method_2(1).should eql 'method_2 with arg'
|
167
|
+
end
|
168
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: loverload
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Teja Sophista V.R.
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
prerelease: false
|
16
|
+
type: :development
|
17
|
+
name: bundler
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '1.3'
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
prerelease: false
|
32
|
+
type: :development
|
33
|
+
name: rake
|
34
|
+
version_requirements: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
prerelease: false
|
48
|
+
type: :development
|
49
|
+
name: rspec
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
prerelease: false
|
64
|
+
type: :development
|
65
|
+
name: debugger
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: DSL for building method overloading in Ruby more magical
|
79
|
+
email:
|
80
|
+
- tejanium@yahoo.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE.txt
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- lib/loverload.rb
|
91
|
+
- lib/loverload/method.rb
|
92
|
+
- lib/loverload/version.rb
|
93
|
+
- loverload.gemspec
|
94
|
+
- spec/loverload/loverload_spec.rb
|
95
|
+
homepage: http://github.com/tejanium/loverload
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.8.25
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: DSL for building method overloading in Ruby
|
120
|
+
test_files:
|
121
|
+
- spec/loverload/loverload_spec.rb
|