Skip to content

Commit 6eaf859

Browse files
committed
Merge pull request #10 from sclinede/master
Implement `#respond_to_missing?` and stop using Struct
2 parents b0c69fd + 8aeb332 commit 6eaf859

8 files changed

Lines changed: 62 additions & 4 deletions

File tree

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ rvm:
55
- 2.0.0
66
- 2.1.2
77
script: bundle exec rspec
8+
before_install:
9+
- gem install bundler

lib/monads/eventually.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
require 'monads/monad'
22

33
module Monads
4-
Eventually = Struct.new(:block) do
4+
class Eventually
55
include Monad
6+
attr_reader :block
67

78
def initialize(&block)
8-
super(block)
9+
@block = block
910
end
1011

1112
def run(&success)

lib/monads/many.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
require 'monads/monad'
22

33
module Monads
4-
Many = Struct.new(:values) do
4+
class Many
55
include Monad
6+
attr_reader :values
7+
8+
def initialize(values)
9+
@values = values
10+
end
611

712
def and_then(&block)
813
block = ensure_monadic_result(&block)

lib/monads/monad.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ def method_missing(*args, &block)
1212
end
1313
end
1414

15+
def respond_to_missing?(method_name, include_private=false)
16+
within do |value|
17+
value.respond_to?(method_name, include_private)
18+
end || super
19+
end
20+
1521
private
1622

1723
def ensure_monadic_result(&block)

lib/monads/optional.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
require 'monads/monad'
22

33
module Monads
4-
Optional = Struct.new(:value) do
4+
class Optional
55
include Monad
6+
attr_reader :value
7+
8+
def initialize(value)
9+
@value = value
10+
end
611

712
def and_then(&block)
813
block = ensure_monadic_result(&block)

spec/monads/eventually_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,26 @@ module Monads
102102
it 'forwards any unrecognised message to the block’s value' do
103103
expect(value).to receive(:challenge)
104104
Eventually.new { |success| success.call(value) }.challenge.run {}
105+
expect { Eventually.new { |success| success.call(value) }.method(:challenge) }.not_to raise_error
106+
expect(Eventually.new { |success| success.call(value) }).to respond_to(:challenge)
105107
end
106108

107109
it 'returns the message’s result wrapped in an Eventually' do
108110
@result = nil
109111
Eventually.new { |success| success.call(value) }.challenge.run { |result| @result = result }
110112
expect(@result).to eq response
111113
end
114+
115+
context 'when value is Enumerable' do
116+
let(:value) { [1, 2, 3] }
117+
118+
it 'forwards any unrecognised message to the value' do
119+
expect(Eventually.new { |success| success.call(value) }.first).to be_a(Eventually)
120+
expect(Eventually.new { |success| success.call(value) }.first.run { |value| value }).to eq 1
121+
expect(Eventually.new { |success| success.call(value) }.last).to be_a(Eventually)
122+
expect(Eventually.new { |success| success.call(value) }.last.run { |value| value }).to eq 3
123+
end
124+
end
112125
end
113126
end
114127
end

spec/monads/many_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,24 @@ module Monads
8787
expect(value).to receive(:challenge)
8888
end
8989
many.challenge
90+
expect { many.method(:challenge) }.not_to raise_error
91+
expect(many).to respond_to(:challenge)
9092
end
9193

9294
it 'returns the messages’ results wrapped in a Many' do
9395
expect(many.challenge.values).to eq responses
9496
end
97+
98+
context 'when values are Enumerable' do
99+
let(:values) { [[1, 2], [3, 5]] }
100+
101+
it 'forwards any unrecognised message to the value' do
102+
expect(many.first).to be_a(Many)
103+
expect(many.first.values).to eq [1, 3]
104+
expect(many.last).to be_a(Many)
105+
expect(many.last.values).to eq [2, 5]
106+
end
107+
end
95108
end
96109
end
97110
end

spec/monads/optional_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,24 @@ module Monads
8989
it 'forwards any unrecognised message to the value' do
9090
expect(value).to receive(:challenge)
9191
optional.challenge
92+
expect { optional.method(:challenge) }.not_to raise_error
93+
expect(optional).to respond_to(:challenge)
9294
end
9395

9496
it 'returns the message’s result wrapped in an Optional' do
9597
expect(optional.challenge.value).to eq response
9698
end
99+
100+
context 'when value is Enumerable' do
101+
let(:value) { [1, 2, 3] }
102+
103+
it 'forwards any unrecognised message to the value' do
104+
expect(optional.first).to be_a(Optional)
105+
expect(optional.first.value).to eq 1
106+
expect(optional.last).to be_a(Optional)
107+
expect(optional.last.value).to eq 3
108+
end
109+
end
97110
end
98111
end
99112
end

0 commit comments

Comments
 (0)