object_enumerate 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []