lambda_driver 1.0.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 +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +170 -0
- data/Rakefile +1 -0
- data/lambda_driver.gemspec +22 -0
- data/lib/lambda_driver/ap.rb +13 -0
- data/lib/lambda_driver/callable.rb +94 -0
- data/lib/lambda_driver/core_ext/class.rb +3 -0
- data/lib/lambda_driver/core_ext/method.rb +4 -0
- data/lib/lambda_driver/core_ext/object.rb +4 -0
- data/lib/lambda_driver/core_ext/proc.rb +4 -0
- data/lib/lambda_driver/core_ext/symbol.rb +4 -0
- data/lib/lambda_driver/core_ext/unbound_method.rb +3 -0
- data/lib/lambda_driver/core_ext.rb +3 -0
- data/lib/lambda_driver/currying.rb +20 -0
- data/lib/lambda_driver/op.rb +31 -0
- data/lib/lambda_driver/version.rb +3 -0
- data/lib/lambda_driver.rb +26 -0
- data/spec/ap_spec.rb +41 -0
- data/spec/class_spec.rb +12 -0
- data/spec/lambda_spec.rb +61 -0
- data/spec/method_spec.rb +91 -0
- data/spec/op_spec.rb +63 -0
- data/spec/proc_spec.rb +61 -0
- data/spec/shared/composable_spec.rb +193 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/symbol_spec.rb +63 -0
- data/spec/unbound_method_spec.rb +13 -0
- metadata +96 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Tomohito Ozaki
|
|
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,170 @@
|
|
|
1
|
+
# LambdaDriver
|
|
2
|
+
|
|
3
|
+
虚弦斥力場生成システム
|
|
4
|
+
|
|
5
|
+
LambdaDriver drives your code more functional.
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# [:foo, :bar, :baz].map{|s| s.to_s }.map{|s| s.upcase }
|
|
9
|
+
# [:foo, :bar, :baz].map(&:to_s).map(&:upcase)
|
|
10
|
+
|
|
11
|
+
[:foo, :bar, :baz].map(&:to_s >> :upcase ) # => ["FOO", "BAR", "BAZ"]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
# [:foo, :hoge, :bar, :fuga].select{|s| s.to_s.length > 3} # => [:hoge, :fuga]
|
|
16
|
+
|
|
17
|
+
[:foo, :hoge, :bar, :fuga].select(&:to_s >> :length >> 3._(:<)) # => [:hoge, :fuga]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Add this line to your application's Gemfile:
|
|
23
|
+
|
|
24
|
+
gem 'lambda_driver'
|
|
25
|
+
|
|
26
|
+
And then execute:
|
|
27
|
+
|
|
28
|
+
$ bundle
|
|
29
|
+
|
|
30
|
+
Or install it yourself as:
|
|
31
|
+
|
|
32
|
+
$ gem install lambda_driver
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### Proc/lambda/Symbol/Method extensions
|
|
37
|
+
- call
|
|
38
|
+
- compose
|
|
39
|
+
- with_args
|
|
40
|
+
- flip
|
|
41
|
+
- curry
|
|
42
|
+
|
|
43
|
+
#### alias :< to Proc#call
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
f = lamdba{|x| x.to_s }
|
|
47
|
+
f < :foo # => "foo"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Proc#compose
|
|
51
|
+
|
|
52
|
+
Returns new lambda which composed self and given function.
|
|
53
|
+
A composed proc called with args, executes `self.(g(*args)).
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
f = lamdba{|x| x.to_s }
|
|
57
|
+
g = lambda{|y| y.length }
|
|
58
|
+
h = f compose g
|
|
59
|
+
h.(:hoge) # => 4
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This method is aliased as `<<`.
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
f << g # => f.compose(g)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Proc#with_args
|
|
69
|
+
|
|
70
|
+
Returns partially applied function that has 2nd and more parameters
|
|
71
|
+
fixed by given *args.
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
f = lamdba{|x, y, z| [x, y, z]}
|
|
75
|
+
h = f.with_args(:a, :b)
|
|
76
|
+
h.(:c) # => [:c, :a, :b]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This method is aliased as `*`.
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
f * :foo # => f.with_args(:foo)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
#### Proc#flip
|
|
87
|
+
|
|
88
|
+
Returns function whose parameter order spawed 1st for 2nd.
|
|
89
|
+
A result of filped fuction is curried by Proc#curry.
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
f = lamdba{|x, y, z| [x, y, z]}
|
|
93
|
+
h = f.flip
|
|
94
|
+
h.(:a).(:b).(:c) # => [:b, :a, :c]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If arguments is var-args, pass explicitly arity to curring.
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
p = Proc.new{|*args| args.inspect }
|
|
101
|
+
p.flip(3).call(:a).(:b).(:c) # => "[:b, :a, :c]"
|
|
102
|
+
p.flip(4).call(:a).(:b).(:c).(:d) # => "[:b, :a, :c, :d]"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If arity is 0 or 1, flip returns itself.
|
|
106
|
+
|
|
107
|
+
This method is aliased as `~@`.
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
~f # => f.filp
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
<!-- Symbol extensions -->
|
|
114
|
+
<!-- - to_method -->
|
|
115
|
+
|
|
116
|
+
### Class extensions
|
|
117
|
+
- alias instance_method, :/
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
String / :index # => #<UnboundMethod: String#index>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### UnboundMethod extensions
|
|
124
|
+
- alias bind, :<
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
String / :index # => #<UnboundMethod: String#index>
|
|
128
|
+
String / :index < "foobarbaz" # => #<Method: String#index>
|
|
129
|
+
String / :index < "foobarbaz" < 3 # => 3 (== "foobarbaz".index(3) )
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Combinators
|
|
133
|
+
<!-- - && || -->
|
|
134
|
+
- ski combinator
|
|
135
|
+
|
|
136
|
+
### Object extensions
|
|
137
|
+
- ap(|>) : obj.ap(f) => f.call(obj)
|
|
138
|
+
- obj._.method : returns obj.method(method) or lamdba{|*args| obj.send(method, *args) }
|
|
139
|
+
<!-- - obj.disjunction(f) : if f(self) is nil, return self else return f(self) -->
|
|
140
|
+
|
|
141
|
+
#### Object#ap
|
|
142
|
+
|
|
143
|
+
`Object#ap` is applies self to given proc/block.
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
f = lambda{|x| x * 2 }
|
|
147
|
+
"foo".ap(f) # => "fooffoo"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Object#_
|
|
151
|
+
|
|
152
|
+
Object#op is shortcut to quickly extract Method object.
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
"foobarbaz"._.index #=> #<Method: String#index>
|
|
156
|
+
"foobarbaz"._.index < "bar" # => 3 (== "foobarbaz".index(3) )
|
|
157
|
+
|
|
158
|
+
2._(:>=) # => #<Method: Fixnum#>=>
|
|
159
|
+
[1, 2, 3].select(&2._(:>=)) # => [1, 2]( = [1, 2].select{|n| 2 >= n})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
## Contributing
|
|
165
|
+
|
|
166
|
+
1. Fork it
|
|
167
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
168
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
169
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
170
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'lambda_driver/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "lambda_driver"
|
|
8
|
+
gem.version = LambdaDriver::VERSION
|
|
9
|
+
gem.authors = ["Tomohito Ozaki"]
|
|
10
|
+
gem.email = ["ozaki@yuroyoro.com"]
|
|
11
|
+
gem.description = %q{Drives your code more functioal!}
|
|
12
|
+
gem.summary = %q{Drives your code more functioal!}
|
|
13
|
+
gem.homepage = ""
|
|
14
|
+
|
|
15
|
+
gem.files = `git ls-files`.split($/)
|
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
|
+
gem.require_paths = ["lib"]
|
|
19
|
+
|
|
20
|
+
# dependencies
|
|
21
|
+
gem.add_development_dependency 'rspec'
|
|
22
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module LambdaDriver::Callable
|
|
2
|
+
|
|
3
|
+
def call(*args, &block)
|
|
4
|
+
if block_given?
|
|
5
|
+
self.to_proc.call(*args, &block)
|
|
6
|
+
else
|
|
7
|
+
self.to_proc.call(*args)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Returns new lambda which composed self and given function.
|
|
12
|
+
# A composed proc called with args, executes `self.(g(*args)).
|
|
13
|
+
#
|
|
14
|
+
# f = lamdba{|x| x.to_s }
|
|
15
|
+
# g = lambda{|y| y.length }
|
|
16
|
+
# h = f compose g
|
|
17
|
+
# h.(:hoge) # => 4
|
|
18
|
+
#
|
|
19
|
+
# This method is aliased as `<<`.
|
|
20
|
+
#
|
|
21
|
+
# f << g # => f.compose(g)
|
|
22
|
+
#
|
|
23
|
+
def compose(g)
|
|
24
|
+
lambda{|*args| self.to_proc.call(g.to_proc.call(*args)) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# g compose self
|
|
28
|
+
def >>(g)
|
|
29
|
+
g.to_proc << self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns partially applied function that has 2nd and more parameters
|
|
33
|
+
# fixed by given *args.
|
|
34
|
+
#
|
|
35
|
+
# f = lamdba{|x, y, z| [x, y, z]}
|
|
36
|
+
# h = f.with_args(:a, :b)
|
|
37
|
+
# h.(:c) # => [:c, :a, :b]
|
|
38
|
+
#
|
|
39
|
+
# This method is aliased as `*`.
|
|
40
|
+
#
|
|
41
|
+
# f * :foo # => f.with_args(:foo)
|
|
42
|
+
#
|
|
43
|
+
def with_args(*args)
|
|
44
|
+
lambda{|v|
|
|
45
|
+
self.to_proc.call(*([v] + args))
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Returns function whose parameter order spawed 1st for 2nd.
|
|
50
|
+
# A result of filped fuction is curried by Proc#curry.
|
|
51
|
+
#
|
|
52
|
+
# f = lamdba{|x, y, z| [x, y, z]}
|
|
53
|
+
# h = f.flip
|
|
54
|
+
# h.(:a).(:b).(:c) # => [:b, :a, :c]
|
|
55
|
+
#
|
|
56
|
+
# If arguments is var-args, pass explicitly arity to curring.
|
|
57
|
+
#
|
|
58
|
+
# p = Proc.new{|*args| args.inspect }
|
|
59
|
+
# p.flip(3).call(:a).(:b).(:c) # => "[:b, :a, :c]"
|
|
60
|
+
# p.flip(4).call(:a).(:b).(:c).(:d) # => "[:b, :a, :c, :d]"
|
|
61
|
+
#
|
|
62
|
+
# If arity is 0 or 1, flip returns itself.
|
|
63
|
+
#
|
|
64
|
+
# This method is aliased as `~@`.
|
|
65
|
+
#
|
|
66
|
+
# ~f # => f.filp
|
|
67
|
+
#
|
|
68
|
+
def flip(arity = nil)
|
|
69
|
+
f = self.to_proc
|
|
70
|
+
return self if (0..1).include?(f.arity)
|
|
71
|
+
return self if f.arity == -1 && arity.nil?
|
|
72
|
+
|
|
73
|
+
curried = f.curry(arity)
|
|
74
|
+
lambda{|x|
|
|
75
|
+
lambda{|y|
|
|
76
|
+
g = curried[y]
|
|
77
|
+
(g.respond_to? :call) ? g[x] : g
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def curry(arity = nil)
|
|
83
|
+
self.to_proc.curry(arity)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.included(klass)
|
|
87
|
+
klass.send(:alias_method, :+@, :to_proc)
|
|
88
|
+
klass.send(:alias_method, :<, :call)
|
|
89
|
+
klass.send(:alias_method, :<<, :compose)
|
|
90
|
+
klass.send(:alias_method, :*, :with_args)
|
|
91
|
+
klass.send(:alias_method, :~@, :flip)
|
|
92
|
+
klass.send(:alias_method, :%, :curry)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module LambdaDriver::Currying
|
|
2
|
+
def curry
|
|
3
|
+
f = self.to_proc
|
|
4
|
+
arity = __arity(f)
|
|
5
|
+
return f if arity == 0
|
|
6
|
+
|
|
7
|
+
lambda{|arg| __curry(f, arity, arg, []) }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
def __arity(f)
|
|
12
|
+
(f.arity >= 0) ? f.arity : -(f.arity + 1)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def __curry(f, arity, arg, passed)
|
|
16
|
+
args = passed + [arg]
|
|
17
|
+
return f.call(*args) if arity == 1
|
|
18
|
+
lambda{|arg| __curry(f, arity - 1, arg, args) }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module LambdaDriver::Op
|
|
2
|
+
module Proxy
|
|
3
|
+
def _(method = nil)
|
|
4
|
+
method ? ::LambdaDriver::Op.method_or_lambda(self, method) : OpProxy.new(self)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def method_or_lambda(obj, method)
|
|
9
|
+
(obj.respond_to?(method) && obj.method(method)) ||
|
|
10
|
+
lambda{|*args| obj.__send__(method, *args) }
|
|
11
|
+
end
|
|
12
|
+
module_function :method_or_lambda
|
|
13
|
+
|
|
14
|
+
class BlankSlate
|
|
15
|
+
instance_methods.each { |m| undef_method m unless m =~ /^(__|object_id)/ }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class OpProxy < (RUBY_VERSION < '1.9.0' ? BlankSlate : BasicObject)
|
|
19
|
+
def initialize(obj)
|
|
20
|
+
@obj = obj
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def call(method)
|
|
24
|
+
::LambdaDriver::Op.method_or_lambda(@obj, method)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def method_missing(method)
|
|
28
|
+
::LambdaDriver::Op.method_or_lambda(@obj, method)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "lambda_driver/version"
|
|
2
|
+
|
|
3
|
+
Dir["#{File.dirname(__FILE__)}/lambda_driver/*.rb"].sort.each do |path|
|
|
4
|
+
next if File.basename(path, '.rb') == 'core_ext'
|
|
5
|
+
require "lambda_driver/#{File.basename(path, '.rb')}"
|
|
6
|
+
end
|
|
7
|
+
require "lambda_driver/core_ext"
|
|
8
|
+
|
|
9
|
+
module LambdaDriver
|
|
10
|
+
|
|
11
|
+
# SKI combinators
|
|
12
|
+
I = lambda{|x| x }
|
|
13
|
+
K = lambda{|x| lambda{|y| y }}
|
|
14
|
+
S = lambda{|x| lambda{|y| lambda{|z| x.to_proc.call(z).call(y.to_proc.call(z)) } } }
|
|
15
|
+
|
|
16
|
+
# Boolean combinators
|
|
17
|
+
AND = lambda{|l| lambda{|r| l && r }}
|
|
18
|
+
OR = lambda{|l| lambda{|r| l || r }}
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def i ; I end
|
|
22
|
+
def k ; K end
|
|
23
|
+
def s ; S end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
data/spec/ap_spec.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe LambdaDriver::Ap do
|
|
4
|
+
let(:object) { "foobarbaz" }
|
|
5
|
+
let(:f) { lambda{|x| x * 2 } }
|
|
6
|
+
|
|
7
|
+
describe '#ap'do
|
|
8
|
+
context 'given none' do
|
|
9
|
+
subject { object.ap }
|
|
10
|
+
|
|
11
|
+
it { should be_a_kind_of Proc }
|
|
12
|
+
it('obj.ap.call(f) should be f.call(obj)'){
|
|
13
|
+
subject.call(f).should == f.call(object)
|
|
14
|
+
}
|
|
15
|
+
it('obj.ap.call{block} should be result of execute block with obj'){
|
|
16
|
+
subject.call{|x| x * 3 }.should == (object * 3)
|
|
17
|
+
}
|
|
18
|
+
it('obj.ap.call(f){block} should be result of execute block with obj'){
|
|
19
|
+
subject.call(f){|x| x * 3 }.should == (object * 3)
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'block given' do
|
|
24
|
+
it('obj.ap{block} should be result of execute block with obj'){
|
|
25
|
+
object.ap{|x| x * 3 }.should == (object * 3)
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'proc object given' do
|
|
30
|
+
it('obj.ap(f) should be f.call(obj)'){
|
|
31
|
+
object.ap(f).should == f.call(object)
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'block given and proc object given' do
|
|
36
|
+
it('obj.ap.call(f){block} should be result of execute block with obj'){
|
|
37
|
+
object.ap(f){|x| x * 3 }.should == (object * 3)
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/spec/class_spec.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'class' do
|
|
4
|
+
describe './' do
|
|
5
|
+
subject { String / :index }
|
|
6
|
+
|
|
7
|
+
it { should be_a_kind_of UnboundMethod }
|
|
8
|
+
it("(klass / method_name).bind(obj).call(x) should be obj.method_name(x)"){
|
|
9
|
+
subject.bind("foobarbaz").call("bar") == "foobarbaz".index("bar")
|
|
10
|
+
}
|
|
11
|
+
end
|
|
12
|
+
end
|
data/spec/lambda_spec.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'lambda' do
|
|
4
|
+
describe '#compose' do
|
|
5
|
+
subject { lambda{|x| x.to_s} }
|
|
6
|
+
|
|
7
|
+
it_should_behave_like 'composable'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe '#with_args' do
|
|
11
|
+
subject { lambda{|x, y, *z| [x, y] + z.to_a } }
|
|
12
|
+
it_should_behave_like 'with_args'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe '#flip' do
|
|
16
|
+
context 'arity = 1' do
|
|
17
|
+
subject { lambda{|x| [x] } }
|
|
18
|
+
|
|
19
|
+
it_should_behave_like 'flip(arity=1)'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'arity > 1' do
|
|
23
|
+
subject { lambda{|x, y| [x, y] } }
|
|
24
|
+
|
|
25
|
+
it_should_behave_like 'flip'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'varargs' do
|
|
29
|
+
subject { lambda{|*x| x } }
|
|
30
|
+
|
|
31
|
+
it_should_behave_like 'flip(varargs)'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe '#curry' do
|
|
36
|
+
subject { lambda{|x, y| [x, y] } }
|
|
37
|
+
|
|
38
|
+
it_should_behave_like 'curry'
|
|
39
|
+
|
|
40
|
+
context 'varargs' do
|
|
41
|
+
subject { lambda{|*x| x } }
|
|
42
|
+
|
|
43
|
+
it_should_behave_like 'curry(varargs)'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe '#call' do
|
|
48
|
+
subject { lambda{|x| x.to_s + "_f"} }
|
|
49
|
+
|
|
50
|
+
it_should_behave_like 'call'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe 'ailases' do
|
|
54
|
+
subject { lambda{|x| x.to_s + "_f"} }
|
|
55
|
+
|
|
56
|
+
it_should_behave_like 'aliases'
|
|
57
|
+
it_should_behave_like 'aliases(varargs)' do
|
|
58
|
+
subject { lambda{|*x| x } }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/spec/method_spec.rb
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Method do
|
|
4
|
+
describe '#compose' do
|
|
5
|
+
subject { "aaa".method(:+) }
|
|
6
|
+
|
|
7
|
+
it_should_behave_like 'composable' do
|
|
8
|
+
let(:x) { "foo" }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe '#with_args' do
|
|
13
|
+
subject { "foobarbaz".method(:delete) }
|
|
14
|
+
|
|
15
|
+
it_should_behave_like 'with_args' do
|
|
16
|
+
let(:x) { 'r' }
|
|
17
|
+
let(:y) { 'o' }
|
|
18
|
+
let(:z) { 'a' }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '#flip' do
|
|
23
|
+
context 'arity = 1' do
|
|
24
|
+
subject { "aaa".method(:+) }
|
|
25
|
+
|
|
26
|
+
it_should_behave_like 'flip(arity=1)' do
|
|
27
|
+
let(:x) { "foo" }
|
|
28
|
+
let(:y) { "bar" }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'arity > 1' do
|
|
33
|
+
subject { "foobarbaz".method(:tr) }
|
|
34
|
+
|
|
35
|
+
it_should_behave_like 'flip' do
|
|
36
|
+
let(:x) { 'r' }
|
|
37
|
+
let(:y) { 'o' }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'varargs' do
|
|
42
|
+
subject { "foobarbaz".method(:delete) }
|
|
43
|
+
|
|
44
|
+
it_should_behave_like 'flip(varargs)' do
|
|
45
|
+
let(:x) { 'r' }
|
|
46
|
+
let(:y) { 'o' }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe '#curry' do
|
|
52
|
+
context 'arity > 1' do
|
|
53
|
+
subject { "foobarbaz".method(:tr) }
|
|
54
|
+
|
|
55
|
+
it_should_behave_like 'curry' do
|
|
56
|
+
let(:x) { 'r' }
|
|
57
|
+
let(:y) { 'o' }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context 'varargs' do
|
|
62
|
+
subject { "foobarbaz".method(:delete) }
|
|
63
|
+
|
|
64
|
+
it_should_behave_like 'curry(varargs)' do
|
|
65
|
+
let(:x) { 'r' }
|
|
66
|
+
let(:y) { 'o' }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe '#call' do
|
|
72
|
+
subject { "aaa".method(:+) }
|
|
73
|
+
|
|
74
|
+
it_should_behave_like 'call' do
|
|
75
|
+
let(:x) { "foo" }
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe 'ailases' do
|
|
80
|
+
it_should_behave_like 'aliases' do
|
|
81
|
+
subject { "aaa".method(:+) }
|
|
82
|
+
let(:x) { "foo" }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it_should_behave_like 'aliases(varargs)' do
|
|
86
|
+
subject { "foobarbaz".method(:delete) }
|
|
87
|
+
let(:x) { 'r' }
|
|
88
|
+
let(:y) { 'o' }
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
data/spec/op_spec.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
shared_examples_for 'method_or_lambda' do |label|
|
|
4
|
+
let(:method_name) { :+ }
|
|
5
|
+
context 'given method name (is reciever object responds)' do
|
|
6
|
+
subject { method }
|
|
7
|
+
|
|
8
|
+
it { should be_a_kind_of Method }
|
|
9
|
+
it("#{label}.call(args) should be obj.send(method_name, args)"){
|
|
10
|
+
subject.call('bar').should == object.send(method_name, 'bar')
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'given method name (is not reciever object responds)' do
|
|
15
|
+
subject { lambda_proc }
|
|
16
|
+
before {
|
|
17
|
+
def object.method_missing(method, *args)
|
|
18
|
+
method == :foo ? args : super(method, *args)
|
|
19
|
+
end
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
it { should be_a_kind_of Proc }
|
|
23
|
+
it("#{label}.call(args) should be obj.send(method_name, args)"){
|
|
24
|
+
lambda_proc.call('bar', 'baz').should == object.send(:foo, 'bar', 'baz')
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe LambdaDriver::Op do
|
|
30
|
+
describe '#_' do
|
|
31
|
+
let(:object) { "foobarbaz" }
|
|
32
|
+
|
|
33
|
+
context 'given nil' do
|
|
34
|
+
subject { object._ }
|
|
35
|
+
|
|
36
|
+
it { subject.class.should be_a_kind_of LambdaDriver::Op::Proxy }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it_should_behave_like 'method_or_lambda', 'obj._(method_name)' do
|
|
40
|
+
let(:method){ object._(:+) }
|
|
41
|
+
let(:lambda_proc){ object._(:foo) }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe LambdaDriver::Op::Proxy do
|
|
47
|
+
let(:object) { "foobarbaz" }
|
|
48
|
+
|
|
49
|
+
describe '#call' do
|
|
50
|
+
it_should_behave_like 'method_or_lambda', 'obj._(method_name)' do
|
|
51
|
+
let(:method){ object._.call(:+) }
|
|
52
|
+
let(:lambda_proc){ object._.call(:foo) }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe '#method_missing' do
|
|
57
|
+
it_should_behave_like 'method_or_lambda', 'obj._.method_name' do
|
|
58
|
+
let(:method){ object._.index }
|
|
59
|
+
let(:method_name) { :index }
|
|
60
|
+
let(:lambda_proc){ object._.foo }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/spec/proc_spec.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Proc do
|
|
4
|
+
describe '#compose' do
|
|
5
|
+
subject { Proc.new{|x| x.to_s} }
|
|
6
|
+
|
|
7
|
+
it_should_behave_like 'composable'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe '#with_args' do
|
|
11
|
+
subject { Proc.new{|x, y, *z| [x, y] + z.to_a } }
|
|
12
|
+
it_should_behave_like 'with_args'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe '#flip' do
|
|
16
|
+
context 'arity = 1' do
|
|
17
|
+
subject { Proc.new{|x| [x] } }
|
|
18
|
+
|
|
19
|
+
it_should_behave_like 'flip(arity=1)'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'arity > 1' do
|
|
23
|
+
subject { Proc.new{|x, y| [x, y] } }
|
|
24
|
+
|
|
25
|
+
it_should_behave_like 'flip'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'varargs' do
|
|
29
|
+
subject { Proc.new{|*x| x } }
|
|
30
|
+
|
|
31
|
+
it_should_behave_like 'flip(varargs)'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe '#curry' do
|
|
36
|
+
subject { Proc.new{|x, y| [x, y] } }
|
|
37
|
+
|
|
38
|
+
it_should_behave_like 'curry'
|
|
39
|
+
|
|
40
|
+
context 'varargs' do
|
|
41
|
+
subject { Proc.new{|*x| x } }
|
|
42
|
+
|
|
43
|
+
it_should_behave_like 'curry(varargs)'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe '#call' do
|
|
48
|
+
subject { Proc.new{|x| x.to_s + "_f"} }
|
|
49
|
+
|
|
50
|
+
it_should_behave_like 'call'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe 'ailases' do
|
|
54
|
+
subject { Proc.new{|x| x.to_s + "_f"} }
|
|
55
|
+
|
|
56
|
+
it_should_behave_like 'aliases'
|
|
57
|
+
it_should_behave_like 'aliases(varargs)' do
|
|
58
|
+
subject { Proc.new{|*x| x } }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
shared_examples_for 'composable' do
|
|
4
|
+
it { should respond_to :to_proc}
|
|
5
|
+
it { should respond_to :>> }
|
|
6
|
+
it { should respond_to :<< }
|
|
7
|
+
it { should respond_to :compose }
|
|
8
|
+
|
|
9
|
+
let(:x) { :foo }
|
|
10
|
+
let(:y) { 12 }
|
|
11
|
+
let(:g) { lambda{|x| (x.to_s * 2) + "_g" } }
|
|
12
|
+
|
|
13
|
+
it('" f >> g" returns g(f)'){
|
|
14
|
+
(subject >> g).should be_a_kind_of Proc
|
|
15
|
+
}
|
|
16
|
+
it('"(f >> g).call(x)" should be g(f(x))'){
|
|
17
|
+
(subject >> g).call(x).should == g.call(subject.to_proc.call(x))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
it('" f << g" returns g(f)'){
|
|
21
|
+
(subject << g).should be_a_kind_of Proc
|
|
22
|
+
}
|
|
23
|
+
it('"(f << g).call(x)" should be f(g(x))'){
|
|
24
|
+
(subject << g).call(y).should == subject.to_proc.call(g.call(y)) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
shared_examples_for 'with_args' do
|
|
28
|
+
it { should respond_to :with_args }
|
|
29
|
+
it { should respond_to :*}
|
|
30
|
+
|
|
31
|
+
let(:x) { :foo }
|
|
32
|
+
let(:y) { :bar }
|
|
33
|
+
let(:z) { :baz }
|
|
34
|
+
|
|
35
|
+
it('" f.with_args(x) returns proc which is partaily appied arguments'){
|
|
36
|
+
subject.with_args(y).should be_a_kind_of Proc
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
it('" f.with_args(y).call(x)" should be f(x, y)'){
|
|
40
|
+
puts x.inspect
|
|
41
|
+
subject.with_args(y).call(x).should == subject.to_proc.call(x, y)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
it('" f.with_args(*args).call(x)" should be f(x, *args)'){
|
|
45
|
+
subject.with_args(y, z).call(x).should == subject.to_proc.call(x, y, z)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
it('" f * x returns proc which is partaily appied arguments'){
|
|
49
|
+
(subject * y).should be_a_kind_of Proc
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
it('" (f * y).call(x)" should be f(x, y)'){
|
|
53
|
+
(subject * y).call(x).should == subject.to_proc.call(x, y)
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
shared_examples_for 'flip' do
|
|
58
|
+
it { should respond_to :flip }
|
|
59
|
+
it { should respond_to :~}
|
|
60
|
+
|
|
61
|
+
let(:x) { :foo }
|
|
62
|
+
let(:y) { :bar }
|
|
63
|
+
|
|
64
|
+
it(' f.flip returns function whose parameter order swaped 1st for 2nd.'){
|
|
65
|
+
subject.flip.should be_a_kind_of Proc
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
it(' f.flip.call(x) returns proc ') {
|
|
69
|
+
subject.flip.call(y).should be_a_kind_of Proc
|
|
70
|
+
}
|
|
71
|
+
it(' f.flip.call(x).call(y) should be (y,x)'){
|
|
72
|
+
subject.flip.call(y).call(x).should == subject.to_proc.call(x, y)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
it(' ~f returns function whose parameter order swaped 1st for 2nd.'){
|
|
76
|
+
(~subject).should be_a_kind_of Proc
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
it(' ~f.call(x) returns proc ') {
|
|
80
|
+
(~subject).call(y).should be_a_kind_of Proc
|
|
81
|
+
}
|
|
82
|
+
it(' ~f.call(x).call(y) should be (y,x)'){
|
|
83
|
+
(~subject).call(y).call(x).should == subject.to_proc.call(x, y)
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
shared_examples_for 'flip(arity=1)' do
|
|
88
|
+
let(:x) { :foo }
|
|
89
|
+
let(:y) { :bar }
|
|
90
|
+
|
|
91
|
+
it(' f.flip returns itself'){
|
|
92
|
+
subject.flip.should == subject
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
it(' f.flip.call(x) returns proc ') {
|
|
96
|
+
subject.flip.call(y) == subject.call(y)
|
|
97
|
+
}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
shared_examples_for 'flip(varargs)' do
|
|
101
|
+
let(:x) { :foo }
|
|
102
|
+
let(:y) { :bar }
|
|
103
|
+
|
|
104
|
+
it('f.flip returns itself'){
|
|
105
|
+
subject.flip.should == subject
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
it('f.flip(2).call(x) returns proc ') {
|
|
109
|
+
subject.flip(2).call(y) == subject.call(y)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
it('~f.flip(2).call(x).call(y) should be f.call(y,x)'){
|
|
113
|
+
subject.flip(2).call(y).call(x).should == subject.to_proc.call(x, y)
|
|
114
|
+
}
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
shared_examples_for 'curry' do
|
|
118
|
+
it { should respond_to :curry}
|
|
119
|
+
it { should respond_to :%}
|
|
120
|
+
|
|
121
|
+
let(:x) { :foo }
|
|
122
|
+
let(:y) { :bar }
|
|
123
|
+
|
|
124
|
+
it('f.curry returns curried function'){
|
|
125
|
+
subject.curry.should be_a_kind_of Proc
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
it('f.curry.call(x) returns proc ') {
|
|
129
|
+
subject.curry.call(y).should be_a_kind_of Proc
|
|
130
|
+
}
|
|
131
|
+
it('f.curry.call(x).call(y) should be f.call(x,y)'){
|
|
132
|
+
subject.curry.call(x).call(y).should == subject.to_proc.call(x, y)
|
|
133
|
+
}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
shared_examples_for 'curry(varargs)' do
|
|
137
|
+
let(:x) { :foo }
|
|
138
|
+
let(:y) { :bar }
|
|
139
|
+
|
|
140
|
+
it('f % 2 returns curried function'){
|
|
141
|
+
(subject % 2).should be_a_kind_of Proc
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
it('(f % 2).call(x) returns proc ') {
|
|
145
|
+
(subject % 2).call(y).should be_a_kind_of Proc
|
|
146
|
+
}
|
|
147
|
+
it('(f % 2).call(x).call(y) should be f.call(x,y)'){
|
|
148
|
+
(subject % 2).call(x).call(y).should == subject.to_proc.call(x, y)
|
|
149
|
+
}
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
shared_examples_for 'call' do
|
|
153
|
+
it { should respond_to :call}
|
|
154
|
+
it { should respond_to :<}
|
|
155
|
+
|
|
156
|
+
let(:x) { :foo }
|
|
157
|
+
|
|
158
|
+
it('f.call(x) == f.call(x)'){
|
|
159
|
+
subject.call(x).should == subject.call(x)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
it('(f < x) == f.call(x)'){
|
|
163
|
+
(subject < x).should == subject.call(x)
|
|
164
|
+
}
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
shared_examples_for 'aliases' do
|
|
168
|
+
let(:x) { :foo }
|
|
169
|
+
let(:y) { 12 }
|
|
170
|
+
let(:g) { lambda{|x| (x.to_s * 2).to_s + "_g" } }
|
|
171
|
+
|
|
172
|
+
it('(~f < x) should be f.flip.call(x)'){
|
|
173
|
+
(~subject < x).should == subject.flip.call(x)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
it('(f << g < x) should f.compose(g).call(x)'){
|
|
177
|
+
(subject << g < x).should == subject.compose(g).call(x)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
it('(f >> g < x) should g.compose(f).call(x)'){
|
|
181
|
+
(subject >> g < x).should == g.compose(subject).call(x)
|
|
182
|
+
}
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
shared_examples_for 'aliases(varargs)' do
|
|
186
|
+
let(:x) { :foo }
|
|
187
|
+
let(:y) { 12 }
|
|
188
|
+
let(:g) { lambda{|x| (x.to_s * 2).to_s + "_g" } }
|
|
189
|
+
|
|
190
|
+
it('(f % 2 * y << g < x) should be f.curry(2).with_args(y).compose(g).call(x)'){
|
|
191
|
+
(subject % 2 * y << g < x).should == subject.curry(2).with_args(y).compose(g).call(x)
|
|
192
|
+
}
|
|
193
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
|
4
|
+
# loaded once.
|
|
5
|
+
#
|
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
|
7
|
+
#
|
|
8
|
+
require 'rspec'
|
|
9
|
+
require 'lambda_driver'
|
|
10
|
+
|
|
11
|
+
Dir["#{File.dirname(__FILE__)}/shared/**/*.rb"].each {|f| require f}
|
|
12
|
+
|
|
13
|
+
RSpec.configure do |config|
|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
15
|
+
config.run_all_when_everything_filtered = true
|
|
16
|
+
config.filter_run :focus
|
|
17
|
+
end
|
data/spec/symbol_spec.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Symbol do
|
|
4
|
+
describe '#compose' do
|
|
5
|
+
subject { :to_s }
|
|
6
|
+
|
|
7
|
+
it_should_behave_like 'composable'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe '#with_args' do
|
|
11
|
+
subject {:delete }
|
|
12
|
+
|
|
13
|
+
it_should_behave_like 'with_args' do
|
|
14
|
+
let(:x) { 'foobar' }
|
|
15
|
+
let(:y) { 'o' }
|
|
16
|
+
let(:z) { 'a'}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#flip' do
|
|
21
|
+
context 'arity = 1' do
|
|
22
|
+
subject { :to_s }
|
|
23
|
+
|
|
24
|
+
it_should_behave_like 'flip(arity=1)'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'varargs' do
|
|
28
|
+
subject {:product }
|
|
29
|
+
|
|
30
|
+
it_should_behave_like 'flip(varargs)' do
|
|
31
|
+
let(:x) { [:bar] }
|
|
32
|
+
let(:y) { [:foo] }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '#curry' do
|
|
38
|
+
subject { :product }
|
|
39
|
+
|
|
40
|
+
it_should_behave_like 'curry(varargs)' do
|
|
41
|
+
let(:x) { [:bar] }
|
|
42
|
+
let(:y) { [:foo] }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe '#call' do
|
|
47
|
+
subject { :to_s }
|
|
48
|
+
|
|
49
|
+
it_should_behave_like 'call'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe 'ailases' do
|
|
53
|
+
subject { :to_s }
|
|
54
|
+
|
|
55
|
+
it_should_behave_like 'aliases'
|
|
56
|
+
|
|
57
|
+
it_should_behave_like 'aliases(varargs)' do
|
|
58
|
+
subject { :product }
|
|
59
|
+
let(:x) { [:bar] }
|
|
60
|
+
let(:y) { [:foo] }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe UnboundMethod do
|
|
4
|
+
describe '#<' do
|
|
5
|
+
let(:unbound_method){ String.instance_method(:index) }
|
|
6
|
+
subject { unbound_method < "foobarbaz" }
|
|
7
|
+
|
|
8
|
+
it { should be_a_kind_of Method }
|
|
9
|
+
it('(unbound_method < obj).call(x) should be unbound_method.bind(obj).call(x)'){
|
|
10
|
+
subject.call('bar').should == unbound_method.bind("foobarbaz").call("bar")
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lambda_driver
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Tomohito Ozaki
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-03-26 00:00:00.000000000Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: rspec
|
|
16
|
+
requirement: &70364479275960 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *70364479275960
|
|
25
|
+
description: Drives your code more functioal!
|
|
26
|
+
email:
|
|
27
|
+
- ozaki@yuroyoro.com
|
|
28
|
+
executables: []
|
|
29
|
+
extensions: []
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
files:
|
|
32
|
+
- .gitignore
|
|
33
|
+
- .rspec
|
|
34
|
+
- Gemfile
|
|
35
|
+
- LICENSE.txt
|
|
36
|
+
- README.md
|
|
37
|
+
- Rakefile
|
|
38
|
+
- lambda_driver.gemspec
|
|
39
|
+
- lib/lambda_driver.rb
|
|
40
|
+
- lib/lambda_driver/ap.rb
|
|
41
|
+
- lib/lambda_driver/callable.rb
|
|
42
|
+
- lib/lambda_driver/core_ext.rb
|
|
43
|
+
- lib/lambda_driver/core_ext/class.rb
|
|
44
|
+
- lib/lambda_driver/core_ext/method.rb
|
|
45
|
+
- lib/lambda_driver/core_ext/object.rb
|
|
46
|
+
- lib/lambda_driver/core_ext/proc.rb
|
|
47
|
+
- lib/lambda_driver/core_ext/symbol.rb
|
|
48
|
+
- lib/lambda_driver/core_ext/unbound_method.rb
|
|
49
|
+
- lib/lambda_driver/currying.rb
|
|
50
|
+
- lib/lambda_driver/op.rb
|
|
51
|
+
- lib/lambda_driver/version.rb
|
|
52
|
+
- spec/ap_spec.rb
|
|
53
|
+
- spec/class_spec.rb
|
|
54
|
+
- spec/lambda_spec.rb
|
|
55
|
+
- spec/method_spec.rb
|
|
56
|
+
- spec/op_spec.rb
|
|
57
|
+
- spec/proc_spec.rb
|
|
58
|
+
- spec/shared/composable_spec.rb
|
|
59
|
+
- spec/spec_helper.rb
|
|
60
|
+
- spec/symbol_spec.rb
|
|
61
|
+
- spec/unbound_method_spec.rb
|
|
62
|
+
homepage: ''
|
|
63
|
+
licenses: []
|
|
64
|
+
post_install_message:
|
|
65
|
+
rdoc_options: []
|
|
66
|
+
require_paths:
|
|
67
|
+
- lib
|
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
|
+
none: false
|
|
70
|
+
requirements:
|
|
71
|
+
- - ! '>='
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
none: false
|
|
76
|
+
requirements:
|
|
77
|
+
- - ! '>='
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
requirements: []
|
|
81
|
+
rubyforge_project:
|
|
82
|
+
rubygems_version: 1.8.10
|
|
83
|
+
signing_key:
|
|
84
|
+
specification_version: 3
|
|
85
|
+
summary: Drives your code more functioal!
|
|
86
|
+
test_files:
|
|
87
|
+
- spec/ap_spec.rb
|
|
88
|
+
- spec/class_spec.rb
|
|
89
|
+
- spec/lambda_spec.rb
|
|
90
|
+
- spec/method_spec.rb
|
|
91
|
+
- spec/op_spec.rb
|
|
92
|
+
- spec/proc_spec.rb
|
|
93
|
+
- spec/shared/composable_spec.rb
|
|
94
|
+
- spec/spec_helper.rb
|
|
95
|
+
- spec/symbol_spec.rb
|
|
96
|
+
- spec/unbound_method_spec.rb
|