enumerator_generate 0.0.1
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.
- checksums.yaml +7 -0
- data/README.md +48 -0
- data/examples.rb +46 -0
- data/lib/enumerator_generate.rb +16 -0
- metadata +74 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9570b3287b1910c7a5fa6fddae5f3706d40ee745885b226da236a5e65223c70a
|
4
|
+
data.tar.gz: c99e8abce49b85df5f03007c033cfc90a429fa3a61ce88edafebd8112e53f9cc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cdc400176f0915f01022f093660442a7248d61c7e4882a0b692db5215d9aca5013651d6b66ff7c5a67b110332c0bbd568154ed507a6ca5c4a7cbf08b03d28d24
|
7
|
+
data.tar.gz: d573ce12a0bb2ce869052759de7202abc98299035c695a7cda942aa8ce19d31732c30b665babdf0b43f10f0a47d426d0785bdf634fd66193791cf0f9da934027
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# `Enumerator#generate`
|
2
|
+
|
3
|
+
This is an alternative to [`Object#enumerate`](https://github.com/zverok/object_enumerate) Ruby language core proposal. Goal is the same: generating enumerators which can idiomatically replace (most of) `while` and `loop` cycles.
|
4
|
+
|
5
|
+
After some experiments, it turns out that "start from initial value, and continue with this block" (like `Object#enumerate` does) is not the only important use case. "Just enumerate with this block" is equally important, and `Enumerator#generate` supports this case finely. Also, the call sequence seems to be less confusing, it is pretty straight: `Enumerator#generate` generates an enumerator from block and optional initial value.
|
6
|
+
|
7
|
+
## Synopsys
|
8
|
+
|
9
|
+
`Enumerator#generate` takes a block and optional initial value, and generates (infinite) enumerator by applying the block to result of previous iteration. If initial value is not passed, first block receives no arguments.
|
10
|
+
|
11
|
+
## Examples of usage
|
12
|
+
|
13
|
+
### With initial value
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
# Infinite sequence
|
17
|
+
p Enumerator.generate(1, &:succ).take(5)
|
18
|
+
# => [1, 2, 3, 4, 5]
|
19
|
+
|
20
|
+
# Easy Fibonacci
|
21
|
+
p Enumerator.generate([0, 1]) { |f0, f1| [f1, f0 + f1] }.take(10).map(&:first)
|
22
|
+
#=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
|
23
|
+
|
24
|
+
require 'date'
|
25
|
+
|
26
|
+
# Find next Tuesday
|
27
|
+
p Enumerator.generate(Date.today, &:succ).detect { |d| d.wday == 2 }
|
28
|
+
# => #<Date: 2018-05-22 ((2458261j,0s,0n),+0s,2299161j)>
|
29
|
+
```
|
30
|
+
(Other examples from [`Object#enumerate`](https://github.com/zverok/object_enumerate) are easily translated, too.)
|
31
|
+
|
32
|
+
### Without initial value
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
# Random search
|
36
|
+
target = 7
|
37
|
+
p Enumerator.generate { rand(10) }.take_while { |i| i != target }.to_a
|
38
|
+
# => [0, 6, 3, 5,....]
|
39
|
+
|
40
|
+
# External while condition
|
41
|
+
require 'strscan'
|
42
|
+
scanner = StringScanner.new('7+38/6')
|
43
|
+
p Enumerator.generate { scanner.scan(%r{\d+|[-+*/]}) }.take_while { !scanner.eos? }.to_a
|
44
|
+
# => ["7", "+", "38", "/"]
|
45
|
+
|
46
|
+
# Potential message loop system:
|
47
|
+
Enumerator.generate { Message.receive }.take_while { |msg| msg != :exit }
|
48
|
+
```
|
data/examples.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative 'lib/enumerator_generate'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
# Infinite sequence
|
5
|
+
p Enumerator.generate(1, &:succ).take(5)
|
6
|
+
|
7
|
+
# Easy Fibonacci
|
8
|
+
p Enumerator.generate([0, 1]) { |f0, f1| [f1, f0 + f1] }.take(10).map(&:first)
|
9
|
+
|
10
|
+
require 'date'
|
11
|
+
|
12
|
+
# Find next Tuesday
|
13
|
+
p Enumerator.generate(Date.today, &:succ).detect { |d| d.wday == 2 }
|
14
|
+
|
15
|
+
require 'nokogiri'
|
16
|
+
require 'open-uri'
|
17
|
+
|
18
|
+
# Find some element on page, then make list of all parents
|
19
|
+
p Nokogiri::HTML(open('https://www.ruby-lang.org/en/'))
|
20
|
+
.at('a:contains("Ruby 2.2.10 Released")')
|
21
|
+
.yield_self { |node| Enumerator.generate(node, &:parent) } # Enumerator#generate is a bit wordy in chains
|
22
|
+
.take_while { |node| node.respond_to?(:parent) }
|
23
|
+
.map(&:name)
|
24
|
+
|
25
|
+
require 'octokit'
|
26
|
+
|
27
|
+
Octokit.stargazers('rails/rails')
|
28
|
+
# ^ this method returned just an array, but have set `.last_response` to full response, with data
|
29
|
+
# and pagination. So now we can do this:
|
30
|
+
p Enumerator.generate(Octokit.last_response) { |response| response.rels[:next].get } # pagination: `get` fetches next Response
|
31
|
+
.first(3) # take just 3 pages of stargazers
|
32
|
+
.flat_map(&:data) # data is parsed response content (stargazers themselves)
|
33
|
+
.map { |h| h[:login] }
|
34
|
+
|
35
|
+
# No initial value: random search
|
36
|
+
target = 7
|
37
|
+
p Enumerator.generate { rand(10) }.take_while { |i| i != target }.to_a
|
38
|
+
|
39
|
+
# No initial value: external while condition
|
40
|
+
require 'strscan'
|
41
|
+
scanner = StringScanner.new('7+38/6')
|
42
|
+
p Enumerator.generate { scanner.scan(%r{\d+|[-+*/]}) }.take_while { !scanner.eos? }.to_a
|
43
|
+
|
44
|
+
|
45
|
+
# Potential message loop system:
|
46
|
+
# Enumerator.generate { Message.receive }.take_while { |msg| msg != :exit }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Enumerator
|
2
|
+
NOVALUE = Object.new.freeze
|
3
|
+
|
4
|
+
def self.generate(initial = NOVALUE)
|
5
|
+
raise ArgumentError, "No block given" unless block_given?
|
6
|
+
Enumerator.new do |y|
|
7
|
+
val = initial == NOVALUE ? yield() : initial
|
8
|
+
y << val
|
9
|
+
|
10
|
+
loop do
|
11
|
+
val = yield(val)
|
12
|
+
y << val
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: enumerator_generate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Victor Shepelev
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubygems-tasks
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: " This is just a showcase gem to support language core proposal.\n"
|
42
|
+
email: zverok.offline@gmail.com
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- README.md
|
48
|
+
- examples.rb
|
49
|
+
- lib/enumerator_generate.rb
|
50
|
+
homepage: https://github.com/zverok/enumerator_generate
|
51
|
+
licenses:
|
52
|
+
- MIT
|
53
|
+
metadata: {}
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 2.2.0
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 2.7.4
|
71
|
+
signing_key:
|
72
|
+
specification_version: 4
|
73
|
+
summary: 'Enumerator#generate: Simple infinite enumerators'
|
74
|
+
test_files: []
|