totally_lazy 0.0.20 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/compiler.xml +22 -0
- data/.idea/encodings.xml +6 -0
- data/.idea/misc.xml +19 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.travis.yml +2 -5
- data/Gemfile +6 -8
- data/Guardfile +2 -17
- data/LICENSE +202 -0
- data/Rakefile +18 -33
- data/VERSION +1 -1
- data/contributors.txt +1 -0
- data/lib/comparators.rb +9 -0
- data/lib/enumerators.rb +74 -0
- data/lib/functions.rb +66 -0
- data/lib/numbers.rb +38 -0
- data/lib/option.rb +38 -268
- data/lib/pair.rb +13 -51
- data/lib/predicates.rb +5 -0
- data/lib/sequence.rb +171 -526
- data/lib/strings.rb +13 -0
- data/lib/totally_lazy.rb +14 -165
- data/readme.md +2 -0
- data/spec/option_spec.rb +6 -182
- data/spec/sequence_spec.rb +202 -132
- data/spec/spec_helper.rb +0 -13
- data/totally_lazy.iml +74 -0
- metadata +58 -71
- data/.document +0 -5
- data/.rspec +0 -1
- data/LICENSE.txt +0 -20
- data/README.md +0 -173
- data/lib/any.rb +0 -13
- data/lib/functor.rb +0 -92
- data/lib/generators.rb +0 -161
- data/lib/parallel/parallel.rb +0 -442
- data/lib/parallel/processor_count.rb +0 -85
- data/lib/predicates/compare.rb +0 -25
- data/lib/predicates/conversions.rb +0 -22
- data/lib/predicates/numbers.rb +0 -21
- data/lib/predicates/predicates.rb +0 -141
- data/lib/predicates/where.rb +0 -34
- data/lib/predicates/where_processor.rb +0 -13
- data/lib/type_check.rb +0 -19
- data/lib/utils.rb +0 -9
- data/spec/functor_spec.rb +0 -35
- data/spec/generators_spec.rb +0 -37
- data/spec/pair_spec.rb +0 -44
- data/spec/predicate_spec.rb +0 -77
- data/spec/serialization_spec.rb +0 -56
- data/spec/type_check_spec.rb +0 -20
- data/spec/util_spec.rb +0 -10
- data/totally_lazy.gemspec +0 -101
metadata
CHANGED
@@ -1,43 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: totally_lazy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Raymond Barlow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 3.0.0
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
17
|
+
- - ">="
|
25
18
|
- !ruby/object:Gem::Version
|
26
19
|
version: 3.0.0
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rdoc
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
20
|
- - "~>"
|
32
21
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3.
|
22
|
+
version: '3.0'
|
34
23
|
type: :development
|
35
24
|
prerelease: false
|
36
25
|
version_requirements: !ruby/object:Gem::Requirement
|
37
26
|
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.0.0
|
38
30
|
- - "~>"
|
39
31
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3.
|
32
|
+
version: '3.0'
|
41
33
|
- !ruby/object:Gem::Dependency
|
42
34
|
name: bundler
|
43
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,16 +48,22 @@ dependencies:
|
|
56
48
|
name: jeweler
|
57
49
|
requirement: !ruby/object:Gem::Requirement
|
58
50
|
requirements:
|
59
|
-
- - "
|
51
|
+
- - ">="
|
60
52
|
- !ruby/object:Gem::Version
|
61
53
|
version: 2.0.1
|
54
|
+
- - "~>"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '2.0'
|
62
57
|
type: :development
|
63
58
|
prerelease: false
|
64
59
|
version_requirements: !ruby/object:Gem::Requirement
|
65
60
|
requirements:
|
66
|
-
- - "
|
61
|
+
- - ">="
|
67
62
|
- !ruby/object:Gem::Version
|
68
63
|
version: 2.0.1
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '2.0'
|
69
67
|
- !ruby/object:Gem::Dependency
|
70
68
|
name: rspec_html_formatter
|
71
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,106 +82,95 @@ dependencies:
|
|
84
82
|
name: rake
|
85
83
|
requirement: !ruby/object:Gem::Requirement
|
86
84
|
requirements:
|
87
|
-
- - "
|
85
|
+
- - ">="
|
88
86
|
- !ruby/object:Gem::Version
|
89
87
|
version: 10.3.2
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
88
|
- - "~>"
|
95
89
|
- !ruby/object:Gem::Version
|
96
|
-
version: 10.3
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: simplecov
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
90
|
+
version: '10.3'
|
104
91
|
type: :development
|
105
92
|
prerelease: false
|
106
93
|
version_requirements: !ruby/object:Gem::Requirement
|
107
94
|
requirements:
|
108
95
|
- - ">="
|
109
96
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
97
|
+
version: 10.3.2
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '10.3'
|
111
101
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
102
|
+
name: guard-rspec
|
113
103
|
requirement: !ruby/object:Gem::Requirement
|
114
104
|
requirements:
|
115
105
|
- - ">="
|
116
106
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
107
|
+
version: 4.6.4
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '4.6'
|
118
111
|
type: :development
|
119
112
|
prerelease: false
|
120
113
|
version_requirements: !ruby/object:Gem::Requirement
|
121
114
|
requirements:
|
122
115
|
- - ">="
|
123
116
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
117
|
+
version: 4.6.4
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '4.6'
|
125
121
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
122
|
+
name: concurrent-ruby-edge
|
127
123
|
requirement: !ruby/object:Gem::Requirement
|
128
124
|
requirements:
|
129
|
-
- - "
|
125
|
+
- - "~>"
|
130
126
|
- !ruby/object:Gem::Version
|
131
127
|
version: '0'
|
132
128
|
type: :development
|
133
129
|
prerelease: false
|
134
130
|
version_requirements: !ruby/object:Gem::Requirement
|
135
131
|
requirements:
|
136
|
-
- - "
|
132
|
+
- - "~>"
|
137
133
|
- !ruby/object:Gem::Version
|
138
134
|
version: '0'
|
139
135
|
description: Port of java functional library totally lazy to ruby
|
140
|
-
email:
|
136
|
+
email: rbarlow@raymanoz.com
|
141
137
|
executables: []
|
142
138
|
extensions: []
|
143
139
|
extra_rdoc_files:
|
144
|
-
- LICENSE
|
145
|
-
- README.md
|
140
|
+
- LICENSE
|
146
141
|
files:
|
147
|
-
- ".
|
148
|
-
- ".
|
142
|
+
- ".idea/.name"
|
143
|
+
- ".idea/.rakeTasks"
|
144
|
+
- ".idea/compiler.xml"
|
145
|
+
- ".idea/encodings.xml"
|
146
|
+
- ".idea/misc.xml"
|
147
|
+
- ".idea/modules.xml"
|
148
|
+
- ".idea/vcs.xml"
|
149
149
|
- ".travis.yml"
|
150
150
|
- Gemfile
|
151
151
|
- Guardfile
|
152
|
-
- LICENSE
|
153
|
-
- README.md
|
152
|
+
- LICENSE
|
154
153
|
- Rakefile
|
155
154
|
- VERSION
|
156
|
-
-
|
157
|
-
- lib/
|
158
|
-
- lib/
|
155
|
+
- contributors.txt
|
156
|
+
- lib/comparators.rb
|
157
|
+
- lib/enumerators.rb
|
158
|
+
- lib/functions.rb
|
159
|
+
- lib/numbers.rb
|
159
160
|
- lib/option.rb
|
160
161
|
- lib/pair.rb
|
161
|
-
- lib/
|
162
|
-
- lib/parallel/processor_count.rb
|
163
|
-
- lib/predicates/compare.rb
|
164
|
-
- lib/predicates/conversions.rb
|
165
|
-
- lib/predicates/numbers.rb
|
166
|
-
- lib/predicates/predicates.rb
|
167
|
-
- lib/predicates/where.rb
|
168
|
-
- lib/predicates/where_processor.rb
|
162
|
+
- lib/predicates.rb
|
169
163
|
- lib/sequence.rb
|
164
|
+
- lib/strings.rb
|
170
165
|
- lib/totally_lazy.rb
|
171
|
-
-
|
172
|
-
- lib/utils.rb
|
173
|
-
- spec/functor_spec.rb
|
174
|
-
- spec/generators_spec.rb
|
166
|
+
- readme.md
|
175
167
|
- spec/option_spec.rb
|
176
|
-
- spec/pair_spec.rb
|
177
|
-
- spec/predicate_spec.rb
|
178
168
|
- spec/sequence_spec.rb
|
179
|
-
- spec/serialization_spec.rb
|
180
169
|
- spec/spec_helper.rb
|
181
|
-
-
|
182
|
-
|
183
|
-
- totally_lazy.gemspec
|
184
|
-
homepage: http://github.com/kingsleyh/totally_lazy
|
170
|
+
- totally_lazy.iml
|
171
|
+
homepage: http://github.com/raymanoz/totally_lazy
|
185
172
|
licenses:
|
186
|
-
-
|
173
|
+
- Apache 2.0
|
187
174
|
metadata: {}
|
188
175
|
post_install_message:
|
189
176
|
rdoc_options: []
|
@@ -201,8 +188,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
188
|
version: '0'
|
202
189
|
requirements: []
|
203
190
|
rubyforge_project:
|
204
|
-
rubygems_version: 2.4.
|
191
|
+
rubygems_version: 2.4.6
|
205
192
|
signing_key:
|
206
193
|
specification_version: 4
|
207
|
-
summary:
|
194
|
+
summary: A lazy FP library for Ruby
|
208
195
|
test_files: []
|
data/.document
DELETED
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|
data/LICENSE.txt
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright (c) 2014 Kingsley Hendrickse
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
# PLEASE NOTE - This project is not being actively maintained at the moment - I am taking a break - not sure when I will return.
|
2
|
-
|
3
|
-
# Totally Lazy for Ruby
|
4
|
-
|
5
|
-
This is a port of the java functional library [Totally Lazy](https://code.google.com/p/totallylazy/) to the ruby language. I've tried to get it as close as I can to the original concepts behind the java version of Totally Lazy but I'm still pretty far away from being happy with it.
|
6
|
-
|
7
|
-
### Status
|
8
|
-
|
9
|
-
[![Build Status](https://travis-ci.org/kingsleyh/totally_lazy.svg?branch=master)](https://travis-ci.org/kingsleyh/totally_lazy)
|
10
|
-
[![Gem Version](https://badge.fury.io/rb/totally_lazy.svg)](http://badge.fury.io/rb/totally_lazy)
|
11
|
-
[![Stories in Ready](https://badge.waffle.io/kingsleyh/totally_lazy.svg?label=ready&title=Ready)](http://waffle.io/kingsleyh/totally_lazy)
|
12
|
-
[![Coverage Status](https://coveralls.io/repos/kingsleyh/totally_lazy/badge.png?branch=master)](https://coveralls.io/r/kingsleyh/totally_lazy?branch=master)
|
13
|
-
[![Inline docs](http://inch-ci.org/github/kingsleyh/totally_lazy.png?branch=master)](http://inch-ci.org/github/kingsleyh/totally_lazy)
|
14
|
-
### Summary
|
15
|
-
|
16
|
-
* Tries to be as lazy as possible
|
17
|
-
* Supports method chaining
|
18
|
-
* Is primarily based on ruby Enumerators
|
19
|
-
|
20
|
-
### Install
|
21
|
-
|
22
|
-
This gem requires ruby 2.x.x
|
23
|
-
|
24
|
-
In your bundler Gemfile
|
25
|
-
|
26
|
-
```ruby
|
27
|
-
gem totally_lazy, '~>0.0.6'
|
28
|
-
```
|
29
|
-
|
30
|
-
Or with rubygems
|
31
|
-
|
32
|
-
```
|
33
|
-
gem install totally_lazy
|
34
|
-
```
|
35
|
-
|
36
|
-
### Examples
|
37
|
-
|
38
|
-
The following are some simple examples of the currently implemented functionality.
|
39
|
-
|
40
|
-
```ruby
|
41
|
-
require 'totally_lazy'
|
42
|
-
|
43
|
-
sequence(1,2,3,4).filter(even) # lazily returns 2,4
|
44
|
-
sequence(1,2).map(as_string) # lazily returns "1","2"
|
45
|
-
sequence(1, 2).map_concurrently(to_string) # lazily distributes the work to background threads
|
46
|
-
sequence(1,2,3).take(2) # lazily returns 1,2
|
47
|
-
sequence(1,2,3).drop(2) # lazily returns 3
|
48
|
-
sequence(1,2,3).tail # lazily returns 2,3
|
49
|
-
sequence(1,2,3).head # eagerly returns 1
|
50
|
-
sequence(1,2,3).head_option # eagerly returns an option
|
51
|
-
some(sequence(1,2,3)).get_or_else(empty) # eagerly returns value or else empty sequence
|
52
|
-
sequence(1, 2, 3, 4, 5).filter(where(is greater_than 2).and(is odd)) # lazily returns 3,5
|
53
|
-
sequence(pair(1, 2), pair(3, 4)).filter(where(key:odd)) # lazily returns 1,3
|
54
|
-
```
|
55
|
-
|
56
|
-
#### Sequences
|
57
|
-
|
58
|
-
* sequence wraps whatever is passed without modification - e.g. sequence([1,2,3]).head returns the array [1,2,3]
|
59
|
-
* if you have a single array you can [1,2,3].to_seq which returns a flattened sequence - e.g. [1,2,3].to_seq.head returns 1
|
60
|
-
* you can also do sequence([1,2,3]).flatten to get sequence([1,2,3]).flatten.head returns 1
|
61
|
-
|
62
|
-
#### Generators
|
63
|
-
|
64
|
-
There are 2 types of generators:
|
65
|
-
|
66
|
-
* Seq - returns a sequence
|
67
|
-
* Iter - returns a regular ruby enumerator
|
68
|
-
|
69
|
-
```ruby
|
70
|
-
Seq.range(1, 4) # lazily returns 1,2,3,4
|
71
|
-
Seq.repeat("car") # lazily returns an infinite sequence of "car"s
|
72
|
-
Seq.iterate(:+, 1) # lazily returns 1,2,3 ... to infinity
|
73
|
-
Seq.range(1, 4).cycle # lazily returns 1,2,3,4,1,2,3,4,1,2,3,4 infinitely
|
74
|
-
Seq.primes # lazily returns every prime number
|
75
|
-
Seq.fibonacci # lazily returns the fibonacci sequence
|
76
|
-
Seq.powers_of(3) # lazily returns the powers of 3 (i.e 1,3,9,27 ...)
|
77
|
-
|
78
|
-
Iter.range(1,4) # example with Iter: lazily returns 1,2,3,4 with a regular ruby enumerator
|
79
|
-
```
|
80
|
-
|
81
|
-
Naturally you can combine these operations together:
|
82
|
-
|
83
|
-
```ruby
|
84
|
-
option(1).join(sequence(2,3,4)).join(sequence(5,6)).filter(odd).take(2) # lazily returns 1,3
|
85
|
-
|
86
|
-
Seq.iterate(:+, 1).filter(even).take(2).reduce(:+) # returns 6
|
87
|
-
```
|
88
|
-
|
89
|
-
### Predicates
|
90
|
-
|
91
|
-
You can supply basic predicates as follows:
|
92
|
-
|
93
|
-
##### numbers
|
94
|
-
|
95
|
-
sequence(1,2,3).filter(even) # returns 2
|
96
|
-
|
97
|
-
##### conversions
|
98
|
-
|
99
|
-
sequence(1,2,3).map(as_string) # returns ["1","2","3"]
|
100
|
-
|
101
|
-
##### comparisons
|
102
|
-
|
103
|
-
sequence(1,2,3).filter(equals(2) # return 2
|
104
|
-
|
105
|
-
##### where - for self or objects
|
106
|
-
|
107
|
-
**using self**
|
108
|
-
|
109
|
-
When the predicate applies to an item in the sequence you use the **is** keyword with *where* to indicate the operation is on *self*
|
110
|
-
|
111
|
-
sequence(1,2,3).filter(where is greater_than 2)
|
112
|
-
|
113
|
-
**using objects**
|
114
|
-
|
115
|
-
When the predicate applies to a method on an object in the sequence then you supply hashmap of method_name:predicate (without using *is*)
|
116
|
-
|
117
|
-
sequence(pair(1,2),pair(3,4)).filter(where key:greater_than(3))
|
118
|
-
|
119
|
-
(pair has methods key and value)
|
120
|
-
|
121
|
-
##### Regex
|
122
|
-
|
123
|
-
You can use a regex predicate
|
124
|
-
|
125
|
-
sequence("apple","pear").filter(matches(/app/))
|
126
|
-
sequence(pair("apple",1),pair("pear",2)).filter(where(key:matches(/app/)))
|
127
|
-
|
128
|
-
#### Custom Transformer
|
129
|
-
|
130
|
-
There is a built in helper for a simple transform
|
131
|
-
|
132
|
-
* simple_transform
|
133
|
-
|
134
|
-
##### simple_transform
|
135
|
-
|
136
|
-
For example:
|
137
|
-
|
138
|
-
def as_uppercase
|
139
|
-
simple_transform(:as_uppercase, -> (v) { v.upcase })
|
140
|
-
end
|
141
|
-
|
142
|
-
sequence("apple","pear").map(as_uppercase) # returns ["APPLE","PEAR"]
|
143
|
-
|
144
|
-
|
145
|
-
#### Custom Predicates
|
146
|
-
|
147
|
-
Writing a custom predicate is very easy and there are 3 built in helpers:
|
148
|
-
|
149
|
-
* value predicate
|
150
|
-
* self predicate
|
151
|
-
|
152
|
-
##### value_predicate
|
153
|
-
|
154
|
-
For example:
|
155
|
-
|
156
|
-
def greater_than_or_equal_to(value)
|
157
|
-
value_predicate(:greater_than_or_equal_to,:>=,value)
|
158
|
-
end
|
159
|
-
|
160
|
-
sequence(1,2,3).filter(greater_than_or_equal_to 2)
|
161
|
-
sequence(1,2,3).filter(where is greater_than_or_equal_to 2)
|
162
|
-
|
163
|
-
##### self_predicate
|
164
|
-
|
165
|
-
For example:
|
166
|
-
|
167
|
-
def is_valid
|
168
|
-
self_predicate(:is_valid, :is_valid)
|
169
|
-
end
|
170
|
-
|
171
|
-
sequence(OpenStruct.new(is_valid:true,name:'apple'),OpenStruct.new(is_valid:false,name:'pear')).filter(is_valid).to_a
|
172
|
-
=> [#<OpenStruct is_valid=true, name="apple">]
|
173
|
-
|
data/lib/any.rb
DELETED
data/lib/functor.rb
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
# Functor is Ruby's implementation of a Higher-Order-Message. Essentally,
|
2
|
-
# a Functor can vary its behavior accorrding to the operation applied to it.
|
3
|
-
#
|
4
|
-
# Example
|
5
|
-
#
|
6
|
-
# f = Functor.new { |op, x| x.send(op, x) }
|
7
|
-
# (f + 1) #=> 2
|
8
|
-
# (f + 2) #=> 4
|
9
|
-
# (f + 3) #=> 6
|
10
|
-
# (f * 1) #=> 1
|
11
|
-
# (f * 2) #=> 4
|
12
|
-
# (f * 3) #=> 9
|
13
|
-
#
|
14
|
-
class Functor #< BasicObject
|
15
|
-
|
16
|
-
# Functors can be somewhat inefficient if a new Functor
|
17
|
-
# is frequently recreated for the same use. So this cache
|
18
|
-
# can be used to speed things up.
|
19
|
-
#
|
20
|
-
# The +key+ will always be an array, wich makes it easier
|
21
|
-
# to cache Functor for multiple factors.
|
22
|
-
#
|
23
|
-
def self.cache(*key, &function)
|
24
|
-
@cache ||= {}
|
25
|
-
if function
|
26
|
-
@cache[key] = new(&function)
|
27
|
-
else
|
28
|
-
@cache[key]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
EXCEPTIONS = [:binding, :inspect, :object_id]
|
33
|
-
if defined?(::BasicObject)
|
34
|
-
EXCEPTIONS.concat(::BasicObject.instance_methods)
|
35
|
-
EXCEPTIONS.uniq!
|
36
|
-
EXCEPTIONS.map!{ |m| m.to_sym }
|
37
|
-
end
|
38
|
-
|
39
|
-
#
|
40
|
-
alias :__class__ :class
|
41
|
-
|
42
|
-
## If Functor were built-in to Ruby this would not be
|
43
|
-
## needed since exceptions could just be added directly.
|
44
|
-
##$FUNCTOR_EXCEPTIONS ||= [:binding, :undefine_method]
|
45
|
-
|
46
|
-
## TODO: This will not work when BasicObject is utilized. How to fix?
|
47
|
-
##def self.honor_exceptions
|
48
|
-
## $FUNCTOR_EXCEPTIONS.each{ |name|
|
49
|
-
## next if method_defined?(name)
|
50
|
-
## eval %{
|
51
|
-
## def #{name}(*a,&b)
|
52
|
-
## super(*a, &b)
|
53
|
-
## end
|
54
|
-
## }
|
55
|
-
## }
|
56
|
-
##end
|
57
|
-
|
58
|
-
# Privatize all methods except vital methods and #binding.
|
59
|
-
instance_methods(true).each do |m|
|
60
|
-
next if m.to_s =~ /^__/
|
61
|
-
next if EXCEPTIONS.include?(m.to_sym)
|
62
|
-
undef_method(m)
|
63
|
-
end
|
64
|
-
|
65
|
-
#
|
66
|
-
def initialize(&function)
|
67
|
-
@function = function
|
68
|
-
end
|
69
|
-
|
70
|
-
#
|
71
|
-
def to_proc
|
72
|
-
@function
|
73
|
-
end
|
74
|
-
|
75
|
-
##def inspect
|
76
|
-
## #"#<#{__class__}:#{object_id} #{method_missing(:inspect)}>" # hex id ?
|
77
|
-
## "#{method_missing(:inspect)}"
|
78
|
-
##end
|
79
|
-
|
80
|
-
## Needed?
|
81
|
-
##def send(op, *a, &b)
|
82
|
-
## method_missing(op, *a, &b)
|
83
|
-
##end
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
# Any action against the Functor is processesd by the function.
|
88
|
-
def method_missing(op, *args, &blk)
|
89
|
-
@function.call(op, *args, &blk)
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
data/lib/generators.rb
DELETED
@@ -1,161 +0,0 @@
|
|
1
|
-
module Generators
|
2
|
-
|
3
|
-
module Seq
|
4
|
-
|
5
|
-
module_function
|
6
|
-
|
7
|
-
def repeat(item)
|
8
|
-
Sequence.new(Sequence::Generator.new do |g|
|
9
|
-
loop { g.yield item.respond_to?(:call) ? item.call : item }
|
10
|
-
end)
|
11
|
-
end
|
12
|
-
|
13
|
-
def range(lower, higher)
|
14
|
-
Sequence.new(Sequence::Generator.new do |g|
|
15
|
-
(lower..higher).each { |item| g.yield item }
|
16
|
-
end)
|
17
|
-
end
|
18
|
-
|
19
|
-
def iterate(operator, item, start=1)
|
20
|
-
Sequence.new(Sequence::Generator.new do |g|
|
21
|
-
value = start
|
22
|
-
loop do
|
23
|
-
g.yield value
|
24
|
-
value = value.send(operator, item)
|
25
|
-
end
|
26
|
-
end)
|
27
|
-
end
|
28
|
-
|
29
|
-
def primes
|
30
|
-
Sequence.new(Sequence::Generator.new do |g|
|
31
|
-
Prime.each { |n| g.yield n }
|
32
|
-
end)
|
33
|
-
end
|
34
|
-
|
35
|
-
def fibonacci
|
36
|
-
Sequence.new(Sequence::Generator.new do |g|
|
37
|
-
i, j = 1, 1
|
38
|
-
loop do
|
39
|
-
g.yield i
|
40
|
-
i, j = j, i + j
|
41
|
-
end
|
42
|
-
end)
|
43
|
-
end
|
44
|
-
|
45
|
-
def powers_of(v)
|
46
|
-
Sequence.new(Sequence::Generator.new do |g|
|
47
|
-
Seq.iterate(:+,1,0).each {|n| g.yield v**n}
|
48
|
-
end)
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
module Iter
|
55
|
-
|
56
|
-
module_function
|
57
|
-
|
58
|
-
def repeat(item)
|
59
|
-
Repeater.new(item)
|
60
|
-
end
|
61
|
-
|
62
|
-
def range(lower, higher)
|
63
|
-
Ranger.new(lower, higher)
|
64
|
-
end
|
65
|
-
|
66
|
-
def iterate(operator, item, start=1)
|
67
|
-
Iterate.new(operator, item, start)
|
68
|
-
end
|
69
|
-
|
70
|
-
def primes
|
71
|
-
Primes.new
|
72
|
-
end
|
73
|
-
|
74
|
-
def fibonacci
|
75
|
-
Fibonacci.new
|
76
|
-
end
|
77
|
-
|
78
|
-
def powers_of(v)
|
79
|
-
PowerOf.new(v)
|
80
|
-
end
|
81
|
-
|
82
|
-
class Repeater
|
83
|
-
include Enumerable
|
84
|
-
|
85
|
-
def initialize(item)
|
86
|
-
@item = item
|
87
|
-
end
|
88
|
-
|
89
|
-
def each
|
90
|
-
loop { yield(@item) }
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
class Ranger
|
95
|
-
include Enumerable
|
96
|
-
|
97
|
-
def initialize(lower, higher)
|
98
|
-
@lower = lower
|
99
|
-
@higher = higher
|
100
|
-
end
|
101
|
-
|
102
|
-
def each
|
103
|
-
(@lower..@higher).each { |i| yield i }
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
class Iterate
|
108
|
-
|
109
|
-
include Enumerable
|
110
|
-
|
111
|
-
def initialize(operator, item, start)
|
112
|
-
@operator = operator
|
113
|
-
@item = item
|
114
|
-
@start = start
|
115
|
-
end
|
116
|
-
|
117
|
-
def each
|
118
|
-
value = @start
|
119
|
-
loop do
|
120
|
-
yield value
|
121
|
-
value = value.send(@operator, @item)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
class Primes
|
128
|
-
include Enumerable
|
129
|
-
|
130
|
-
def each
|
131
|
-
Prime.each { |p| yield p }
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
class Fibonacci
|
136
|
-
include Enumerable
|
137
|
-
|
138
|
-
def each
|
139
|
-
i, j = 1, 1
|
140
|
-
loop do
|
141
|
-
yield i
|
142
|
-
i, j = j, i + j
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
class PowerOf
|
148
|
-
include Enumerable
|
149
|
-
|
150
|
-
def initialize(v)
|
151
|
-
@v = v
|
152
|
-
end
|
153
|
-
|
154
|
-
def each
|
155
|
-
Iter.iterate(:+,1,0).each {|n| yield @v**n}
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
|
161
|
-
end
|