totally_lazy 0.0.4 → 0.0.5

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: 6e482f2fe314ee171197af7ff51b88e2d8358496
4
- data.tar.gz: e937ed5db278d9fd2deb1d58b8e4b7090f7802cb
3
+ metadata.gz: ef27c17e829a30f3c3efd0bacdb6023066e85326
4
+ data.tar.gz: d583a528661e3c190245c64ffce9cf9b8093d55a
5
5
  SHA512:
6
- metadata.gz: 52347e5e2810a2a807f175df3cca581713426f7708530e764994a9b19525bc38488a3de8f9d0a0fdfbecc0c6b81dcc93b3aca60a4ff490131862000a6b225975
7
- data.tar.gz: 17aba7a1fc6b30ffddf49aa80db50d516aecb729e7d5ed2f6c4d83124ebb4c118f5c37cc8596cdac0c338360a1ae963fc0883bc742d4b0d5a389924b7fdb47b1
6
+ metadata.gz: 32ed21dfa78360ba8dec458c2f6646a4af09a448957b84e51c0ee686aa1fb6e031334f676e7bb5a51e759bceb9c8e88a942f022b39c80189e64877949f121aa2
7
+ data.tar.gz: 9e903a0e2716f72c524753d35de1a5ecfdb0f71228b6aa4aef1f0f55e92c3bdf9a6cb38c9fdfad99acc49a19f2501992d4175180daa1b7805cde33b84f5bb305
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
data/Gemfile CHANGED
@@ -7,4 +7,7 @@ group :development do
7
7
  gem 'jeweler', '~> 2.0.1'
8
8
  gem 'rspec_html_formatter', '~> 0.3.0'
9
9
  gem 'rake', '~> 10.3.2'
10
+ gem 'simplecov', '>= 0'
11
+ gem 'coveralls', require: false
12
+ gem 'guard-rspec', require: false
10
13
  end
data/Guardfile ADDED
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # # Rails example
10
+ # watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ # watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ # watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ # watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ # watch('config/routes.rb') { "spec/routing" }
15
+ # watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+ #
17
+ # # Capybara features specs
18
+ # watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
19
+ #
20
+ # # Turnip features and steps
21
+ # watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ # watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
data/README.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  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.
4
4
 
5
+ ### Status
6
+
7
+ [![Build Status](https://travis-ci.org/kingsleyh/totally_lazy.svg?branch=master)](https://travis-ci.org/kingsleyh/totally_lazy)
8
+ [![Gem Version](https://badge.fury.io/rb/totally_lazy.svg)](http://badge.fury.io/rb/totally_lazy)
9
+ [![Stories in Ready](https://badge.waffle.io/kingsleyh/totally_lazy.svg?label=ready&title=Ready)](http://waffle.io/kingsleyh/totally_lazy)
10
+ [![Coverage Status](https://coveralls.io/repos/kingsleyh/totally_lazy/badge.png?branch=master)](https://coveralls.io/r/kingsleyh/totally_lazy?branch=master)
11
+ [![Inline docs](http://inch-ci.org/github/kingsleyh/totally_lazy.png?branch=master)](http://inch-ci.org/github/kingsleyh/totally_lazy)
5
12
  ### Summary
6
13
 
7
14
  * Tries to be as lazy as possible
@@ -31,12 +38,34 @@ require 'totally_lazy'
31
38
 
32
39
  sequence(1,2,3,4).filter(even) # lazily returns 2,4
33
40
  sequence(1,2).map(as_string) # lazily returns "1","2"
41
+ sequence(1, 2).map_concurrently(to_string) # lazily distributes the work to background threads
34
42
  sequence(1,2,3).take(2) # lazily returns 1,2
35
43
  sequence(1,2,3).drop(2) # lazily returns 3
36
44
  sequence(1,2,3).tail # lazily returns 2,3
37
45
  sequence(1,2,3).head # eagerly returns 1
38
46
  sequence(1,2,3).head_option # eagerly returns an option
39
47
  some(sequence(1,2,3)).get_or_else(empty) # eagerly returns value or else empty sequence
48
+ sequence(1, 2, 3, 4, 5).filter(where(is greater_than 2).and(is odd)) # lazily returns 3,5
49
+ sequence(pair(1, 2), pair(3, 4)).filter(where(key:odd)) # lazily returns 1,3
50
+ ```
51
+
52
+ #### Generators
53
+
54
+ There are 2 types of generators:
55
+
56
+ * Seq - returns a sequence
57
+ * Iter - returns a regular ruby enumerator
58
+
59
+ ```ruby
60
+ Seq.range(1, 4) # lazily returns 1,2,3,4
61
+ Seq.repeat("car") # lazily returns an infinite sequence of "car"s
62
+ Seq.iterate(:+, 1) # lazily returns 1,2,3 ... to infinity
63
+ Seq.range(1, 4).cycle # lazily returns 1,2,3,4,1,2,3,4,1,2,3,4 infinitely
64
+ Seq.primes # lazily returns every prime number
65
+ Seq.fibonacci # lazily returns the fibonacci sequence
66
+ Seq.powers_of(3) # lazily returns the powers of 3 (i.e 1,3,9,27 ...)
67
+
68
+ Iter.range(1,4) # example with Iter: lazily returns 1,2,3,4 with a regular ruby enumerator
40
69
  ```
41
70
 
42
71
  Naturally you can combine these operations together:
@@ -44,4 +73,6 @@ Naturally you can combine these operations together:
44
73
  ```ruby
45
74
  option(1).join(sequence(2,3,4)).join(sequence(5,6)).filter(odd).take(2)
46
75
  # lazily returns 1,3
76
+
77
+ Seq.iterate(:+, 1).filter(even).take(2).reduce(:+) # returns 6
47
78
  ```
data/Rakefile CHANGED
@@ -48,3 +48,15 @@ Rake::RDocTask.new do |rdoc|
48
48
  rdoc.rdoc_files.include('README*')
49
49
  rdoc.rdoc_files.include('lib/**/*.rb')
50
50
  end
51
+
52
+ desc 'run rspec guard'
53
+ task :guard do
54
+ system('bundle exec guard')
55
+ end
56
+
57
+ desc 'rebuild gem'
58
+ task :re do
59
+ system('gem uninstall totally_lazy && rake build && gem install -l pkg/totally_lazy-' + File.read('VERSION') + '.gem')
60
+ end
61
+
62
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/lib/any.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Any
2
+
3
+ module_function
4
+
5
+ def string(length=rand(10)+1)
6
+ Seq.range('a','z').shuffle.take(length).to_a.join
7
+ end
8
+
9
+ def int(length=rand(10)+1)
10
+ Seq.repeat(-> { rand(9)}).take(length).to_a.join.to_i
11
+ end
12
+
13
+ end
data/lib/generators.rb ADDED
@@ -0,0 +1,161 @@
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
data/lib/option.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  module Option
2
2
 
3
3
  def option(thing)
4
- thing.nil? ? none : some(thing)
4
+ validate = thing.respond_to?(:empty?) ? thing.empty? : !thing
5
+ validate ? none : some(thing)
5
6
  end
6
7
 
7
8
  def some(thing)
@@ -18,13 +19,21 @@ module Option
18
19
 
19
20
  def initialize(content)
20
21
  @content = content
21
- raise(Exception,'some cannot be nil') if @content.nil?
22
+ raise(Exception, 'some cannot be nil') if @content.nil?
22
23
  end
23
24
 
24
25
  def <=>(object)
25
26
  self.state <=> object.state
26
27
  end
27
28
 
29
+ def is_none?
30
+ self.is_a?(None)
31
+ end
32
+
33
+ def is_some?
34
+ self.is_a?(Some)
35
+ end
36
+
28
37
  def get
29
38
  @content
30
39
  end
@@ -34,11 +43,11 @@ module Option
34
43
  end
35
44
 
36
45
  def empty?
37
- @content.empty?
46
+ blank?
38
47
  end
39
48
 
40
49
  def defined?
41
- !empty?
50
+ !blank?
42
51
  end
43
52
 
44
53
  def get_or_else(item)
@@ -49,8 +58,8 @@ module Option
49
58
  blank? ? nil : @content
50
59
  end
51
60
 
52
- def get_or_throw(exception)
53
- blank? ? raise(exception) : @content
61
+ def get_or_throw(exception,message='')
62
+ blank? ? raise(exception,message) : @content
54
63
  end
55
64
 
56
65
  def to_seq
@@ -58,16 +67,17 @@ module Option
58
67
  end
59
68
 
60
69
  def contains(item)
61
- value == item
70
+ value == item
62
71
  end
63
72
 
64
73
  def exists?(predicate)
65
-
74
+ value
66
75
  end
67
76
 
68
77
  def join(target_sequence)
69
- sequence(value) << target_sequence
78
+ sequence(value) << target_sequence
70
79
  end
80
+
71
81
  alias + join
72
82
  alias << join
73
83
 
@@ -79,7 +89,7 @@ module Option
79
89
  private
80
90
 
81
91
  def blank?
82
- @content.respond_to?(:empty?) ? empty? : !self
92
+ @content.respond_to?(:empty?) ? @content.empty? : !@content
83
93
  end
84
94
 
85
95
  end
@@ -96,6 +106,61 @@ module Option
96
106
  self.state <=> object.state
97
107
  end
98
108
 
109
+ def is_none?
110
+ self.is_a?(None)
111
+ end
112
+
113
+ def is_some?
114
+ self.is_a?(Some)
115
+ end
116
+
117
+ def get
118
+ raise NoSuchElementException.new, 'The option was empty'
119
+ end
120
+
121
+ def value
122
+ raise NoSuchElementException.new, 'The option was empty'
123
+ end
124
+
125
+ def empty?
126
+ true
127
+ end
128
+
129
+ def defined?
130
+ false
131
+ end
132
+
133
+ def get_or_else(item)
134
+ item
135
+ end
136
+
137
+ def get_or_nil
138
+ nil
139
+ end
140
+
141
+ def get_or_throw(exception,message='')
142
+ raise(exception,message)
143
+ end
144
+
145
+ def to_seq
146
+ sequence(self)
147
+ end
148
+
149
+ def contains(item)
150
+ false
151
+ end
152
+
153
+ def exists?(predicate)
154
+ false
155
+ end
156
+
157
+ def join(target_sequence)
158
+ target_sequence.is_a?(Sequences::Sequence) ? target_sequence : sequence(target_sequence)
159
+ end
160
+
161
+ alias + join
162
+ alias << join
163
+
99
164
  protected
100
165
 
101
166
  def state
data/lib/pair.rb CHANGED
@@ -25,6 +25,12 @@ module Pair
25
25
  @second.call
26
26
  end
27
27
 
28
+ def each(&block)
29
+ [first,second].each do |i|
30
+ block.call(i)
31
+ end
32
+ end
33
+
28
34
  alias value second
29
35
 
30
36
  def to_map