multidispatch 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d975637a4c55f40bdf6a33590aa958cffdbf0aa3
4
- data.tar.gz: 9a077af69a97c8ced3fc0ff08be393079464aa17
3
+ metadata.gz: 8f12abed938c65400d74580c619b6402c71ff3a8
4
+ data.tar.gz: c46add3d7435b03edad192c00b4e2f3558363c54
5
5
  SHA512:
6
- metadata.gz: dc40bf40542e8ab5cffa4cf1eb918a9be09b9bea5292d0c0840c41b659f411c364a015cb8a317741c622c99b15b891ced694457e9b7c076f435e31c7cb6b8e57
7
- data.tar.gz: a5bbe28efda4a1d9bc0d68d5cc87819daa0e7db3cef8270fd46e1dc84aa1f58ad52d4339488519cf407880e2986af96f41621168ff28c0a83572dece96b156ef
6
+ metadata.gz: 862b044e7ff7f49a7738d0b2eddeb3f1c3416a9d4cd676ace183dc690828d9df3da6442b7a33ffa434e474ac9408ce023963247729ef881717fbc4bcd50bff83
7
+ data.tar.gz: 154fcc15d9e6dff7344c8093c9b59212029dbcc575881f5a775dad50f4f00b4f6446e1ba6bf1d6b56c0c0e288297263d5555adafebf4ad3b37152568484f6377
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.2"
4
+ - "1.9.3"
5
+ - jruby-19mode
6
+ - rbx-19mode
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ruby-multidispatch.gemspec
4
+ gem 'coveralls', :require => false
4
5
  gemspec
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  multidispatch
2
2
  ==================
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/multidispatch.png)](http://badge.fury.io/rb/multidispatch)
5
+ [![Build Status](https://travis-ci.org/noomorph/multidispatch.png)](https://travis-ci.org/noomorph/multidispatch)
6
+ [![Coverage Status](https://coveralls.io/repos/noomorph/multidispatch/badge.png)](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
@@ -1,2 +1,9 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec do
8
+ system "gem build multidispatch.gemspec"
9
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Multidispatch
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  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
- @@store = Store.new
12
+ @@interceptor = Interceptor.new(Store.new)
12
13
 
13
- def method_added(name)
14
- return if @@store.locked? # prevent recursion
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
@@ -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
- context "when released" do
12
- it "can be locked" do
13
- expect { subject.lock! }.to change { subject.locked? }.from(nil).to(true)
14
- end
8
+ it "should extend in self.included method" do
9
+ class IsExtended; end
10
+ subject.included(IsExtended)
15
11
 
16
- it "has no effect to release" do
17
- expect { subject.release! }.not_to change { subject.locked? }
18
- end
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
- it { @the_method.should be_instance_of(UnboundMethod) }
24
- its(:store) { should == {"Hash" => {inspect: {0 => @the_method}}} }
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
- it "get() returns it" do
27
- subject.get(Hash, :inspect, 0).should == @the_method
28
- end
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
- context "when locked" do
34
- before { subject.lock! }
31
+ DoesNotInclude.method(:method_added).should_not == subject
32
+ end
35
33
 
36
- it "can be released" do
37
- expect { subject.release! }.to change { subject.locked? }.from(true).to(nil)
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
- it { @the_method.should be_nil }
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
@@ -1,5 +1,7 @@
1
1
  require 'bundler/setup'
2
2
  require 'multidispatch'
3
+ require 'coveralls'
4
+ Coveralls.wear!
3
5
 
4
6
  RSpec.configure do |config|
5
7
  config.treat_symbols_as_metadata_keys_with_true_values = true
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.2
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-02 00:00:00.000000000 Z
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