From 89288430c23268908ba458257ed0acfd00705e57 Mon Sep 17 00:00:00 2001 From: Peter Arato Date: Wed, 7 Jun 2023 17:25:34 -0400 Subject: [PATCH] Add Method#const_addeed. --- CHANGELOG.md | 1 + spec/ruby/core/module/const_added_spec.rb | 31 +++++++++++++++++++ spec/truffleruby.next-specs | 2 ++ .../truffleruby/core/module/ModuleFields.java | 7 +++++ src/main/ruby/truffleruby/core/module.rb | 3 ++ 5 files changed, 44 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index beaf6f59c582..1328ed7259e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Compatibility: * Add `String#byteindex` and `String#byterindex` (#3039, @itarato). * Add implementations of `rb_proc_call_with_block`, `rb_proc_call_kw`, `rb_proc_call_with_block_kw` and `rb_funcall_with_block_kw` (#3068, @andrykonchin). * Add optional `timeout` argument to `Thread::Queue#pop` (#3039, @itarato). +* Add `Module#const_added` (#3039, @itarato). Performance: diff --git a/spec/ruby/core/module/const_added_spec.rb b/spec/ruby/core/module/const_added_spec.rb index 31ac6eb10590..32bb82905259 100644 --- a/spec/ruby/core/module/const_added_spec.rb +++ b/spec/ruby/core/module/const_added_spec.rb @@ -121,5 +121,36 @@ class SubClass ScratchPad.recorded.should == [line + 2, line + 4, line + 7, line + 11] end + + it "is called when the constant is ready to be used" do + mod = Module.new do + def self.const_added(name) + ScratchPad.record const_get(name) + end + end + + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 123 + RUBY + + ScratchPad.recorded.should == 123 + end + + it "records re-definition of existing constants" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << const_get(name) + end + end + + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 123 + TEST = 456 + RUBY + + ScratchPad.recorded.should == [123, 456] + end end end diff --git a/spec/truffleruby.next-specs b/spec/truffleruby.next-specs index e7a0a3492875..9ec04efe6d49 100644 --- a/spec/truffleruby.next-specs +++ b/spec/truffleruby.next-specs @@ -25,3 +25,5 @@ spec/ruby/core/string/byterindex_spec.rb spec/ruby/core/queue/deq_spec.rb spec/ruby/core/queue/pop_spec.rb spec/ruby/core/queue/shift_spec.rb + +spec/ruby/core/module/const_added_spec.rb diff --git a/src/main/java/org/truffleruby/core/module/ModuleFields.java b/src/main/java/org/truffleruby/core/module/ModuleFields.java index e2a59c474319..58bbf630c59c 100644 --- a/src/main/java/org/truffleruby/core/module/ModuleFields.java +++ b/src/main/java/org/truffleruby/core/module/ModuleFields.java @@ -30,6 +30,7 @@ import org.truffleruby.RubyLanguage; import org.truffleruby.collections.ConcurrentOperations; import org.truffleruby.collections.ConcurrentWeakSet; +import org.truffleruby.core.CoreLibrary; import org.truffleruby.core.encoding.Encodings; import org.truffleruby.core.encoding.TStringUtils; import org.truffleruby.core.kernel.KernelNodes; @@ -494,6 +495,12 @@ private RubyConstant setConstantInternal(RubyContext context, Node currentNode, invalidateConstantIncludedBy(name); } + final CoreLibrary coreLibrary = context.getCoreLibrary(); + if (currentNode != null && coreLibrary != null && coreLibrary.isLoaded()) { + final RubySymbol constSymbol = context.getLanguageSlow().getSymbol(name); + RubyContext.send(currentNode, rubyModule, "const_added", constSymbol); + } + return autoload ? newConstant : previous; } diff --git a/src/main/ruby/truffleruby/core/module.rb b/src/main/ruby/truffleruby/core/module.rb index e4687d25e0b8..8dabc6dfccef 100644 --- a/src/main/ruby/truffleruby/core/module.rb +++ b/src/main/ruby/truffleruby/core/module.rb @@ -105,6 +105,9 @@ def prepend(*modules) self end + private def const_added(name) + end + def const_defined?(name, inherit = true) Primitive.module_const_defined?(self, name, inherit, true) end