Description
NEWS for Ruby 3.2.0
This document is a list of user-visible feature changes
since the 3.1.0 release, except for bug fixes.
Note that each entry is kept to a minimum, see links for details.
Language changes
-
Anonymous rest and keyword rest arguments can now be passed as
arguments, instead of just used in method parameters.
[Feature #18351]def foo(*) bar(*) end def baz(**) quux(**) end
-
A proc that accepts a single positional argument and keywords will
no longer autosplat. [Bug #18633]proc{|a, **k| a}.call([1, 2]) # Ruby 3.1 and before # => 1 # Ruby 3.2 and after # => [1, 2]
-
Constant assignment evaluation order for constants set on explicit
objects has been made consistent with single attribute assignment
evaluation order. With this code:foo::BAR = baz
foo
is now called beforebaz
. Similarly, for multiple assignments
to constants, left-to-right evaluation order is used. With this
code:foo1::BAR1, foo2::BAR2 = baz1, baz2
The following evaluation order is now used:
foo1
foo2
baz1
baz2
-
"Find pattern" is no longer experimental.
[Feature #18585] -
Methods taking a rest parameter (like
*args
) and wishing to delegate keyword
arguments throughfoo(*args)
must now be marked withruby2_keywords
(if not already the case). In other words, all methods wishing to delegate
keyword arguments through*args
must now be marked withruby2_keywords
,
with no exception. This will make it easier to transition to other ways of
delegation once a library can require Ruby 3+. Previously, theruby2_keywords
flag was kept if the receiving method took*args
, but this was a bug and an
inconsistency. A good technique to find the potentially-missingruby2_keywords
is to run the test suite, for where it fails find the last method which must
receive keyword arguments, useputs nil, caller, nil
there, and check each
method/block on the call chain which must delegate keywords is correctly marked
asruby2_keywords
. [Bug #18625] [Bug #16466]def target(**kw) end # Accidentally worked without ruby2_keywords in Ruby 2.7-3.1, ruby2_keywords # needed in 3.2+. Just like (*args, **kwargs) or (...) would be needed on # both #foo and #bar when migrating away from ruby2_keywords. ruby2_keywords def bar(*args) target(*args) end ruby2_keywords def foo(*args) bar(*args) end foo(k: 1)
-
eval
and related methods are able to generate code coverage. Enabled using
Coverage.setup(:all)
orCoverge.setup(eval: true)
. [Feature #19008] -
Coverage.supported?(mode)
enables detection of what coverage modes are
supported. [Feature #19026]
Command line options
Core classes updates
Note: We're only listing outstanding class updates.
-
Fiber
-
Introduce Fiber.[] and Fiber.[]= for inheritable fiber storage.
Introduce Fiber#storage and Fiber#storage= (experimental) for
getting and resetting the current storage. Introduce
Fiber.new(storage:)
for setting the storage when creating a
fiber. [Feature #19078]Existing Thread and Fiber local variables can be tricky to use.
Thread local variables are shared between all fibers, making it
hard to isolate, while Fiber local variables can be hard to
share. It is often desirable to define unit of execution
("execution context") such that some state is shared between all
fibers and threads created in that context. This is what Fiber
storage provides.def log(message) puts "#{Fiber[:request_id]}: #{message}" end def handle_requests while request = read_request Fiber.schedule do Fiber[:request_id] = SecureRandom.uuid request.messages.each do |message| Fiber.schedule do log("Handling #{message}") # Log includes inherited request_id. end end end end end
You should generally consider Fiber storage for any state which
you want to be shared implicitly between all fibers and threads
created in a given context, e.g. a connection pool, a request
id, a logger level, environment variables, configuration, etc.
-
-
Fiber::Scheduler
- Introduce
Fiber::Scheduler#io_select
for non-blocking IO.select.
[Feature #19060]
- Introduce
-
IO
-
Introduce IO#timeout= and IO#timeout which can cause
IO::TimeoutError to be raised if a blocking operation exceeds the
specified timeout. [Feature #18630] Start implementing IO#timeout #8662STDIN.timeout = 1 STDIN.read # => Blocking operation timed out! (IO::TimeoutError)
-
-
UNIXSocket
- Add support for UNIXSocket on Windows. Emulate anonymous sockets. Add
support for File.socket? and File::Stat#socket? where possible.
[Feature #19135]
- Add support for UNIXSocket on Windows. Emulate anonymous sockets. Add
-
Class
-
Class#attached_object, which returns the object for which
the receiver is the singleton class. Raises TypeError if the
receiver is not a singleton class.
[Feature #12084]class Foo; end Foo.singleton_class.attached_object #=> Foo Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370> Foo.attached_object #=> TypeError: `Foo' is not a singleton class nil.singleton_class.attached_object #=> TypeError: `NilClass' is not a singleton class
-
-
Data
- New core class to represent simple immutable value object. The class is
similar to Struct and partially shares an implementation, but has more
lean and strict API. [Feature #16122]
- New core class to represent simple immutable value object. The class is
-
Encoding
- Encoding#replicate has been deprecated and will be removed in 3.3. [Feature #18949]
- The dummy
Encoding::UTF_16
andEncoding::UTF_32
encodings no longer
try to dynamically guess the endian based on a byte order mark.
UseEncoding::UTF_16BE
/UTF_16LE
andEncoding::UTF_32BE
/UTF_32LE
instead.
This change speeds up getting the encoding of a String. [Feature #18949]
-
Enumerator
- Enumerator.product has been added. Enumerator::Product is the implementation. [Feature #18685]
-
Exception
- Exception#detailed_message has been added.
The default error printer calls this method on the Exception object
instead of #message. [Feature #18564]
- Exception#detailed_message has been added.
-
Hash
- Hash#shift now always returns nil if the hash is
empty, instead of returning the default value or
calling the default proc. [Bug #16908]
- Hash#shift now always returns nil if the hash is
-
Integer
- Integer#ceildiv has been added. [Feature #18809]
-
Kernel
- Kernel#binding raises RuntimeError if called from a non-Ruby frame
(such as a method defined in C). [Bug #18487]
- Kernel#binding raises RuntimeError if called from a non-Ruby frame
-
MatchData
- MatchData#byteoffset has been added. [Feature #13110]
- MatchData#deconstruct has been added. [Feature #18821]
- MatchData#deconstruct_keys has been added. [Feature #18821]
-
Module
- Module.used_refinements has been added. [Feature #14332]
- Module#refinements has been added. [Feature #12737]
- Module#const_added has been added. [Feature #17881]
- Module#undefined_instance_methods has been added. [Feature #12655]
-
Proc
- Proc#dup returns an instance of subclass. [Bug #17545]
- Proc#parameters now accepts lambda keyword. [Feature #15357]
-
Process
- Added
RLIMIT_NPTS
constant to FreeBSD platform
- Added
-
Regexp
-
Regexp.new now supports passing the regexp flags not only as an Integer,
but also as a String. Unknown flags raise ArgumentError.
Otherwise, anything other thantrue
,false
,nil
or Integer will be warned.
[Feature #18788] -
Regexp.timeout= has been added. Also, Regexp.new new supports timeout keyword.
See [Feature #17837]
-
-
Refinement
- Refinement#refined_class has been added. [Feature #12737]
-
RubyVM::AbstractSyntaxTree
-
Add
error_tolerant
option forparse
,parse_file
andof
. [Feature #19013]
With this option- SyntaxError is suppressed
- AST is returned for invalid input
end
is complemented when a parser reachs to the end of input butend
is insufficientend
is treated as keyword based on indent
# Without error_tolerant option root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY) def m a = 10 if end RUBY # => <internal:ast>:33:in `parse': syntax error, unexpected `end' (SyntaxError) # With error_tolerant option root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true) def m a = 10 if end RUBY p root # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-4:3> # `end` is treated as keyword based on indent root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true) module Z class Foo foo. end def bar end end RUBY p root.children[-1].children[-1].children[-1].children[-2..-1] # => [#<RubyVM::AbstractSyntaxTree::Node:CLASS@2:2-4:5>, #<RubyVM::AbstractSyntaxTree::Node:DEFN@6:2-7:5>]
-
Add
keep_tokens
option forparse
,parse_file
andof
. Add#tokens
and#all_tokens
for RubyVM::AbstractSyntaxTree::Node [Feature #19070]root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true) root.tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...] root.tokens.map{_1[2]}.join # => "x = 1 + 2"
-
-
Set
- Set is now available as a built-in class without the need for
require "set"
. [Feature #16989]
It is currently autoloaded via the Set constant or a call to Enumerable#to_set.
- Set is now available as a built-in class without the need for
-
Socket
- Added the following constants for supported platforms.
SO_INCOMING_CPU
SO_INCOMING_NAPI_ID
SO_RTABLE
SO_SETFIB
SO_USER_COOKIE
TCP_KEEPALIVE
TCP_CONNECTION_INFO
- Added the following constants for supported platforms.
-
String
- String#byteindex and String#byterindex have been added. [Feature #13110]
- Update Unicode to Version 15.0.0 and Emoji Version 15.0. [Feature #18639]
(also applies to Regexp) - String#bytesplice has been added. [Feature #18598]
-
Struct
- A Struct class can also be initialized with keyword arguments
withoutkeyword_init: true
on Struct.new [Feature #16806]
- A Struct class can also be initialized with keyword arguments
-
Time
- Time#deconstruct_keys is added, allowing to use Time instances
in pattern-matching expressions [Feature #19071]
- Time#deconstruct_keys is added, allowing to use Time instances
-
SyntaxError
- SyntaxError#path has been added. [Feature #19138]
-
TracePoint
- TracePoint#binding now returns
nil
forc_call
/c_return
TracePoints.
[Bug #18487] - TracePoint#enable
target_thread
keyword argument now defaults to the
current thread iftarget
andtarget_line
keyword arguments are not
passed. [Bug #16889]
- TracePoint#binding now returns
Stdlib updates
Note: Most of these updates are superseded by those in #8029.
-
ERB
-
-S
option is removed fromerb
command.
-
-
FileUtils
- Add FileUtils.ln_sr method and
relative:
option to FileUtils.ln_s.
[Feature #18925]
- Add FileUtils.ln_sr method and
-
SyntaxSuggest
- The feature of
syntax_suggest
formerlydead_end
is integrated in Ruby.
[Feature #18159] - Update once syntax_suggest CLI doesn't work when it is a standard gem ruby/syntax_suggest#215 is addressed.
- The feature of
-
The following default gems are updated.
- RubyGems 3.4.0.dev
- benchmark 0.2.1
- bigdecimal 3.1.3
- bundler 2.4.0.dev
- cgi 0.3.6
- date 3.3.0
- delegate 0.3.0
- did_you_mean 1.6.2
- digest 3.1.1
- drb 2.1.1
- erb 4.0.2
- error_highlight 0.5.1
- etc 1.4.1
- fcntl 1.0.2
- fiddle 1.1.1
- fileutils 1.7.0
- forwardable 1.3.3
- getoptlong 0.2.0
- io-console 0.5.11
- io-nonblock 0.2.0
- io-wait 0.3.0.pre
- ipaddr 1.2.5
- irb 1.5.1
- json 2.6.2
- logger 1.5.2
- mutex_m 0.1.2
- net-http 0.3.1
- net-protocol 0.2.0
- nkf 0.1.2
- open-uri 0.3.0
- openssl 3.1.0.pre
- optparse 0.3.0
- ostruct 0.5.5
- pathname 0.2.1
- pp 0.4.0
- pstore 0.1.2
- psych 5.0.0
- racc 1.6.1
- rdoc 6.5.0
- reline 0.3.1
- resolv 0.2.2
- securerandom 0.2.1
- set 1.0.3
- stringio 3.0.3
- syntax_suggest 1.0.1
- timeout 0.3.1
- tmpdir 0.1.3
- tsort 0.1.1
- un 0.2.1
- uri 0.12.0
- win32ole 1.8.9
- zlib 3.0.0
-
The following bundled gems are updated.
- minitest 5.16.3
- power_assert 2.0.2
- test-unit 3.5.5
- net-ftp 0.2.0
- net-imap 0.3.1
- net-pop 0.1.2
- net-smtp 0.3.3
- rbs 2.8.1
- typeprof 0.21.3
- debug 1.7.0
Compatibility issues
Note: Excluding feature bug fixes.
Removed constants
The following deprecated constants are removed.
-
Fixnum
andBignum
[Feature #12005] -
Random::DEFAULT
[Feature #17351] -
Struct::Group
-
Struct::Passwd
Removed methods
The following deprecated methods are removed.
-
Dir.exists?
[Feature #17391] -
File.exists?
[Feature #17391] -
Kernel#=~
[Feature #15231] -
Kernel#taint
,Kernel#untaint
,Kernel#tainted?
[Feature #16131] -
Kernel#trust
,Kernel#untrust
,Kernel#untrusted?
[Feature #16131]