Skip to content

Commit d85639f

Browse files
authored
Allow properties to be accessed even when the object is moved to another Ractor (#29)
1 parent 8534f69 commit d85639f

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

lib/ostruct.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,14 @@ def marshal_dump # :nodoc:
221221
#
222222
def new_ostruct_member!(name) # :nodoc:
223223
unless @table.key?(name) || is_method_protected!(name)
224-
define_singleton_method!(name) { @table[name] }
225-
define_singleton_method!("#{name}=") {|x| @table[name] = x}
224+
getter_proc = Proc.new { @table[name] }
225+
setter_proc = Proc.new {|x| @table[name] = x}
226+
if defined?(::Ractor)
227+
::Ractor.make_shareable(getter_proc)
228+
::Ractor.make_shareable(setter_proc)
229+
end
230+
define_singleton_method!(name, &getter_proc)
231+
define_singleton_method!("#{name}=", &setter_proc)
226232
end
227233
end
228234
private :new_ostruct_member!

test/ostruct/test_ostruct.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,18 @@ def test_ractor
368368
RUBY
369369
end if defined?(Ractor)
370370

371+
def test_access_methods_from_different_ractor
372+
assert_ractor(<<~RUBY, require: 'ostruct')
373+
os = OpenStruct.new
374+
os.value = 100
375+
r = Ractor.new(os) do |x|
376+
v = x.value
377+
Ractor.yield v
378+
end
379+
assert 100 == r.take
380+
RUBY
381+
end if defined?(Ractor)
382+
371383
def test_legacy_yaml
372384
s = "--- !ruby/object:OpenStruct\ntable:\n :foo: 42\n"
373385
o = YAML.safe_load(s, permitted_classes: [Symbol, OpenStruct])

0 commit comments

Comments
 (0)