ruby-next-core 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +68 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +279 -0
  5. data/bin/parse +19 -0
  6. data/bin/ruby-next +16 -0
  7. data/bin/transform +21 -0
  8. data/lib/ruby-next.rb +37 -0
  9. data/lib/ruby-next/cli.rb +55 -0
  10. data/lib/ruby-next/commands/base.rb +42 -0
  11. data/lib/ruby-next/commands/nextify.rb +118 -0
  12. data/lib/ruby-next/core.rb +34 -0
  13. data/lib/ruby-next/core/array/difference_union_intersection.rb +31 -0
  14. data/lib/ruby-next/core/enumerable/filter.rb +23 -0
  15. data/lib/ruby-next/core/enumerable/filter_map.rb +50 -0
  16. data/lib/ruby-next/core/enumerable/tally.rb +28 -0
  17. data/lib/ruby-next/core/enumerator/produce.rb +22 -0
  18. data/lib/ruby-next/core/hash/merge.rb +16 -0
  19. data/lib/ruby-next/core/kernel/then.rb +12 -0
  20. data/lib/ruby-next/core/pattern_matching.rb +37 -0
  21. data/lib/ruby-next/core/proc/compose.rb +21 -0
  22. data/lib/ruby-next/core/runtime.rb +10 -0
  23. data/lib/ruby-next/language.rb +117 -0
  24. data/lib/ruby-next/language/bootsnap.rb +26 -0
  25. data/lib/ruby-next/language/eval.rb +64 -0
  26. data/lib/ruby-next/language/parser.rb +24 -0
  27. data/lib/ruby-next/language/rewriters/args_forward.rb +57 -0
  28. data/lib/ruby-next/language/rewriters/base.rb +105 -0
  29. data/lib/ruby-next/language/rewriters/endless_range.rb +60 -0
  30. data/lib/ruby-next/language/rewriters/method_reference.rb +31 -0
  31. data/lib/ruby-next/language/rewriters/numbered_params.rb +41 -0
  32. data/lib/ruby-next/language/rewriters/pattern_matching.rb +522 -0
  33. data/lib/ruby-next/language/runtime.rb +96 -0
  34. data/lib/ruby-next/language/setup.rb +43 -0
  35. data/lib/ruby-next/language/unparser.rb +8 -0
  36. data/lib/ruby-next/utils.rb +36 -0
  37. data/lib/ruby-next/version.rb +5 -0
  38. data/lib/uby-next.rb +68 -0
  39. metadata +117 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 920bab371a964915799cae3423ebe43f77d54986a904da19e9c868efe309fc42
4
+ data.tar.gz: a19414277a1cc30b1f7863d765026b2c20162d51ae6aadd84def479915a641bd
5
+ SHA512:
6
+ metadata.gz: c72c42d6ef93f871448e50d15d935001973347450b6cfc47eef3c455ffcbfee18c33e03e761315571fa4010535c0649b82882b38e951229d6141f82b45fe01af
7
+ data.tar.gz: 1ba4bac7b1a9c18abfc07fb9304b92393ffa61659e80d4cb99d91c606569331a3ca0cd35eb9cd64a7078dbd905cdf417abf35b24ca7742dc8eb466625d53a3f2
data/CHANGELOG.md ADDED
@@ -0,0 +1,68 @@
1
+ # Change log
2
+
3
+ ## master
4
+
5
+ ## 0.2.0 (2020-01-13) 🎄
6
+
7
+ - Add `Enumerator.produce`. ([@palkan][])
8
+
9
+ - Add Bootsnap integration. ([@palkan][])
10
+
11
+ Add `require "ruby-next/language/bootsnap"` after setting up Bootsnap
12
+ to transpile the files on load (and cache the resulted iseq via Bootsnap as usually).
13
+
14
+ - Do not patch `eval` and friends when using runtime mode. ([@palkan][])
15
+
16
+ Eval support should be enabled explicitly via the `RubyNext::Language::Eval` refinement, 'cause we cannot handle all the edge cases easily (e.g., the usage caller's binding locals).
17
+
18
+ - Revoke method reference support. ([@palkan][])
19
+
20
+ You can still use this feature by enabling it explicitly (see Readme).
21
+
22
+ - Support in modifier. ([@palkan][])
23
+
24
+ ```ruby
25
+ {a:1, b: 2} in {a:, **}
26
+ p a #=> 1
27
+ ```
28
+
29
+ ## 0.1.0 (2019-11-18)
30
+
31
+ - Support hash pattern in array and vice versa. ([@palkan][])
32
+
33
+ - Handle multile `-e` in `uby-next`. ([@palkan][])
34
+
35
+ ## 0.1.0 (2019-11-16)
36
+
37
+ - Add pattern matching. ([@palkan][])
38
+
39
+ - Add numbered parameters. ([@palkan][])
40
+
41
+ - Add arguments forwarding. ([@palkan][])
42
+
43
+ - Add `Enumerable#filter_map`. ([@palkan][])
44
+
45
+ - Add `Enumerable#filter/filter!`. ([@palkan][])
46
+
47
+ - Add multiple arguments support to `Hash#merge`. ([@palkan][])
48
+
49
+ - Add `Array#intersection`, `Array#union`, `Array#difference`. ([@palkan][])
50
+
51
+ - Add `Enumerable#tally`. ([@palkan][])
52
+
53
+ - Implement gem integration flow. ([@palkan][])
54
+
55
+ - Transpile code via `ruby-next nextify`.
56
+ - Setup load path via `RubyNext::Language.setup_gem_load_Path`.
57
+
58
+ - Add `ruby-next nextify` command. ([@palkan][])
59
+
60
+ - Add endless Range support. ([@palkan][])
61
+
62
+ - Add method reference syntax support. ([@palkan][])
63
+
64
+ - Add `Proc#<<` and `Proc#>>`. ([@palkan][])
65
+
66
+ - Add `Kernel#then`. ([@palkan][])
67
+
68
+ [@palkan]: https://github.com/palkan
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Vladimir Dementyev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,279 @@
1
+ [![Gem Version](https://badge.fury.io/rb/ruby-next.svg)](https://rubygems.org/gems/ruby-next) [![Build](https://github.com/ruby-next/ruby-next/workflows/Build/badge.svg)](https://github.com/ruby-next/ruby-next/actions)
2
+ [![JRuby Build](https://github.com/ruby-next/ruby-next/workflows/JRuby%20Build/badge.svg)](https://github.com/ruby-next/ruby-next/actions)
3
+
4
+ # Ruby Next
5
+
6
+ > Make all Rubies quack like edge Ruby!
7
+
8
+ Ruby Next is a collection of **polyfills** and a **transpiler** for supporting the latest and upcoming Ruby features (APIs and syntax) in older versions and alternative implementations. For example, you can use pattern matching and `Kernel#then` in Ruby 2.5 or [mruby][].
9
+
10
+ Who might be interested in Ruby Next?
11
+
12
+ - **Ruby gems maintainers** who want to write code using the latest Ruby version but still support older ones.
13
+ - **Application developers** who want to give new features a try without waiting for the final release (or, more often, for the first patch).
14
+ - **Users of non-MRI implementations** such as [mruby][], [JRuby][], [TruffleRuby][], [Opal][], [RubyMotion][], [Artichoke][], [Prism][].
15
+
16
+ Ruby Next also aims to help the community to assess new, _experimental_, MRI features by making it easier to play with them.
17
+ That's why Ruby Next implements the `trunk` features as fast as possible.
18
+
19
+ _⚡️ The project is in a **beta** phase. That means that the main functionality has been implemented (see [the list][features]) and APIs shouldn't change a lot in the nearest future. On the other hand, the number of users/projects is not enough to say we're "production-ready". So, can't wait to hear your feedback 🙂_
20
+
21
+ ## Links
22
+
23
+ - [Ruby Next: Make old Rubies quack like a new one](https://noti.st/palkan/j3i2Dr/ruby-next-make-old-rubies-quack-like-a-new-one) (RubyConf 2019)
24
+
25
+ ## Overview
26
+
27
+ Ruby Next consists of two parts: **core** and **language**.
28
+
29
+ Core provides **polyfills** for Ruby core classes APIs via Refinements.
30
+ Thus, polyfills are only available in compatible runtimes (MRI, JRuby, TruffleRuby).
31
+
32
+ Language is responsible for **transpiling** edge Ruby syntax into older versions. It could be done
33
+ programmatically or via CLI. It also could be done in runtime.
34
+
35
+ Currently, Ruby Next supports Ruby versions 2.5+ (including JRuby 9.2.8+).
36
+ Please, [open an issue](https://github.com/ruby-next/ruby-next/issues/new/choose) if you would like us to support older Ruby versions.
37
+
38
+ ## Using only polyfills
39
+
40
+ First, install a gem:
41
+
42
+ ```ruby
43
+ # Gemfile
44
+ gem "ruby-next-core"
45
+
46
+ # gemspec
47
+ spec.add_dependency "ruby-next-core"
48
+ ```
49
+
50
+ **NOTE:** we use the different _distribution_ gem, `ruby-next-core`, to provide zero-dependency, polyfills-only version.
51
+
52
+ Then, all you need is to load the Ruby Next:
53
+
54
+ ```ruby
55
+ require "ruby-next"
56
+ ```
57
+
58
+ And activate the refinement in every file where you want to use it\*:
59
+
60
+ ```ruby
61
+ using RubyNext
62
+ ```
63
+
64
+ Ruby Next only refines core classes if necessary; thus, this line wouldn't have any effect in the edge Ruby.
65
+
66
+ [**The list of supported APIs.**][features_core]
67
+
68
+ ## Transpiling, or using edge Ruby syntax features
69
+
70
+ Ruby Next transpiler relies on two libraries: [parser][] and [unparser][].
71
+
72
+ **NOTE:** The "official" parser gem only supports the latest stable Ruby version, while Ruby Next aims to support edge and experimental Ruby features. To enable them, you should use our version of Parser (see [instructions](#using-ruby-next-parser) below).
73
+
74
+ Installation:
75
+
76
+ ```ruby
77
+ # Gemfile
78
+ gem "ruby-next"
79
+
80
+ # gemspec
81
+ spec.add_dependency "ruby-next"
82
+
83
+ # or install globally
84
+ gem install ruby-next
85
+ ```
86
+
87
+ [**The list of supported syntax features.**][features_syntax]
88
+
89
+ ### Integrating into a gem development
90
+
91
+ We recommend _pre-transpiling_ source code to work with older versions before releasing it.
92
+
93
+ This is how you can do that with Ruby Next:
94
+
95
+ - Write source code using the modern/edge Ruby syntax.
96
+
97
+ - Generate transpiled code by calling `ruby-next nextify ./lib` (e.g., before releasing or pushing to VCS).
98
+
99
+ This will produce `lib/.rbnext` folder containing the transpiled files, `lib/.rbnext/2.6`, `lib/.rbnext/2.7`. The version in the path indicates which Ruby version is required for the original functionality. Only the source files containing new syntax are added to this folder.
100
+
101
+ **NOTE:** Do not edit these files manually, either run linters/type checkers/whatever against these files.
102
+
103
+ - Add the following code to your gem's _entrypoint_ (the file that is required first and contains other `require`-s):
104
+
105
+ ```ruby
106
+ require "ruby-next/language/setup"
107
+
108
+ RubyNext::Language.setup_gem_load_path
109
+ ```
110
+
111
+ The `setup_gem_load_path` does the following:
112
+
113
+ - Resolves the current ruby version.
114
+ - Checks whether there are directories corresponding to the current and earlier\* Ruby versions within the `.rbnext` folder.
115
+ - Add the path to this directory to the `$LOAD_PATH` before the path to the gem's directory.
116
+
117
+ That's why need an _entrypoint_: all the subsequent `require` calls will load the transpiled files instead of the original ones
118
+ due to the way feature resolving works in Ruby (scanning the `$LOAD_PATH` and halting as soon as the matching file is found).
119
+
120
+ **NOTE:** `require_relative` should be avoided due to the way we _hijack_ the features loading mechanism.
121
+
122
+ \* Ruby Next avoids storing duplicates; instead, only the code for the earlier version is created and is assumed to be used with other versions. For example, if the transpiled code is the same for Ruby 2.5 and Ruby 2.6, only the `.rbnext/2.7/path/to/file.rb` is kept. That's why multiple entries are added to the `$LOAD_PATH` (`.rbnext/2.6` and `.rbnext/2.7` in the specified order for Ruby 2.5 and only `.rbnext/2.7` for Ruby 2.6).
123
+
124
+ ## CLI
125
+
126
+ Ruby Next ships with the command-line interface (`ruby-next`) which provides the following functionality:
127
+
128
+ - `ruby-next nextify` — transpile file or directory into older Rubies (see, for example, the "Integrating into a gem development" section above).
129
+
130
+ It has the following interface:
131
+
132
+ ```sh
133
+ $ ruby-next nextify
134
+ Usage: ruby-next nextify DIRECTORY_OR_FILE [options]
135
+ -o, --output=OUTPUT Specify output directory or file
136
+ --min-version=VERSION Specify the minimum Ruby version to support
137
+ --single-version Only create one version of a file (for the earliest Ruby version)
138
+ -V Turn on verbose mode
139
+ ```
140
+
141
+ The behaviour depends on whether you transpile a single file or a directory:
142
+
143
+ - When transpiling a directory, the `.rbnext` subfolder is created within the target folder with subfolders for each supported Ruby versions (e.g., `.rbnext/2.6`, `.rbnext/2.7`). If you want to create only a single version (the smallest), you can also pass `--single-version` flag. In that case, no version directory is created (i.e., transpiled files go into `.rbnext`).
144
+
145
+ - When transpiling a file and providing the output path as a _file_ path, only a single version is created. For example:
146
+
147
+ ```sh
148
+ $ ruby-next nextify my_ruby.rb -o my_ruby_next.rb -V
149
+ Generated: my_ruby_next.rb
150
+ ```
151
+
152
+ ## Runtime mode
153
+
154
+ It is also possible to transpile Ruby source code in run-time via Ruby Next.
155
+
156
+ All you need is to `require "ruby-next/language/runtime"` as early as possible to hijack `Kernel#require` and friends.
157
+ You can also automatically inject `using RubyNext` to every\* loaded file by also adding `require "ruby-next/core/runtime"`.
158
+
159
+ Since the runtime mode requires Kernel monkey-patching, it should be used carefully. For example, we use it in Ruby Next tests—works perfectly. But think twice before enabling it in production.
160
+
161
+ Consider using [Bootsnap](#using-with-bootsnap) integration, 'cause its monkey-patching has been bullet-proofed 😉.
162
+
163
+ \* Ruby Next doesn't hijack every required file but _watches_ only the configured directories: `./app/`, `./lib/`, `./spec/`, `./test/` (relative to the `pwd`). You can configure the watch dirs:
164
+
165
+ ```ruby
166
+ RubyNext::Language.watch_dirs << "path/to/other/dir"
167
+ ```
168
+
169
+ ### Eval & similar
170
+
171
+ By default, we do not hijack `Kernel.eval` and similar methods due to some limitations (e.g., there is no easy and efficient way to access the caller's scope, or _binding_, and some evaluations relies on local variables).
172
+
173
+ If you want to support transpiling in `eval`-like methods, opt-in explicitly by activating the refinement:
174
+
175
+ ```ruby
176
+ using RubyNext::Language::Eval
177
+ ```
178
+
179
+ ## Using with Bootsnap
180
+
181
+ [Bootsnap][] is a great tool to speed-up your application load and it's included into the default Rails Gemfile. It patches Ruby mechanism of loading source files to make it possible to cache the intermediate representation (_iseq_).
182
+
183
+ Ruby Next provides a specific integration which allows to add a transpiling step to this process, thus making the transpiler overhead as small as possible, because the cached and **already transpiled** version is used if no changes were made.
184
+
185
+ To enable this integration, add the following line after the `require "bootsnap/setup"`:
186
+
187
+ ```ruby
188
+ require "ruby-next/language/bootsnap"
189
+ ```
190
+
191
+ **NOTE:** there is no way to invalidate the cache when you upgrade Ruby Next (e.g., due to the bug fixes), so you should do this manually.
192
+
193
+ ## `uby-next`
194
+
195
+ You can also enable runtime mode by requiring `uby-next` while running a Ruby executable:
196
+
197
+ ```sh
198
+ ruby -ruby-next my_ruby_script.rb
199
+
200
+ # or
201
+ RUBYOPT="-ruby-next" ruby my_ruby_script.rb
202
+
203
+ # or
204
+ ruby -ruby-next -e "puts [2, 4, 5].tally"
205
+ ```
206
+
207
+ ## Unofficial/experimental features
208
+
209
+ Ruby Next also provides support for some features not-yet-merged into Ruby master (or reverted).
210
+
211
+ These features require a [custom parser](#using-ruby-next-parser).
212
+
213
+ Currenly, the only such feature is the [_method reference_ operator](https://bugs.ruby-lang.org/issues/13581):
214
+
215
+ - Add `--enable-method-reference` option to `nextify` command when using CLI.
216
+ - OR add it programmatically when using a runtime mode (see [example](https://github.com/ruby-next/ruby-next/blob/master/default.mspec)).
217
+ - OR set `RUBY_NEXT_ENABLE_METHOD_REFERENCE=1` environment variable (works with CLI as well).
218
+
219
+ ## Using Ruby Next parser
220
+
221
+ ### Prerequisites
222
+
223
+ Our own version of [parser][next_parser] gem is hosted on Github Package Registry. That makes the installation process a bit more complicated than usual.
224
+
225
+ You must obtain an access token to use it. See the [GPR docs](https://help.github.com/en/github/managing-packages-with-github-package-registry/configuring-rubygems-for-use-with-github-package-registry#authenticating-to-github-package-registry).
226
+
227
+ ### Installing with Bundler
228
+
229
+ First, configure your bundler to access GPR:
230
+
231
+ ```sh
232
+ bundle config --local https://rubygems.pkg.github.com/ruby-next USERNAME:ACCESS_TOKEN
233
+ ```
234
+
235
+ Then, add to your Gemfile:
236
+
237
+ ```ruby
238
+ source "https://rubygems.pkg.github.com/ruby-next" do
239
+ gem "parser", "2.7.0.100"
240
+ end
241
+
242
+ gem "ruby-next"
243
+ ```
244
+
245
+ **NOTE:** we don't add `parser` and `unparser` to the gem's runtime deps, 'cause they're not necessary if you only need polyfills.
246
+
247
+ ### Installing globally via `gem`
248
+
249
+ You can install `ruby-next` globally by running the following commands:
250
+
251
+ ```sh
252
+ gem install parser -v "2.7.0.100" --source "https://USERNAME:ACCESS_TOKEN@rubygems.pkg.github.com/ruby-next"
253
+ gem install ruby-next
254
+ ```
255
+
256
+ ## Contributing
257
+
258
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/ruby-next/ruby-next](ttps://github.com/ruby-next/ruby-next).
259
+
260
+ See also the [development guide](./DEVELOPMENT.md).
261
+
262
+ ## License
263
+
264
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
265
+
266
+ [features]: ./SUPPORTED_FEATURES.md
267
+ [features_core]: ./SUPPORTED_FEATURES.md#Core
268
+ [features_syntax]: ./SUPPORTED_FEATURES.md#Syntax
269
+ [mruby]: https://mruby.org
270
+ [JRuby]: https://www.jruby.org
271
+ [TruffleRuby]: https://github.com/oracle/truffleruby
272
+ [Opal]: https://opalrb.com
273
+ [RubyMotion]: http://www.rubymotion.com
274
+ [Artichoke]: https://github.com/artichoke/artichoke
275
+ [Prism]: https://github.com/prism-rb/prism
276
+ [parser]: https://github.com/whitequark/parser
277
+ [unparser]: https://github.com/mbj/unparser
278
+ [next_parser]: https://github.com/ruby-next/parser
279
+ [Bootsnap]: https://github.com/Shopify/bootsnap
data/bin/parse ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path("../../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ $VERBOSE = nil
6
+
7
+ require "bundler/setup"
8
+
9
+ require "ruby-next/language"
10
+
11
+ contents =
12
+ if File.exist?(ARGV[0])
13
+ File.read(ARGV[0])
14
+ else
15
+ ARGV[0]
16
+ end
17
+
18
+ ast = RubyNext::Language.parse(contents)
19
+ puts ast
data/bin/ruby-next ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_path = File.expand_path("../lib", __dir__)
4
+ $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
5
+
6
+ require "ruby-next/cli"
7
+
8
+ begin
9
+ cli = RubyNext::CLI.new
10
+ cli.run(ARGV)
11
+ rescue => e
12
+ raise e if $DEBUG
13
+ STDERR.puts e.message
14
+ STDERR.puts e.backtrace.join("\n")
15
+ exit 1
16
+ end
data/bin/transform ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path("../../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require "bundler/setup"
7
+
8
+ require "ruby-next/language"
9
+
10
+ # optional parsers
11
+ require "ruby-next/language/rewriters/method_reference"
12
+ RubyNext::Language.rewriters << RubyNext::Language::Rewriters::MethodReference
13
+
14
+ contents =
15
+ if File.exist?(ARGV[0])
16
+ File.read(ARGV[0])
17
+ else
18
+ ARGV[0]
19
+ end
20
+
21
+ puts RubyNext::Language.transform(contents)
data/lib/ruby-next.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby-next/version"
4
+
5
+ module RubyNext
6
+ # Mininum Ruby version supported by RubyNext
7
+ MIN_SUPPORTED_VERSION = Gem::Version.new("2.5.0")
8
+
9
+ # Where to store transpiled files (relative from the project LOAD_PATH, usually `lib/`)
10
+ RUBY_NEXT_DIR = ".rbnext"
11
+
12
+ # Defines last minor version for every major version
13
+ LAST_MINOR_VERSIONS = {
14
+ 2 => 7
15
+ }.freeze
16
+
17
+ LATEST_VERSION = [2, 7].freeze
18
+
19
+ class << self
20
+ def next_version(version = RUBY_VERSION)
21
+ major, minor = Gem::Version.new(version).segments.map(&:to_i)
22
+
23
+ return if major >= LATEST_VERSION.first && minor >= LATEST_VERSION.last
24
+
25
+ nxt =
26
+ if LAST_MINOR_VERSIONS[major] == minor
27
+ "#{major + 1}.0.0"
28
+ else
29
+ "#{major}.#{minor + 1}.0"
30
+ end
31
+
32
+ Gem::Version.new(nxt)
33
+ end
34
+ end
35
+
36
+ require_relative "ruby-next/core"
37
+ end