array_enumerator 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ArrayEnumerator.gemspec +62 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +44 -8
- data/README.md +51 -0
- data/VERSION +1 -1
- data/array_enumerator.gemspec +18 -18
- data/lib/array_enumerator.rb +88 -77
- data/shippable.yml +9 -0
- data/spec/array_enumerator_spec.rb +85 -106
- data/spec/spec_helper.rb +3 -1
- metadata +71 -79
- data/README.rdoc +0 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5aab5eb33c71ba8c4f8c3522917f0ee5c2c1bdde
|
4
|
+
data.tar.gz: 08086ebda4167d4ff4c3ca9df66c3fad6f3ec2f2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8446dacab604ccf62bd44f2b5c4d5cdf6b9a63d959c7216dcbcb1647b3880b6972189539b7ea0e6f04bcfe2fcfb674b15728ef2029ce7a7798926b26f078cc62
|
7
|
+
data.tar.gz: 56abf61e50da49e75d75bb6a28dccce84d49a6768332cfd68db2c865ca4ffe37030055cccdae3aa359429563d6bbd95726b5473763fd6b6e5e3ae913d0285277
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: array_enumerator 0.0.4 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "array_enumerator"
|
9
|
+
s.version = "0.0.4"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Kasper Johansen"]
|
14
|
+
s.date = "2014-12-19"
|
15
|
+
s.description = "Enumerator abstraction layer that emulates certain array functionality (methods like empty?, slice, shift and more) by using a small cache and other tricks without loading all the data from the enumerator at the same time."
|
16
|
+
s.email = "k@spernj.org"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".rspec",
|
24
|
+
"Gemfile",
|
25
|
+
"Gemfile.lock",
|
26
|
+
"LICENSE.txt",
|
27
|
+
"README.md",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"array_enumerator.gemspec",
|
31
|
+
"lib/array_enumerator.rb",
|
32
|
+
"shippable.yml",
|
33
|
+
"spec/array_enumerator_spec.rb",
|
34
|
+
"spec/spec_helper.rb"
|
35
|
+
]
|
36
|
+
s.homepage = "http://github.com/kaspernj/array_enumerator"
|
37
|
+
s.licenses = ["MIT"]
|
38
|
+
s.rubygems_version = "2.4.0"
|
39
|
+
s.summary = "Enumerator abstraction layer that emulates certain array functionality (methods)."
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
s.specification_version = 4
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
46
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
47
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
48
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.8"])
|
49
|
+
else
|
50
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
51
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
52
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
53
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
54
|
+
end
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
57
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
58
|
+
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
59
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,17 +1,48 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
addressable (2.3.6)
|
5
|
+
builder (3.2.2)
|
6
|
+
codeclimate-test-reporter (0.4.3)
|
7
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
4
8
|
diff-lcs (1.1.3)
|
5
|
-
|
6
|
-
|
9
|
+
docile (1.1.5)
|
10
|
+
faraday (0.8.9)
|
11
|
+
multipart-post (~> 1.2.0)
|
12
|
+
git (1.2.8)
|
13
|
+
github_api (0.10.1)
|
14
|
+
addressable
|
15
|
+
faraday (~> 0.8.1)
|
16
|
+
hashie (>= 1.2)
|
17
|
+
multi_json (~> 1.4)
|
18
|
+
nokogiri (~> 1.5.2)
|
19
|
+
oauth2
|
20
|
+
hashie (3.3.2)
|
21
|
+
highline (1.6.21)
|
22
|
+
jeweler (1.8.8)
|
23
|
+
builder
|
7
24
|
bundler (~> 1.0)
|
8
25
|
git (>= 1.2.5)
|
26
|
+
github_api (= 0.10.1)
|
27
|
+
highline (>= 1.6.15)
|
28
|
+
nokogiri (= 1.5.10)
|
9
29
|
rake
|
10
30
|
rdoc
|
11
|
-
json (1.
|
12
|
-
|
13
|
-
|
14
|
-
|
31
|
+
json (1.8.1)
|
32
|
+
jwt (1.2.0)
|
33
|
+
multi_json (1.10.1)
|
34
|
+
multi_xml (0.5.5)
|
35
|
+
multipart-post (1.2.0)
|
36
|
+
nokogiri (1.5.10)
|
37
|
+
oauth2 (1.0.0)
|
38
|
+
faraday (>= 0.8, < 0.10)
|
39
|
+
jwt (~> 1.0)
|
40
|
+
multi_json (~> 1.3)
|
41
|
+
multi_xml (~> 0.5)
|
42
|
+
rack (~> 1.2)
|
43
|
+
rack (1.6.0)
|
44
|
+
rake (10.4.2)
|
45
|
+
rdoc (3.12.2)
|
15
46
|
json (~> 1.4)
|
16
47
|
rspec (2.8.0)
|
17
48
|
rspec-core (~> 2.8.0)
|
@@ -21,13 +52,18 @@ GEM
|
|
21
52
|
rspec-expectations (2.8.0)
|
22
53
|
diff-lcs (~> 1.1.2)
|
23
54
|
rspec-mocks (2.8.0)
|
55
|
+
simplecov (0.9.1)
|
56
|
+
docile (~> 1.1.0)
|
57
|
+
multi_json (~> 1.0)
|
58
|
+
simplecov-html (~> 0.8.0)
|
59
|
+
simplecov-html (0.8.0)
|
24
60
|
|
25
61
|
PLATFORMS
|
26
62
|
ruby
|
27
63
|
|
28
64
|
DEPENDENCIES
|
29
65
|
bundler (>= 1.0.0)
|
30
|
-
|
31
|
-
|
66
|
+
codeclimate-test-reporter
|
67
|
+
jeweler (~> 1.8.8)
|
32
68
|
rdoc (~> 3.12)
|
33
69
|
rspec (~> 2.8.0)
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
[![Build Status](https://api.shippable.com/projects/540e7b993479c5ea8f9ec1fb/badge?branchName=master)](https://app.shippable.com/projects/540e7b993479c5ea8f9ec1fb/builds/latest)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/kaspernj/array_enumerator/badges/gpa.svg)](https://codeclimate.com/github/kaspernj/array_enumerator)
|
3
|
+
[![Test Coverage](https://codeclimate.com/github/kaspernj/array_enumerator/badges/coverage.svg)](https://codeclimate.com/github/kaspernj/array_enumerator)
|
4
|
+
|
5
|
+
# ArrayEnumerator
|
6
|
+
|
7
|
+
A modified enumerator for Ruby that behaves like an array, without loading everything into memory.
|
8
|
+
|
9
|
+
## Install
|
10
|
+
|
11
|
+
Add to your Gemfile and bundle:
|
12
|
+
```ruby
|
13
|
+
gem "array_enumerator"
|
14
|
+
```
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
Use it like a normal enumerator:
|
19
|
+
```ruby
|
20
|
+
a_enum = ArrayEnumerator.new do |y|
|
21
|
+
1_000.times do |count|
|
22
|
+
y << count
|
23
|
+
end
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
Call array-methods like you normally would:
|
28
|
+
```ruby
|
29
|
+
a_enum.empty? #=> false
|
30
|
+
a_enum.first #=> 1
|
31
|
+
a_enum.shift #=> 2
|
32
|
+
a_enum[2] => 3
|
33
|
+
a_enum.each_index { |count| puts "Count: #{count}" }
|
34
|
+
a_enum.length #=> 3
|
35
|
+
```
|
36
|
+
|
37
|
+
## Contributing to ArrayEnumerator
|
38
|
+
|
39
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
40
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
41
|
+
* Fork the project.
|
42
|
+
* Start a feature/bugfix branch.
|
43
|
+
* Commit and push until you are happy with your contribution.
|
44
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
45
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
46
|
+
|
47
|
+
## Copyright
|
48
|
+
|
49
|
+
Copyright (c) 2012 Kasper Johansen. See LICENSE.txt for
|
50
|
+
further details.
|
51
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/array_enumerator.gemspec
CHANGED
@@ -2,62 +2,62 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: array_enumerator 0.0.5 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.0.
|
8
|
+
s.name = "array_enumerator"
|
9
|
+
s.version = "0.0.5"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Kasper Johansen"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
14
|
+
s.date = "2014-12-19"
|
15
|
+
s.description = "Enumerator abstraction layer that emulates certain array functionality (methods like empty?, slice, shift and more) by using a small cache and other tricks without loading all the data from the enumerator at the same time."
|
16
|
+
s.email = "k@spernj.org"
|
15
17
|
s.extra_rdoc_files = [
|
16
18
|
"LICENSE.txt",
|
17
|
-
"README.
|
19
|
+
"README.md"
|
18
20
|
]
|
19
21
|
s.files = [
|
20
22
|
".document",
|
21
23
|
".rspec",
|
24
|
+
"ArrayEnumerator.gemspec",
|
22
25
|
"Gemfile",
|
23
26
|
"Gemfile.lock",
|
24
27
|
"LICENSE.txt",
|
25
|
-
"README.
|
28
|
+
"README.md",
|
26
29
|
"Rakefile",
|
27
30
|
"VERSION",
|
28
31
|
"array_enumerator.gemspec",
|
29
32
|
"lib/array_enumerator.rb",
|
33
|
+
"shippable.yml",
|
30
34
|
"spec/array_enumerator_spec.rb",
|
31
35
|
"spec/spec_helper.rb"
|
32
36
|
]
|
33
|
-
s.homepage =
|
37
|
+
s.homepage = "http://github.com/kaspernj/array_enumerator"
|
34
38
|
s.licenses = ["MIT"]
|
35
|
-
s.
|
36
|
-
s.
|
37
|
-
s.summary = %q{Enumerator abstraction layer that emulates certain array functionality (methods).}
|
39
|
+
s.rubygems_version = "2.4.0"
|
40
|
+
s.summary = "Enumerator abstraction layer that emulates certain array functionality (methods)."
|
38
41
|
|
39
42
|
if s.respond_to? :specification_version then
|
40
|
-
s.specification_version =
|
43
|
+
s.specification_version = 4
|
41
44
|
|
42
45
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
46
|
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
44
47
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
45
48
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
46
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.
|
47
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.8"])
|
48
50
|
else
|
49
51
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
50
52
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
51
53
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
52
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.
|
53
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
54
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
54
55
|
end
|
55
56
|
else
|
56
57
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
57
58
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
58
59
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
59
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.
|
60
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
60
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
data/lib/array_enumerator.rb
CHANGED
@@ -1,43 +1,54 @@
|
|
1
|
-
#This class is ment as an enumerator but with a cache that enables it to emulate array-functionality (first, empty and so on). If elements goes out of memory, then the array becomes corrupted and methods like 'first' and 'slice' will no longer work (raise errors).
|
2
|
-
class
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
# This class is ment as an enumerator but with a cache that enables it to emulate array-functionality (first, empty and so on). If elements goes out of memory, then the array becomes corrupted and methods like 'first' and 'slice' will no longer work (raise errors).
|
2
|
+
class ArrayEnumerator
|
3
|
+
class ArrayCorruptedError < RuntimeError; end
|
4
|
+
class CannotCallBeforeEnd < RuntimeError; end
|
5
|
+
|
6
|
+
# Takes an enumerator to work with as argument.
|
7
|
+
def initialize(enum = nil, &blk)
|
8
|
+
if enum
|
9
|
+
#The enumerator being used.
|
10
|
+
@enum = enum
|
11
|
+
elsif blk
|
12
|
+
@enum = Enumerator.new do |yielder|
|
13
|
+
blk.call(yielder)
|
14
|
+
end
|
15
|
+
else
|
16
|
+
raise "No enum or block was given."
|
17
|
+
end
|
18
|
+
|
19
|
+
# Used to calculate length without depending corruption.
|
9
20
|
@length_cache = 0
|
10
|
-
|
11
|
-
#If the virtual array has become corrupted because of forgotten elements (by calling each and enumerating through elements).
|
21
|
+
|
22
|
+
# If the virtual array has become corrupted because of forgotten elements (by calling each and enumerating through elements).
|
12
23
|
@array_corrupted = false
|
13
|
-
|
14
|
-
#To allow the object to be thread-safe.
|
24
|
+
|
25
|
+
# To allow the object to be thread-safe.
|
15
26
|
@mutex = Mutex.new
|
16
27
|
end
|
17
|
-
|
18
|
-
#Cache the first elements (if not cached already) and returns it.
|
28
|
+
|
29
|
+
# Cache the first elements (if not cached already) and returns it.
|
19
30
|
def first
|
20
31
|
check_corrupted
|
21
|
-
cache_ele if !@eles
|
32
|
+
cache_ele if !@eles || @eles.empty?
|
22
33
|
return @eles.first
|
23
34
|
end
|
24
|
-
|
25
|
-
#Returns true if the array is empty.
|
35
|
+
|
36
|
+
# Returns true if the array is empty.
|
26
37
|
def empty?
|
27
38
|
if @empty == nil
|
28
39
|
cache_ele if !@eles
|
29
|
-
|
40
|
+
|
30
41
|
if @length_cache > 0
|
31
42
|
@empty = false
|
32
43
|
else
|
33
44
|
@empty = true
|
34
45
|
end
|
35
46
|
end
|
36
|
-
|
47
|
+
|
37
48
|
return @empty
|
38
49
|
end
|
39
|
-
|
40
|
-
#Returns each element and releases them from cache.
|
50
|
+
|
51
|
+
# Returns each element and releases them from cache.
|
41
52
|
def each(&block)
|
42
53
|
if block
|
43
54
|
to_enum.each(&block)
|
@@ -46,42 +57,42 @@ class Array_enumerator
|
|
46
57
|
return to_enum
|
47
58
|
end
|
48
59
|
end
|
49
|
-
|
50
|
-
#This method should only be used with 'each_index'.
|
60
|
+
|
61
|
+
# This method should only be used with 'each_index'.
|
51
62
|
def [](key)
|
52
|
-
if @each_index
|
63
|
+
if @each_index && @each_index.key?(key)
|
53
64
|
ret = @each_index[key]
|
54
65
|
@each_index.delete(key)
|
55
66
|
return ret
|
56
67
|
end
|
57
|
-
|
68
|
+
|
58
69
|
raise "This only works when also using 'each_index'. Invalid key: '#{key}'."
|
59
70
|
end
|
60
|
-
|
61
|
-
#Yields each count-key and caches element for returning it by using the []-method.
|
71
|
+
|
72
|
+
# Yields each count-key and caches element for returning it by using the []-method.
|
62
73
|
def each_index(&block)
|
63
74
|
enum = Enumerator.new do |yielder|
|
64
75
|
begin
|
65
76
|
@each_index = {}
|
66
|
-
|
77
|
+
|
67
78
|
count = 0
|
68
79
|
self.each do |ele|
|
69
|
-
#Remove previous element to not take up memory.
|
80
|
+
# Remove previous element to not take up memory.
|
70
81
|
count_before = count - 1
|
71
82
|
@each_index.delete(count_before) if @each_index.key?(count_before)
|
72
|
-
|
73
|
-
#Add current element to cache.
|
83
|
+
|
84
|
+
# Add current element to cache.
|
74
85
|
@each_index[count] = ele
|
75
86
|
yield(count)
|
76
|
-
|
77
|
-
#Increase count for next run.
|
87
|
+
|
88
|
+
# Increase count for next run.
|
78
89
|
count += 1
|
79
90
|
end
|
80
91
|
ensure
|
81
92
|
@each_index = nil
|
82
93
|
end
|
83
94
|
end
|
84
|
-
|
95
|
+
|
85
96
|
if block
|
86
97
|
enum.each(&block)
|
87
98
|
return nil
|
@@ -89,97 +100,97 @@ class Array_enumerator
|
|
89
100
|
return enum
|
90
101
|
end
|
91
102
|
end
|
92
|
-
|
93
|
-
#Returns a enumerator that can yield the all the lements (both cached and future un-cached ones).
|
103
|
+
|
104
|
+
# Returns a enumerator that can yield the all the lements (both cached and future un-cached ones).
|
94
105
|
def to_enum
|
95
106
|
check_corrupted
|
96
107
|
@array_corrupted = true
|
97
|
-
|
108
|
+
|
98
109
|
return Enumerator.new do |yielder|
|
99
110
|
if @eles
|
100
111
|
while ele = @eles.shift
|
101
112
|
yielder << ele
|
102
113
|
end
|
103
114
|
end
|
104
|
-
|
115
|
+
|
105
116
|
yield_rest do |ele|
|
106
117
|
yielder << ele
|
107
118
|
end
|
108
119
|
end
|
109
120
|
end
|
110
|
-
|
111
|
-
#Returns the counted length. Can only be called after the end of the enumerator has been reached.
|
121
|
+
|
122
|
+
# Returns the counted length. Can only be called after the end of the enumerator has been reached.
|
112
123
|
def length
|
113
|
-
raise "Cant call length before the end has been reached."
|
124
|
+
raise CannotCallBeforeEnd, "Cant call length before the end has been reached." unless @end
|
114
125
|
return @length_cache
|
115
126
|
end
|
116
|
-
|
117
|
-
#Giving slice negaive arguments will force it to cache all elements and crush the memory for big results.
|
127
|
+
|
128
|
+
# Giving slice negaive arguments will force it to cache all elements and crush the memory for big results.
|
118
129
|
def slice(*args)
|
119
130
|
check_corrupted
|
120
|
-
|
121
|
-
if args[0].is_a?(Range)
|
131
|
+
|
132
|
+
if args[0].is_a?(Range) && !args[1]
|
122
133
|
need_eles = args[0].begin + args[0].end
|
123
|
-
elsif args[0]
|
134
|
+
elsif args[0] && !args[1]
|
124
135
|
need_eles = args[0]
|
125
|
-
elsif args[0]
|
136
|
+
elsif args[0] && args[1] && args[0] > 0 && args[1] > 0
|
126
137
|
need_eles = args[0] + args[1]
|
127
|
-
elsif args[0] < 0
|
138
|
+
elsif args[0] < 0 || args[1] < 0
|
128
139
|
raise "Slice cant take negative arguments."
|
129
140
|
else
|
130
141
|
raise "Dont now what to do with args: '#{args}'."
|
131
142
|
end
|
132
|
-
|
143
|
+
|
133
144
|
@eles = [] if !@eles
|
134
145
|
cache_eles = need_eles - @eles.length if need_eles
|
135
|
-
cache_ele(cache_eles) if need_eles
|
146
|
+
cache_ele(cache_eles) if need_eles && cache_eles > 0
|
136
147
|
return @eles.slice(*args)
|
137
148
|
end
|
138
|
-
|
139
|
-
#Caches necessary needed elements and then returns the result as on a normal array.
|
149
|
+
|
150
|
+
# Caches necessary needed elements and then returns the result as on a normal array.
|
140
151
|
def shift(*args)
|
141
152
|
check_corrupted
|
142
|
-
|
153
|
+
|
143
154
|
if args[0]
|
144
155
|
amount = args[0]
|
145
156
|
else
|
146
157
|
amount = 1
|
147
158
|
end
|
148
|
-
|
149
|
-
@eles = []
|
150
|
-
cache_ele(amount - @eles.length) if !@eles
|
159
|
+
|
160
|
+
@eles = [] unless @eles
|
161
|
+
cache_ele(amount - @eles.length) if !@eles || @eles.length < amount
|
151
162
|
res = @eles.shift(*args)
|
152
|
-
|
153
|
-
#Since we are removing an element, the length should go down with the amount of elements captured.
|
163
|
+
|
164
|
+
# Since we are removing an element, the length should go down with the amount of elements captured.
|
154
165
|
if args[0]
|
155
166
|
@length_cache -= res.length
|
156
167
|
else
|
157
168
|
@length_cache -= 1
|
158
169
|
end
|
159
|
-
|
170
|
+
|
160
171
|
return res
|
161
172
|
end
|
162
|
-
|
163
|
-
#Returns a normal array with all elements. Can also raise corrupted error if elements have been thrown out.
|
173
|
+
|
174
|
+
# Returns a normal array with all elements. Can also raise corrupted error if elements have been thrown out.
|
164
175
|
def to_a
|
165
176
|
check_corrupted
|
166
177
|
cache_all
|
167
178
|
return @eles
|
168
179
|
end
|
169
|
-
|
180
|
+
|
170
181
|
alias to_ary to_a
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
#Raises error because elements have been forgotten to spare memory.
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
# Raises error because elements have been forgotten to spare memory.
|
175
186
|
def check_corrupted
|
176
|
-
raise "Too late to call. Corrupted." if @array_corrupted
|
187
|
+
raise ArrayCorruptedError, "Too late to call. Corrupted." if @array_corrupted
|
177
188
|
end
|
178
|
-
|
179
|
-
#Yields the rest of the elements to the given block.
|
189
|
+
|
190
|
+
# Yields the rest of the elements to the given block.
|
180
191
|
def yield_rest
|
181
192
|
@array_corrupted = true
|
182
|
-
|
193
|
+
|
183
194
|
begin
|
184
195
|
@mutex.synchronize do
|
185
196
|
while ele = @enum.next
|
@@ -191,11 +202,11 @@ class Array_enumerator
|
|
191
202
|
@end = true
|
192
203
|
end
|
193
204
|
end
|
194
|
-
|
195
|
-
#Caches a given amount of elements.
|
205
|
+
|
206
|
+
# Caches a given amount of elements.
|
196
207
|
def cache_ele(amount = 1)
|
197
208
|
@eles = [] if !@cache
|
198
|
-
|
209
|
+
|
199
210
|
begin
|
200
211
|
@mutex.synchronize do
|
201
212
|
while @eles.length <= amount
|
@@ -207,11 +218,11 @@ class Array_enumerator
|
|
207
218
|
@end = true
|
208
219
|
end
|
209
220
|
end
|
210
|
-
|
211
|
-
#Forces the rest of the elements to be cached.
|
221
|
+
|
222
|
+
# Forces the rest of the elements to be cached.
|
212
223
|
def cache_all
|
213
224
|
@eles = [] if !@eles
|
214
|
-
|
225
|
+
|
215
226
|
begin
|
216
227
|
@mutex.synchronize do
|
217
228
|
while ele = @enum.next
|
@@ -223,4 +234,4 @@ class Array_enumerator
|
|
223
234
|
@end = true
|
224
235
|
end
|
225
236
|
end
|
226
|
-
end
|
237
|
+
end
|
data/shippable.yml
ADDED
@@ -1,143 +1,122 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe "ArrayEnumerator" do
|
4
|
-
it "
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
raise "Expected 'a' but got: '#{res}'." if res != "a"
|
10
|
-
|
11
|
-
arr = ae.to_a
|
12
|
-
exp = %w[b c d e]
|
13
|
-
raise "Expected array to be '#{exp}' but got: '#{arr}'." if arr != exp
|
14
|
-
end
|
15
|
-
|
16
|
-
it "each" do
|
17
|
-
arr = %w[a b c]
|
18
|
-
cont = arr.to_enum
|
19
|
-
ae = Array_enumerator.new(cont)
|
20
|
-
|
21
|
-
count = 0
|
22
|
-
ae.each do |ele|
|
23
|
-
raise "Expected #{arr[count]} but got: #{ele}" if ele != arr[count]
|
24
|
-
count += 1
|
25
|
-
end
|
26
|
-
|
27
|
-
raise "Expected 3 elements to yield through but got: #{count}" if count != 3
|
28
|
-
|
29
|
-
arr = %w[a b c]
|
30
|
-
cont = arr.to_enum
|
31
|
-
ae = Array_enumerator.new(cont)
|
32
|
-
|
33
|
-
res = ae.empty?
|
34
|
-
raise "Expected empty to be false but got: '#{res}'." if res != false
|
35
|
-
|
36
|
-
count = 0
|
37
|
-
ae.each do |ele|
|
38
|
-
raise "Expected #{arr[count]} but got: #{ele}" if ele != arr[count]
|
39
|
-
count += 1
|
40
|
-
end
|
41
|
-
|
42
|
-
raise "Expected 3 elements to yield through but got: #{count}" if count != 3
|
43
|
-
|
44
|
-
begin
|
45
|
-
ae.to_a
|
46
|
-
raise "Should have raised exception but didnt."
|
47
|
-
rescue
|
48
|
-
#ignore.
|
4
|
+
it "can be initialized as normal enumerator" do
|
5
|
+
enum = ArrayEnumerator.new do |y|
|
6
|
+
3.times do |count|
|
7
|
+
y << count
|
8
|
+
end
|
49
9
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
raise "Should have raised exception but didnt."
|
54
|
-
rescue
|
55
|
-
#ignore.
|
10
|
+
|
11
|
+
3.times do |count|
|
12
|
+
enum.shift.should eq count
|
56
13
|
end
|
57
|
-
|
58
|
-
|
14
|
+
end
|
15
|
+
|
16
|
+
it "#shift" do
|
17
|
+
cont = %w[a b c d e].to_enum
|
18
|
+
ae = ArrayEnumerator.new(cont)
|
19
|
+
ae.shift.should eq "a"
|
20
|
+
ae.to_a.should eq %w[b c d e]
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#each" do
|
24
|
+
it "should loop with correct values" do
|
25
|
+
arr = %w[a b c]
|
26
|
+
cont = arr.to_enum
|
27
|
+
ae = ArrayEnumerator.new(cont)
|
28
|
+
|
29
|
+
count = 0
|
59
30
|
ae.each do |ele|
|
60
|
-
|
31
|
+
ele.should eq arr[count]
|
32
|
+
count += 1
|
61
33
|
end
|
62
|
-
|
63
|
-
|
64
|
-
rescue
|
65
|
-
#ignore.
|
34
|
+
|
35
|
+
count.should eq 3
|
66
36
|
end
|
67
37
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
38
|
+
|
39
|
+
describe "#empty?" do
|
40
|
+
it "be able to test empty and then loop correctly afterwards" do
|
41
|
+
arr = %w[a b c]
|
42
|
+
cont = arr.to_enum
|
43
|
+
ae = ArrayEnumerator.new(cont)
|
44
|
+
|
45
|
+
ae.empty?.should eq false
|
46
|
+
|
47
|
+
count = 0
|
48
|
+
ae.each do |ele|
|
49
|
+
ele.should eq arr[count]
|
50
|
+
count += 1
|
51
|
+
end
|
52
|
+
|
53
|
+
count.should eq 3
|
54
|
+
|
55
|
+
expect { ae.to_a }.to raise_error(ArrayEnumerator::ArrayCorruptedError)
|
56
|
+
expect { ae.first }.to raise_error(ArrayEnumerator::ArrayCorruptedError)
|
57
|
+
|
58
|
+
expect {
|
59
|
+
ae.each { |ele| raise "Should never get here?" }
|
60
|
+
}.to raise_error(ArrayEnumerator::ArrayCorruptedError)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "still be able to get the first element after testing if empty" do
|
64
|
+
cont = %w[a b c].to_enum
|
65
|
+
ae = ArrayEnumerator.new(cont)
|
66
|
+
ae.empty?.should eq false
|
67
|
+
ae.first.should eq "a"
|
68
|
+
end
|
78
69
|
end
|
79
|
-
|
80
|
-
it "length" do
|
70
|
+
|
71
|
+
it "#length" do
|
81
72
|
cont = %w[a b c d e].to_enum
|
82
|
-
ae =
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
raise "Should have failed but didnt."
|
87
|
-
rescue
|
88
|
-
#ignore.
|
89
|
-
end
|
90
|
-
|
73
|
+
ae = ArrayEnumerator.new(cont)
|
74
|
+
|
75
|
+
expect { ae.length }.to raise_error(ArrayEnumerator::CannotCallBeforeEnd)
|
76
|
+
|
91
77
|
ae.each do |ele|
|
92
|
-
#ignore.
|
78
|
+
# ignore.
|
93
79
|
end
|
94
|
-
|
95
|
-
|
96
|
-
raise "Expected length to be 5 but it wasnt: '#{res}'." if res != 5
|
80
|
+
|
81
|
+
ae.length.should eq 5
|
97
82
|
end
|
98
|
-
|
99
|
-
it "slice" do
|
83
|
+
|
84
|
+
it "#slice" do
|
100
85
|
arr = %w[a b c d e f g h i j k l m n]
|
101
86
|
cont = arr.to_enum
|
102
|
-
ae =
|
103
|
-
|
87
|
+
ae = ArrayEnumerator.new(cont)
|
88
|
+
|
104
89
|
runs = [
|
105
90
|
[6],
|
106
91
|
[1, 2],
|
107
92
|
[1..3]
|
108
93
|
]
|
109
|
-
|
94
|
+
|
110
95
|
fails = [
|
111
96
|
[-2, 2],
|
112
97
|
[2, -2]
|
113
98
|
]
|
114
|
-
|
99
|
+
|
115
100
|
runs.each do |args|
|
116
|
-
|
117
|
-
res2 = ae.slice(*args)
|
118
|
-
|
119
|
-
raise "Expected res to be: #{res1} but got #{res2} for args '#{args}'." if res1 != res2
|
101
|
+
arr.slice(*args).should eq ae.slice(*args)
|
120
102
|
end
|
121
|
-
|
103
|
+
|
122
104
|
fails.each do |args|
|
123
|
-
|
105
|
+
expect {
|
124
106
|
res2 = ae.slice(*args)
|
125
107
|
raise "Should have failed but didnt."
|
126
|
-
|
127
|
-
#ignore.
|
128
|
-
end
|
108
|
+
}.to raise_error
|
129
109
|
end
|
130
110
|
end
|
131
|
-
|
132
|
-
it "each_index" do
|
111
|
+
|
112
|
+
it "#each_index" do
|
133
113
|
arr = %w[a b c d e f g]
|
134
|
-
ae =
|
135
|
-
|
114
|
+
ae = ArrayEnumerator.new(arr.to_enum)
|
115
|
+
|
136
116
|
expect = 0
|
137
117
|
ae.each_index do |num|
|
138
|
-
|
139
|
-
|
140
|
-
raise "Expected #{arr[num]} but got: #{ele}" if ele != arr[num]
|
118
|
+
num.should eq expect
|
119
|
+
ae[num].should eq arr[num]
|
141
120
|
expect += 1
|
142
121
|
end
|
143
122
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
1
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
5
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
6
|
require 'rspec'
|
@@ -8,5 +11,4 @@ require 'array_enumerator'
|
|
8
11
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
12
|
|
10
13
|
RSpec.configure do |config|
|
11
|
-
|
12
14
|
end
|
metadata
CHANGED
@@ -1,125 +1,117 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: array_enumerator
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.0.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- Kasper Johansen
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2014-12-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
17
14
|
name: rspec
|
18
|
-
requirement:
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Version
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
23
19
|
version: 2.8.0
|
24
20
|
type: :development
|
25
21
|
prerelease: false
|
26
|
-
version_requirements:
|
27
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.8.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
28
|
name: rdoc
|
29
|
-
requirement:
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
version: "3.12"
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.12'
|
35
34
|
type: :development
|
36
35
|
prerelease: false
|
37
|
-
version_requirements:
|
38
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
39
42
|
name: bundler
|
40
|
-
requirement:
|
41
|
-
|
42
|
-
requirements:
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
43
45
|
- - ">="
|
44
|
-
- !ruby/object:Gem::Version
|
46
|
+
- !ruby/object:Gem::Version
|
45
47
|
version: 1.0.0
|
46
48
|
type: :development
|
47
49
|
prerelease: false
|
48
|
-
version_requirements:
|
49
|
-
|
50
|
-
name: jeweler
|
51
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
52
|
-
none: false
|
53
|
-
requirements:
|
54
|
-
- - ~>
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: 1.8.4
|
57
|
-
type: :development
|
58
|
-
prerelease: false
|
59
|
-
version_requirements: *id004
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name: rcov
|
62
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
63
|
-
none: false
|
64
|
-
requirements:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
65
52
|
- - ">="
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version:
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jeweler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.8.8
|
68
62
|
type: :development
|
69
63
|
prerelease: false
|
70
|
-
version_requirements:
|
71
|
-
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.8.8
|
69
|
+
description: Enumerator abstraction layer that emulates certain array functionality
|
70
|
+
(methods like empty?, slice, shift and more) by using a small cache and other tricks
|
71
|
+
without loading all the data from the enumerator at the same time.
|
72
72
|
email: k@spernj.org
|
73
73
|
executables: []
|
74
|
-
|
75
74
|
extensions: []
|
76
|
-
|
77
|
-
extra_rdoc_files:
|
75
|
+
extra_rdoc_files:
|
78
76
|
- LICENSE.txt
|
79
|
-
- README.
|
80
|
-
files:
|
81
|
-
- .document
|
82
|
-
- .rspec
|
77
|
+
- README.md
|
78
|
+
files:
|
79
|
+
- ".document"
|
80
|
+
- ".rspec"
|
81
|
+
- ArrayEnumerator.gemspec
|
83
82
|
- Gemfile
|
84
83
|
- Gemfile.lock
|
85
84
|
- LICENSE.txt
|
86
|
-
- README.
|
85
|
+
- README.md
|
87
86
|
- Rakefile
|
88
87
|
- VERSION
|
89
88
|
- array_enumerator.gemspec
|
90
89
|
- lib/array_enumerator.rb
|
90
|
+
- shippable.yml
|
91
91
|
- spec/array_enumerator_spec.rb
|
92
92
|
- spec/spec_helper.rb
|
93
|
-
has_rdoc: true
|
94
93
|
homepage: http://github.com/kaspernj/array_enumerator
|
95
|
-
licenses:
|
94
|
+
licenses:
|
96
95
|
- MIT
|
96
|
+
metadata: {}
|
97
97
|
post_install_message:
|
98
98
|
rdoc_options: []
|
99
|
-
|
100
|
-
require_paths:
|
99
|
+
require_paths:
|
101
100
|
- lib
|
102
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
-
|
104
|
-
requirements:
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
105
103
|
- - ">="
|
106
|
-
- !ruby/object:Gem::Version
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
version: "0"
|
111
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
|
-
requirements:
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
114
108
|
- - ">="
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version:
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
117
111
|
requirements: []
|
118
|
-
|
119
112
|
rubyforge_project:
|
120
|
-
rubygems_version:
|
113
|
+
rubygems_version: 2.4.0
|
121
114
|
signing_key:
|
122
|
-
specification_version:
|
115
|
+
specification_version: 4
|
123
116
|
summary: Enumerator abstraction layer that emulates certain array functionality (methods).
|
124
117
|
test_files: []
|
125
|
-
|
data/README.rdoc
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
= array_enumerator
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Contributing to array_enumerator
|
6
|
-
|
7
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
-
* Fork the project.
|
10
|
-
* Start a feature/bugfix branch.
|
11
|
-
* Commit and push until you are happy with your contribution.
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2012 Kasper Johansen. See LICENSE.txt for
|
18
|
-
further details.
|
19
|
-
|