Ruby Next makes modern Ruby code run in older versions and alternative implementations
We glad to announce first major release! It indicates both stability we achieved over the years and the initial roadmap completion.
Text rewriters.
We made experimenting with Ruby syntax as simple as possible by introducing text rewriters. No need to manipulate ASTs or write your own parser. Text rewriters allow you manipulate Ruby code the way you prefer (regexps, strings scanners, etc.). You can also use our new parse combinator library, Paco, to have more control over transformations. Read more in the documentation.
Robust runtime transpiling with require-hooks.
We extracted functionality to hijack Ruby's require/load mechanism into a standalone gem, require-hooks. It passes most of the Ruby Spec and provides a universal interface to interfere with code loading for major Ruby implementations.
it
block parameter support from Ruby 3.4 (proc { it }.call("ruby-next") == "ruby-next"
).def foo(*, **); bar(*, **) end
).MatchData#deconstruct
, MatchData#deconstruct_keys
, Time#deconstruct_keys
Read more in our changelog.
P.S. Happy holidays 🎄
This release brings Ruby 3.1 features and more.
42 => @v
) (#18408).This brings back rightward assignment: 42 => @v
.
Shorthand Hash/kwarg notation (data = {x:, y:}
or foo(x:, y:)
) (#15236).
Pinning instance, class and global variables and expressions (#17724, #17411).
Anonymous blocks def b(&); c(&); end
(#11256).
Command syntax in endless methods (def foo() = puts "bar"
) (#17398)
Support omitting parentheses in one-line pattern matching ({a: 1} in a:
)
Refinement#import_methods
(#17429)(There are some limitations though).
Where "partial" means that you can generate Ruby 2.0 compatible source code via Ruby Next, but Ruby Next itself still requires Ruby 2.2+.
This release is dedicated to the upcoming release of Ruby 3.0.
case v; in [*, 42, *]; true; end
)def foo() = "bar"
)def foo(...) = bar(1, ...)
).a => x
)a in x
single-line pattern matching changed to comply with Ruby 3.0 (returns true/false
instead of raising errors).we also extended the proposed shorthand Hash syntax to support kwargs in method calls as well:
x = 1
y = 2
foo x:, y: #= foo x: x, y: y
Could this be the future Ruby? Share your thoughts!.
RubyKaigi 2020 special.
From https://bugs.ruby-lang.org/issues/15236.
Give it a try: x = 1; y = 2; data = {x, y}
.
Here is a real-life example usage: https://github.com/anycable/anycable_rails_demo/commit/d4ee4c614083d633edd9fb2601f1764860ff6f34
Example: [0, 1, 2] in [*, 1 => a, *c]
.
Example: def a(...) b(1, ...); end
.
Hash#except
.Example: {a: 1, b: 2}.except(:a) == {b: 2}
With support for safe navigation operator (&.
) and squiggly heredocs (<<~TXT
).
Now we use ruby-next-parser
gem which adds the next parser capabilities to the official Parser gem.
Use --edge
or --proposed
flags for ruby-next nextify
or
require "ruby-next/language/{edge,proposed}"
in your code.
See more in the Readme.
Make sure you use TargetRubyVersion: next
in your RuboCop configuration.
That's a preliminary step to make unreleased Ruby features work with RuboCop.
Added rewrite
transpiler mode.
Add support for rewriting the source code instead of rebuilding it from scratch to preserve the original layout and improve the debugging experience.
Currently, disable by default. Opt-in via:
-RUBY_NEXT_TRANSPILE_MODE=rewrite
RubyNext::Language.mode = :rewrite
ruby-next nextify --transpile-mode=rewrite
.