Feature #21335
openNamespaces should be present in the backtrace
Description
Namespaces can call in to other name spaces. I think it might be helpful if namespace information is in the backtrace.
For example:
File.binwrite "foo.rb", <<-eorb
class Foo
def self.test(ns1, ns2, count)
if count == 0
puts caller
else
if count % 2 == 0
ns1::Foo.test(ns1, ns2, count - 1)
else
ns2::Foo.test(ns1, ns2, count - 1)
end
end
end
end
eorb
ns1 = Namespace.new
ns1.load "foo.rb"
ns2 = Namespace.new
ns2.load "foo.rb"
ns1::Foo.test(ns1, ns2, 10)
The output is like this:
See doc/namespace.md for known issues, etc.
/Users/aaron/git/ruby/exe/ruby: warning: Namespace is experimental, and the behavior may change in the future!
See doc/namespace.md for known issues, etc.
/Users/aaron/git/ruby/foo.rb:9:in 'test'
/Users/aaron/git/ruby/foo.rb:7:in 'test'
/Users/aaron/git/ruby/foo.rb:9:in 'test'
/Users/aaron/git/ruby/foo.rb:7:in 'test'
/Users/aaron/git/ruby/foo.rb:9:in 'test'
/Users/aaron/git/ruby/foo.rb:7:in 'test'
/Users/aaron/git/ruby/foo.rb:9:in 'test'
/Users/aaron/git/ruby/foo.rb:7:in 'test'
/Users/aaron/git/ruby/foo.rb:9:in 'test'
/Users/aaron/git/ruby/foo.rb:7:in 'test'
./test.rb:23:in '<main>'
Foo.test
alternates between namespaces when calling a method, but you can't tell from the backtrace. I think we should include namespaces in the backtrace.
Updated by tenderlovemaking (Aaron Patterson) 2 days ago
- Related to Feature #21311: Namespace on read (revised) added
Updated by mame (Yusuke Endoh) 2 days ago
As the current behavior of the backtrace, if the receiver class is completely bound to the constant names, they are prefixed to the method names in the backtrace. So, if you do:
NS1 = Namespace.new
NS1.load "foo.rb"
NS2 = Namespace.new
NS2.load "foo.rb"
NS1::Foo.test(NS1, NS2, 10)
you will see:
$ RUBY_NAMESPACE=1 ./miniruby test.rb
./miniruby: warning: Namespace is experimental, and the behavior may change in the future!
See doc/namespace.md for know issues, etc.
foo.rb:9:in 'NS1::Foo.test'
foo.rb:7:in 'NS2::Foo.test'
foo.rb:9:in 'NS1::Foo.test'
foo.rb:7:in 'NS2::Foo.test'
foo.rb:9:in 'NS1::Foo.test'
foo.rb:7:in 'NS2::Foo.test'
foo.rb:9:in 'NS1::Foo.test'
foo.rb:7:in 'NS2::Foo.test'
foo.rb:9:in 'NS1::Foo.test'
foo.rb:7:in 'NS1::Foo.test'
test.rb:23:in '<main>'
This depends on the output of Class#name
, so the result may change depending of the progress of #21316.
Updated by mame (Yusuke Endoh) 2 days ago
- Related to Bug #21316: Namespaces leak with permanent names added
Updated by mame (Yusuke Endoh) 2 days ago
It is possible to change how to display the backtrace to show class names that are not completely bound to constants.
I have conservatively designed the current spec of the backtrace to avoid potential confusing output, but I'm not sure which would be better.
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 26e0a6fb76..15ec9b7a4d 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -201,20 +201,19 @@ VALUE rb_mod_name0(VALUE klass, bool *permanent);
VALUE
rb_gen_method_name(VALUE owner, VALUE name)
{
- bool permanent;
if (RB_TYPE_P(owner, T_CLASS) || RB_TYPE_P(owner, T_MODULE)) {
if (RCLASS_SINGLETON_P(owner)) {
VALUE v = RCLASS_ATTACHED_OBJECT(owner);
if (RB_TYPE_P(v, T_CLASS) || RB_TYPE_P(v, T_MODULE)) {
- v = rb_mod_name0(v, &permanent);
- if (permanent && !NIL_P(v)) {
+ v = rb_mod_name(v);
+ if (!NIL_P(v)) {
return rb_sprintf("%"PRIsVALUE".%"PRIsVALUE, v, name);
}
}
}
else {
- owner = rb_mod_name0(owner, &permanent);
- if (permanent && !NIL_P(owner)) {
+ owner = rb_mod_name(owner);
+ if (!NIL_P(owner)) {
return rb_sprintf("%"PRIsVALUE"#%"PRIsVALUE, owner, name);
}
}
$ RUBY_NAMESPACE=1 ./miniruby test.rb
./miniruby: warning: Namespace is experimental, and the behavior may change in the future!
See doc/namespace.md for know issues, etc.
foo.rb:9:in '#<Namespace:0x00007ff4d61f9f20>::Foo.test'
foo.rb:7:in '#<Namespace:0x00007ff4d61f93e0>::Foo.test'
foo.rb:9:in '#<Namespace:0x00007ff4d61f9f20>::Foo.test'
foo.rb:7:in '#<Namespace:0x00007ff4d61f93e0>::Foo.test'
foo.rb:9:in '#<Namespace:0x00007ff4d61f9f20>::Foo.test'
foo.rb:7:in '#<Namespace:0x00007ff4d61f93e0>::Foo.test'
foo.rb:9:in '#<Namespace:0x00007ff4d61f9f20>::Foo.test'
foo.rb:7:in '#<Namespace:0x00007ff4d61f93e0>::Foo.test'
foo.rb:9:in '#<Namespace:0x00007ff4d61f9f20>::Foo.test'
foo.rb:7:in '#<Namespace:0x00007ff4d61f9f20>::Foo.test'
test.rb:23:in '<main>'
Updated by tagomoris (Satoshi Tagomori) 2 days ago
The ns_id
seems good to be shown in backtrace (I'm unsure about this format is good or not):
foo.rb:7:in namespace(1) 'Foo.test'
Updated by tenderlovemaking (Aaron Patterson) 2 days ago
mame (Yusuke Endoh) wrote in #note-2:
As the current behavior of the backtrace, if the receiver class is completely bound to the constant names, they are prefixed to the method names in the backtrace.
Ah, ok, I didn't know that. Thank you.
I'm not sure if printing the address or the ns_id
is better. Either works for me, but I'm not sure what would be most ergonomic.