Feature #21272
openClass.new doesn't trigger :class TracePoint
Description
According to the official documentation:
To filter what is traced, you can pass any of the following as events:
:class
Start a class or module definition.
I'd expect :class events to be triggered when new classes are defined via Class.new as well, but currently that's not the case.
Should we either support Class.new, or clarify the behaviour in documentation?
Reproduction¶
TracePoint.trace(:class) do |tp|
puts "Class created at line: #{tp.lineno}"
end
class Foo; end # Triggers the tracepoint
Baz = Class.new # Doesn't trigger the tracepoint
# ruby test.rb
# Class created at line: 5
Updated by Eregon (Benoit Daloze) 10 months ago
In my view, Baz = Class.new doesn't really "Start a class or module definition." it creates a class but there is no definition of it, no body.
Though Baz = Class.new { ... } would arguably start a definition/body, but then so would Baz.class_exec { ... } and that seems less reasonable to catch with a :class TracePoint.
I think unless there is a good motivating example to change behavior (which could be incompatible), it's better to just document it better, so I'd suggest opening a PR to document it better.
Updated by cfis (Charlie Savage) 16 days ago
ยท Edited
This is a difference in Ruby 4.0. Previous versions of Ruby sent out a Class.new event. This change results in a lot of failures in the ruby-prof test suite. For example this test now fails:
https://github.com/ruby-prof/ruby-prof/blob/master/test/measure_wall_time_test.rb#L148
Since this is a change in 4.0, it seems to me preferable to maintain historic behavior unless of course there is a good reason to change it. Thanks.
Updated by Eregon (Benoit Daloze) 15 days ago
cfis (Charlie Savage) wrote in #note-2:
This is a difference in Ruby 4.0. Previous versions of Ruby sent out a Class.new event.
No they did not as far as I can see. Even Ruby 2.0.0 does not emit a :class tracepoint for Class.new:
$ ruby -ve 'TracePoint.trace(:class) { puts "class tp" }; p 1; class Foo; end; p 2; Class.new {}'
ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux]
1
class tp
2
$ ruby -ve 'TracePoint.trace(:class) { puts "class tp" }; p 1; class Foo; end; p 2; Class.new {}'
ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux]
1
class tp
2
Updated by Eregon (Benoit Daloze) 15 days ago
- Tracker changed from Bug to Feature
- Backport deleted (
3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN)
Changing this to a feature request.
Updated by Eregon (Benoit Daloze) 15 days ago
@cfis (Charlie Savage) I think you're thinking about :call TracePoints, that's unrelated to this issue and that did change in 4.0, see #21254 and #21298.
Updated by cfis (Charlie Savage) 15 days ago
@Eregon (Benoit Daloze) - Ah, you are right. Thanks for the pointers to the other issues. Reading them I can see that Class.new is eliminated but I also see this note:
Before inlining, ObjectSpace would report the allocation class path and method id as Class#new which isn't very helpful. With the inlining patch, we can see that the object is allocated in Foo#test.
It seems like tracepoint doesn't report anything anymore though? Should I move my questions to those tickets? Thanks!
Updated by Eregon (Benoit Daloze) 14 days ago
cfis (Charlie Savage) wrote in #note-6:
Should I move my questions to those tickets?
Yes, or file a new ticket with a reproduction.