object_enumerate 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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +84 -0
  3. data/examples.rb +34 -0
  4. data/lib/object_enumerate.rb +13 -0
  5. metadata +74 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 380bf967685082971fd49b0913526d97c792c9c1049a85b3813cf298117c322d
4
+ data.tar.gz: 2b0048f1ceab75af3796cdffd52bec00b3173f39c93510c1a045282c10a7344d
5
+ SHA512:
6
+ metadata.gz: b826e1ade022d351157eaae41f16b5ef1fad2fe6f10c73576f1369804301cfecd49dd20464a010bc803796a8cb6c5ea7f99a524f2c56fe90780fd405c930c2e8
7
+ data.tar.gz: a796f6ff93ed172d728a524fbee252d7fb4c955575249dfa8daa81b112d03b3a837048bbbc202cb90fdecd936e2769bbcde5141b5be779dff9e7dd0d3b916805
@@ -0,0 +1,84 @@
1
+ # `Object#enumerate`
2
+
3
+ This is a small (exactly 1 method) gem to showcase my proposal to core Ruby.
4
+
5
+ [The proposal at Ruby tracker](https://bugs.ruby-lang.org/issues/14423).
6
+
7
+ [Discussion log](https://docs.google.com/document/d/e/2PACX-1vR2LdBE87iEcEsVuUUr0G2L6LxSPeGMg_0oeHeh0HYmX36iIa9zkWYlFHilH5D4I_RBJpQnr09yOZaE/pub) from developers meeting:
8
+
9
+ > Naruse: interesting proposal
10
+ >
11
+ > Akr: adding method to Object sounds too radical to me.
12
+ >
13
+ > Usa: I think there is a chance if this is a method of Enumerable.
14
+ >
15
+ > Shyouhei: my feeling is this should start as a gem.
16
+
17
+ So, considering Shyouhei's last remark, I am providing this gem for interested parties to experiment.
18
+
19
+ I still **strongly believe** the method should be a part of language core, so the gem is made as a proof-of-concept, to make experimentation with an idea simple.
20
+
21
+ ## Synopsys
22
+
23
+ `Object#enumerate` takes a block and returns an instance of infinite `Enumerator`, where each next element is made by applying the block to the previous.
24
+
25
+ ## Examples of usage
26
+
27
+ `Object#enumerate` can provide idiomatic replacement for a lot of `while` and `loop` constructs, the same way `each` replaces `for`.
28
+
29
+ ```ruby
30
+ require 'object_enumerate'
31
+
32
+ # Most idiomatic "infinite sequence" possible:
33
+ p 1.enumerate(&:succ).take(5)
34
+ # => [1, 2, 3, 4, 5]
35
+
36
+ # Easy Fibonacci
37
+ p [0, 1].enumerate { |f0, f1| [f1, f0 + f1] }.take(10).map(&:first)
38
+ #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
39
+
40
+ # Find next Tuesday
41
+ require 'date'
42
+ Date.today.enumerate(&:succ).detect { |d| d.wday == 2 }
43
+ # => #<Date: 2018-05-22 ((2458261j,0s,0n),+0s,2299161j)>
44
+
45
+
46
+ # Tree navigation
47
+ # ---------------
48
+ require 'nokogiri'
49
+ require 'open-uri'
50
+
51
+ # Find some element on page, then make list of all parents
52
+ p Nokogiri::HTML(open('https://www.ruby-lang.org/en/'))
53
+ .at('a:contains("Ruby 2.2.10 Released")')
54
+ .enumerate(&:parent)
55
+ .take_while { |node| node.respond_to?(:parent) }
56
+ .map(&:name)
57
+ # => ["a", "h3", "div", "div", "div", "div", "div", "div", "body", "html"]
58
+
59
+ # Pagination
60
+ # ----------
61
+ require 'octokit'
62
+
63
+ Octokit.stargazers('rails/rails')
64
+ # ^ this method returned just an array, but have set `.last_response` to full response, with data
65
+ # and pagination. So now we can do this:
66
+ p Octokit.last_response
67
+ .enumerate { |response| response.rels[:next].get } # pagination: `get` fetches next Response
68
+ .first(3) # take just 3 pages of stargazers
69
+ .flat_map(&:data) # `data` is parsed response content (stargazers themselves)
70
+ .map { |h| h[:login] }
71
+ # => ["wycats", "brynary", "macournoyer", "topfunky", "tomtt", "jamesgolick", ...
72
+ ```
73
+
74
+ ### Alternative synopsys
75
+
76
+ _Not implemented in the gem, just provided for a sake of core language proposal._
77
+
78
+ ```ruby
79
+ Enumerable.enumerate(1, &:succ)
80
+ Enumerable(1, &:succ)
81
+ Enumerator.from(1, &:succ)
82
+ ```
83
+
84
+ I personally don't believe any of those look clear enough, so, however risky adding new method to `Object` could look, I'd vote for it.
@@ -0,0 +1,34 @@
1
+ require_relative 'lib/object_enumerate'
2
+ require 'pp'
3
+
4
+ # Most idiomatic "infinite sequence" possible:
5
+ p 1.enumerate(&:succ).take(5)
6
+
7
+ # Easy Fibonacci
8
+ p [0, 1].enumerate { |f0, f1| [f1, f0 + f1] }.take(10).map(&:first)
9
+
10
+ require 'date'
11
+
12
+ # Find next Tuesday
13
+ Date.today.enumerate(&: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
+ .enumerate(&:parent)
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 Octokit.last_response
31
+ .enumerate { |response| response.rels[:next].get } # pagination: `get` fetches next Response
32
+ .first(3) # take just 3 pages of stargazers
33
+ .flat_map(&:data) # data is parsed response content (stargazers themselves)
34
+ .map { |h| h[:login] }
@@ -0,0 +1,13 @@
1
+ class Object
2
+ def enumerate
3
+ raise ArgumentError, "No block given" unless block_given?
4
+ Enumerator.new do |y|
5
+ val = self
6
+ y << val
7
+ loop do
8
+ val = yield(val)
9
+ y << val
10
+ end
11
+ end
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: object_enumerate
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-18 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: https://bugs.ruby-lang.org/issues/14423\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/object_enumerate.rb
50
+ homepage: https://github.com/zverok/object_enumerate
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: 'Object#enumerate: Simple infinite enumerators'
74
+ test_files: []