multidispatch 0.1.2 → 0.1.3
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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/Gemfile +1 -0
- data/README.md +4 -0
- data/Rakefile +7 -0
- data/lib/multidispatch/interceptor.rb +23 -0
- data/lib/multidispatch/version.rb +1 -1
- data/lib/multidispatch.rb +5 -11
- data/spec/multidispatch_interceptor_spec.rb +47 -0
- data/spec/multidispatch_spec.rb +24 -31
- data/spec/multidispatch_store_spec.rb +40 -0
- data/spec/spec_helper.rb +2 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f12abed938c65400d74580c619b6402c71ff3a8
|
4
|
+
data.tar.gz: c46add3d7435b03edad192c00b4e2f3558363c54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 862b044e7ff7f49a7738d0b2eddeb3f1c3416a9d4cd676ace183dc690828d9df3da6442b7a33ffa434e474ac9408ce023963247729ef881717fbc4bcd50bff83
|
7
|
+
data.tar.gz: 154fcc15d9e6dff7344c8093c9b59212029dbcc575881f5a775dad50f4f00b4f6446e1ba6bf1d6b56c0c0e288297263d5555adafebf4ad3b37152568484f6377
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
multidispatch
|
2
2
|
==================
|
3
3
|
|
4
|
+
[](http://badge.fury.io/rb/multidispatch)
|
5
|
+
[](https://travis-ci.org/noomorph/multidispatch)
|
6
|
+
[](https://coveralls.io/r/noomorph/multidispatch)
|
7
|
+
|
4
8
|
Very basic multidispatch in **Ruby** using natural syntax.
|
5
9
|
Currently supports overloads by count of mandatory parameters.
|
6
10
|
So, it solves only one problem. Converts the following code:
|
data/Rakefile
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Multidispatch::Interceptor
|
2
|
+
attr_accessor :store
|
3
|
+
|
4
|
+
def initialize(store = nil)
|
5
|
+
@store = store
|
6
|
+
end
|
7
|
+
|
8
|
+
def intercept(method)
|
9
|
+
return if @store.locked? # prevent recursion
|
10
|
+
|
11
|
+
store = @store
|
12
|
+
store.set(method.owner, method.name)
|
13
|
+
store.lock!
|
14
|
+
|
15
|
+
method_body = lambda do |*args|
|
16
|
+
method = store.get(self.class, method.name, args.count)
|
17
|
+
method.bind(self).call(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
method.owner.class_eval { define_method method.name, method_body }
|
21
|
+
store.release!
|
22
|
+
end
|
23
|
+
end
|
data/lib/multidispatch.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "multidispatch/store"
|
2
|
+
require "multidispatch/interceptor"
|
2
3
|
require "multidispatch/version"
|
3
4
|
|
4
5
|
module Multidispatch
|
@@ -8,18 +9,11 @@ module Multidispatch
|
|
8
9
|
end
|
9
10
|
|
10
11
|
module ClassMethods
|
11
|
-
@@
|
12
|
+
@@interceptor = Interceptor.new(Store.new)
|
12
13
|
|
13
|
-
def method_added(
|
14
|
-
|
15
|
-
@@store.set(self, name)
|
16
|
-
|
17
|
-
@@store.lock!
|
18
|
-
define_method(name) do |*args|
|
19
|
-
method = @@store.get(self.class, name, args.count)
|
20
|
-
method.bind(self).call(*args)
|
21
|
-
end
|
22
|
-
@@store.release!
|
14
|
+
def method_added(method_name)
|
15
|
+
@@interceptor.intercept(instance_method(method_name))
|
23
16
|
end
|
24
17
|
end
|
18
|
+
|
25
19
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
describe Multidispatch::Interceptor do
|
2
|
+
context "when store is locked" do
|
3
|
+
before { subject.store = double(:locked? => true, :set => nil) }
|
4
|
+
|
5
|
+
it "should not save method to store" do
|
6
|
+
subject.intercept(nil)
|
7
|
+
expect(subject.store).to_not have_received(:set)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when store has no lock" do
|
12
|
+
class Foo; def foo; end end
|
13
|
+
|
14
|
+
before do
|
15
|
+
subject.store = double({
|
16
|
+
:locked? => false,
|
17
|
+
:lock! => nil,
|
18
|
+
:set => nil,
|
19
|
+
:release! => nil
|
20
|
+
})
|
21
|
+
@foo = Foo.instance_method(:foo)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should save method to store" do
|
25
|
+
subject.intercept(@foo)
|
26
|
+
expect(subject.store).to have_received(:set).with(Foo, :foo)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should lock store before re-defining method" do
|
30
|
+
subject.intercept(@foo)
|
31
|
+
expect(subject.store).to have_received(:lock!)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should re-define owner class method" do
|
35
|
+
klass = double(:class_eval => nil)
|
36
|
+
subject.intercept(double(:owner => klass, :name => "method"))
|
37
|
+
|
38
|
+
expect(klass).to have_received(:class_eval)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should release store after re-defining method" do
|
42
|
+
subject.intercept(@foo)
|
43
|
+
expect(subject.store).to have_received(:release!)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
data/spec/multidispatch_spec.rb
CHANGED
@@ -4,45 +4,38 @@ describe Multidispatch do
|
|
4
4
|
it "should have self.included method" do
|
5
5
|
subject.method(:included).should_not be_nil
|
6
6
|
end
|
7
|
-
end
|
8
|
-
|
9
|
-
describe Multidispatch::Store do
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
8
|
+
it "should extend in self.included method" do
|
9
|
+
class IsExtended; end
|
10
|
+
subject.included(IsExtended)
|
15
11
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
context "when method added" do
|
21
|
-
before { @the_method = subject.set(Hash, :inspect) }
|
12
|
+
modules = IsExtended.singleton_class.included_modules
|
13
|
+
modules.should include(Multidispatch::ClassMethods)
|
14
|
+
end
|
15
|
+
end
|
22
16
|
|
23
|
-
|
24
|
-
|
17
|
+
describe Multidispatch::ClassMethods do
|
18
|
+
it "defines variable `interceptor`" do
|
19
|
+
subject.class_variable_defined?(:@@interceptor).should be_true
|
20
|
+
end
|
25
21
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
22
|
+
it "`interceptor` is Multidispatch::Interceptor" do
|
23
|
+
i = subject.send :class_variable_get, :@@interceptor
|
24
|
+
i.should be_instance_of(Multidispatch::Interceptor)
|
31
25
|
end
|
26
|
+
|
27
|
+
it "should not extend class that does not include it" do
|
28
|
+
class DoesNotInclude
|
29
|
+
end
|
32
30
|
|
33
|
-
|
34
|
-
|
31
|
+
DoesNotInclude.method(:method_added).should_not == subject
|
32
|
+
end
|
35
33
|
|
36
|
-
|
37
|
-
|
34
|
+
it "should extend class that includes it" do
|
35
|
+
class Includes
|
36
|
+
extend Multidispatch::ClassMethods
|
38
37
|
end
|
39
|
-
|
40
|
-
context "when try to add method" do
|
41
|
-
before { @the_method = subject.set(Object, :some_method) }
|
42
38
|
|
43
|
-
|
44
|
-
its(:store) { should == {} }
|
45
|
-
end
|
39
|
+
Includes.method(:method_added).owner.should == subject
|
46
40
|
end
|
47
|
-
|
48
41
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
describe Multidispatch::Store do
|
2
|
+
|
3
|
+
context "when released" do
|
4
|
+
it "can be locked" do
|
5
|
+
expect { subject.lock! }.to change { subject.locked? }.from(nil).to(true)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "has no effect to release" do
|
9
|
+
expect { subject.release! }.not_to change { subject.locked? }
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when method added" do
|
13
|
+
before { @the_method = subject.set(Hash, :inspect) }
|
14
|
+
|
15
|
+
it { @the_method.should be_instance_of(UnboundMethod) }
|
16
|
+
its(:store) { should == {"Hash" => {:inspect => {0 => @the_method}}} }
|
17
|
+
|
18
|
+
it "get() returns it" do
|
19
|
+
subject.get(Hash, :inspect, 0).should == @the_method
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when locked" do
|
26
|
+
before { subject.lock! }
|
27
|
+
|
28
|
+
it "can be released" do
|
29
|
+
expect { subject.release! }.to change { subject.locked? }.from(true).to(nil)
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when try to add method" do
|
33
|
+
before { @the_method = subject.set(Object, :some_method) }
|
34
|
+
|
35
|
+
it { @the_method.should be_nil }
|
36
|
+
its(:store) { should == {} }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multidispatch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Iaroslav Sergieiev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -61,12 +61,14 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- .gitignore
|
63
63
|
- .rspec
|
64
|
+
- .travis.yml
|
64
65
|
- Gemfile
|
65
66
|
- LICENSE
|
66
67
|
- LICENSE.txt
|
67
68
|
- README.md
|
68
69
|
- Rakefile
|
69
70
|
- lib/multidispatch.rb
|
71
|
+
- lib/multidispatch/interceptor.rb
|
70
72
|
- lib/multidispatch/store.rb
|
71
73
|
- lib/multidispatch/version.rb
|
72
74
|
- multidispatch.gemspec
|
@@ -74,7 +76,9 @@ files:
|
|
74
76
|
- sample/main.rb
|
75
77
|
- sample/morning.rb
|
76
78
|
- spec/integration_spec.rb
|
79
|
+
- spec/multidispatch_interceptor_spec.rb
|
77
80
|
- spec/multidispatch_spec.rb
|
81
|
+
- spec/multidispatch_store_spec.rb
|
78
82
|
- spec/spec_helper.rb
|
79
83
|
homepage: https://github.com/noomorph/ruby-multidispatch
|
80
84
|
licenses:
|
@@ -103,5 +107,7 @@ summary: Very basic multidispatch in Ruby using natural def syntax. Currently su
|
|
103
107
|
only overloads by count of mandatory parameters.
|
104
108
|
test_files:
|
105
109
|
- spec/integration_spec.rb
|
110
|
+
- spec/multidispatch_interceptor_spec.rb
|
106
111
|
- spec/multidispatch_spec.rb
|
112
|
+
- spec/multidispatch_store_spec.rb
|
107
113
|
- spec/spec_helper.rb
|