lambda_driver 1.1.2 → 1.2.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/.gitignore +1 -0
- data/.travis.yml +2 -1
- data/README.md +25 -0
- data/lib/lambda_driver/core_ext/method.rb +1 -0
- data/lib/lambda_driver/core_ext/object.rb +1 -0
- data/lib/lambda_driver/core_ext/proc.rb +1 -0
- data/lib/lambda_driver/liftable.rb +35 -0
- data/lib/lambda_driver/mzero.rb +6 -0
- data/lib/lambda_driver/version.rb +1 -1
- data/spec/lambda_spec.rb +6 -0
- data/spec/proc_spec.rb +6 -0
- data/spec/shared/liftable.rb +43 -0
- metadata +20 -5
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -82,6 +82,31 @@ This method is aliased as `<<`.
|
|
82
82
|
f << g < :hoge # => "44" ( == f.call(g.call(:hoge)) )
|
83
83
|
```
|
84
84
|
|
85
|
+
|
86
|
+
#### Proc#compose_with_lifting
|
87
|
+
|
88
|
+
compose self and give fuction with checking g(x) is mzero.
|
89
|
+
if g(x) is mzero, it does not call self and return g(x),
|
90
|
+
otherwise returns f(g(x)).
|
91
|
+
|
92
|
+
mzero means the object is nil or emtpy
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
hash = {:a => "foo"}
|
96
|
+
f = lambda{|y| y.length }
|
97
|
+
g = lambda{|y| hash[y]}
|
98
|
+
h = f.compose_with_lifting g
|
99
|
+
h.(:a) # => 3
|
100
|
+
h.(:b) # => nil (it does not called f)
|
101
|
+
```
|
102
|
+
|
103
|
+
This method is aliased as `<=`.
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
f <= g # => f.compose_with_lifting(g)
|
107
|
+
```
|
108
|
+
|
109
|
+
|
85
110
|
#### Proc#with_args
|
86
111
|
|
87
112
|
Returns partially applied function that has 2nd and more parameters are
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module LambdaDriver::Liftable
|
2
|
+
|
3
|
+
# compose self and give fuction with checking g(x) is mzero.
|
4
|
+
# if g(x) is mzero, it does not call self and return g(x),
|
5
|
+
# otherwise returns f(g(x)).
|
6
|
+
#
|
7
|
+
# mzero means the object is nil or emtpy
|
8
|
+
#
|
9
|
+
# hash = {:a => "foo"}
|
10
|
+
# f = lambda{|y| y.length }
|
11
|
+
# g = lambda{|y| hash[y]}
|
12
|
+
# h = f.compose_with_lifting g
|
13
|
+
# h.(:a) # => 3
|
14
|
+
# h.(:b) # => nil (it does not called f)
|
15
|
+
#
|
16
|
+
# This method is aliased as `<=`.
|
17
|
+
#
|
18
|
+
# f <= g # => f.compose_with_lifting(g)
|
19
|
+
#
|
20
|
+
def compose_with_lifting(g)
|
21
|
+
lambda{|*args|
|
22
|
+
result = g.to_proc.call(*args)
|
23
|
+
mzero_method = result.respond_to?(:mzero?) ? :mzero? : :nil?
|
24
|
+
result.send(mzero_method) ? result : self.to_proc.call(result)
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def >=(g)
|
29
|
+
g.to_proc <= self
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.included(klass)
|
33
|
+
klass.send(:alias_method, :<=, :compose_with_lifting)
|
34
|
+
end
|
35
|
+
end
|
data/spec/lambda_spec.rb
CHANGED
@@ -7,6 +7,12 @@ describe 'lambda' do
|
|
7
7
|
it_should_behave_like 'composable'
|
8
8
|
end
|
9
9
|
|
10
|
+
describe '#compose_with_lifting' do
|
11
|
+
subject { lambda{|x| x.mzero? ? x : x.to_s} }
|
12
|
+
|
13
|
+
it_should_behave_like 'liftable'
|
14
|
+
end
|
15
|
+
|
10
16
|
describe '#with_args' do
|
11
17
|
subject { lambda{|x, y, *z| [x, y] + z.to_a } }
|
12
18
|
it_should_behave_like 'with_args'
|
data/spec/proc_spec.rb
CHANGED
@@ -7,6 +7,12 @@ describe Proc do
|
|
7
7
|
it_should_behave_like 'composable'
|
8
8
|
end
|
9
9
|
|
10
|
+
describe '#compose_with_lifting' do
|
11
|
+
subject { Proc.new{|x| x.mzero? ? x : x.to_s} }
|
12
|
+
|
13
|
+
it_should_behave_like 'liftable'
|
14
|
+
end
|
15
|
+
|
10
16
|
describe '#with_args' do
|
11
17
|
subject { Proc.new{|x, y, *z| [x, y] + z.to_a } }
|
12
18
|
it_should_behave_like 'with_args'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'liftable' do
|
4
|
+
it { should respond_to :compose_with_lifting }
|
5
|
+
it { should respond_to :>= }
|
6
|
+
it { should respond_to :<= }
|
7
|
+
|
8
|
+
let(:x) { :foo }
|
9
|
+
let(:y) { [1,2] }
|
10
|
+
let(:z) { {:a => 1, :b => 2} }
|
11
|
+
let(:g) { lambda{|x|
|
12
|
+
if x.nil? || (x.respond_to?(:empty?) && x.empty?)
|
13
|
+
raise "g called with nil arg"
|
14
|
+
else
|
15
|
+
(x.to_s * 2) + "_g"
|
16
|
+
end
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
it('" f >= g" returns function that does not call g if args is mzero'){
|
21
|
+
(subject >= g).should be_a_kind_of Proc
|
22
|
+
}
|
23
|
+
|
24
|
+
it('"(f >= g).call(nil) returns nil and does not call g'){
|
25
|
+
(subject >= g).call(nil).should be_nil
|
26
|
+
}
|
27
|
+
it('"(f >= g).call(x) should be g(f(x))'){
|
28
|
+
(subject >= g).call(x).should == g.call(subject.to_proc.call(x))
|
29
|
+
}
|
30
|
+
it('"(f >= g).call([]) returns [] and does not call g'){
|
31
|
+
(subject >= g).call([]).should == []
|
32
|
+
}
|
33
|
+
it('"(f >= g).call([1,2]) should be g(f([1,2]))'){
|
34
|
+
(subject >= g).call(y).should == g.call(subject.to_proc.call(y))
|
35
|
+
}
|
36
|
+
it('"(f >= g).call({}) returns {} and does not call g'){
|
37
|
+
(subject >= g).call({}).should == {}
|
38
|
+
}
|
39
|
+
it('"(f >= g).call({:a => 1,:b => 2}) should be g(f({:a => 1, :b => 2}))'){
|
40
|
+
(subject >= g).call(z).should == g.call(subject.to_proc.call(z))
|
41
|
+
}
|
42
|
+
|
43
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lambda_driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,12 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
description: Drives your code more functioal!
|
26
31
|
email:
|
27
32
|
- ozaki@yuroyoro.com
|
@@ -48,6 +53,8 @@ files:
|
|
48
53
|
- lib/lambda_driver/core_ext/unbound_method.rb
|
49
54
|
- lib/lambda_driver/currying.rb
|
50
55
|
- lib/lambda_driver/disjunction.rb
|
56
|
+
- lib/lambda_driver/liftable.rb
|
57
|
+
- lib/lambda_driver/mzero.rb
|
51
58
|
- lib/lambda_driver/op.rb
|
52
59
|
- lib/lambda_driver/revapply.rb
|
53
60
|
- lib/lambda_driver/version.rb
|
@@ -59,6 +66,7 @@ files:
|
|
59
66
|
- spec/proc_spec.rb
|
60
67
|
- spec/revapply_spec.rb
|
61
68
|
- spec/shared/composable_spec.rb
|
69
|
+
- spec/shared/liftable.rb
|
62
70
|
- spec/spec_helper.rb
|
63
71
|
- spec/symbol_spec.rb
|
64
72
|
- spec/unbound_method_spec.rb
|
@@ -74,15 +82,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
82
|
- - ! '>='
|
75
83
|
- !ruby/object:Gem::Version
|
76
84
|
version: '0'
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
hash: -920517596245893888
|
77
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
89
|
none: false
|
79
90
|
requirements:
|
80
91
|
- - ! '>='
|
81
92
|
- !ruby/object:Gem::Version
|
82
93
|
version: '0'
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
hash: -920517596245893888
|
83
97
|
requirements: []
|
84
98
|
rubyforge_project:
|
85
|
-
rubygems_version: 1.8.
|
99
|
+
rubygems_version: 1.8.23
|
86
100
|
signing_key:
|
87
101
|
specification_version: 3
|
88
102
|
summary: Drives your code more functioal!
|
@@ -95,6 +109,7 @@ test_files:
|
|
95
109
|
- spec/proc_spec.rb
|
96
110
|
- spec/revapply_spec.rb
|
97
111
|
- spec/shared/composable_spec.rb
|
112
|
+
- spec/shared/liftable.rb
|
98
113
|
- spec/spec_helper.rb
|
99
114
|
- spec/symbol_spec.rb
|
100
115
|
- spec/unbound_method_spec.rb
|