Project

General

Profile

Actions

Bug #22293

open

`String#unicode_normalize` does not work in non-main Ractor

Bug #22293: `String#unicode_normalize` does not work in non-main Ractor

Added by nobu (Nobuyoshi Nakada) 4 days ago. Updated about 18 hours ago.

Status:
Open
Target version:
-
[ruby-core:126572]

Description

This fails consistently since Ruby 3.0 (except for using #take instead of #value).

$ ruby -v -W:no-ex -e 'p Ractor.new{"aaa".unicode_normalize}.value'
ruby 4.1.0dev (2026-09-04T13:17:34Z master 3643154e6d) +PRISM [arm64-darwin25]
#<Thread:0x0000000123bf0008 run> terminated with exception (report_on_exception is true):
/opt/local/lib/ruby/4.1.0+4/unicode_normalize/normalize.rb:138:in 'UnicodeNormalize.normalize': can not access non-shareable objects in constant UnicodeNormalize::NF_HASH_C by non-main ractor. (Ractor::IsolationError)
	from -e:1:in 'String#unicode_normalize'
	from -e:1:in 'block in <main>'
-e:1:in 'Ractor#value': thrown by remote Ractor. (Ractor::RemoteError)
	from -e:1:in '<main>'
/opt/local/lib/ruby/4.1.0+4/unicode_normalize/normalize.rb:138:in 'UnicodeNormalize.normalize': can not access non-shareable objects in constant UnicodeNormalize::NF_HASH_C by non-main ractor. (Ractor::IsolationError)
	from -e:1:in 'String#unicode_normalize'
	from -e:1:in 'block in <main>'

Updated by duerst (Martin Dürst) about 18 hours ago Actions #1 [ruby-core:126587]

Just some comments to hopefully help this issue move forward.

unicode_normalize uses two hashes, UnicodeNormalize::NF_HASH_C and UnicodeNormalize::NF_HASH_D. These hashes are used to cache results of composition (NF_HASH_C) or decomposition (NF_HASH_D). They are updated with default procs when a key is not found (i.e. when the result of a normalization operation isn't already in the hash, and therefore has to be calculated.)

As long as the default proc isn't triggered, using unicode_normalize in parallel in two different ractors (or threads, or fibers, or anything else of that sort) is fine. But when the default proc is executed, the hash can change.

If the two key for which the default proc is executed in parallel are the same, then resulting value will also be the same (because Unicode normalization is deterministic).

I do not know the implementation of Hash in detail. If it can be used in parallel in threads and the like, it should be possible to get unicode_normalize to work in all Ractors in parallel. Potentially, just declaring the involved hashes as sharable could be enough.

Actions

Also available in: PDF Atom