RubyRoot: 5.16: Crash in TLorentzVector#DeltaR

Dear experts,

the following code used to work fine in 5.10.00:

require 'libRuby'

t1 =
t2 =
t1.DeltaR( t2 )

h1 =
h2 =
h1.Add( h2 )

With 5.16.00 RubyRoot bails out with an rb_fatal on line 5:

% ruby test.rb
test.rb:5:in `method_missing': You provided a wrong prototype (TLorentzVector*) for TLorentzVector#DeltaR. Aborting. (fatal)
        from test.rb:5

Since DeltaR has a different signature, this in not terribly surprising. DeltaR expects a TLorentzVector reference, but gets the pointer. The code responsible is in $ROOTSYS/ruby/src/drr.cxx:476:

474                    if (cproto) {
475                        strcat(cproto, STR2CSTR(rb_iv_get (arg, "__rr_class__")));
476                        strcat(cproto, "*");
478                    }

Here the function prototype to be queried from CINT is being composed. It might seem straight-forward that this would not work, as it assumes Root objects are always passed via pointer which is wrong here. However, this bit of the code has not changed since 5.10.00 and neither has the function prototype.

To make sure this is the cause I changed line 476 to read “strcat(cproto, “&”);”:

ruby test.rb
Warning in <TVector3::PseudoRapidity>: transvers momentum = 0! return +/- 10e10
Warning in <TVector3::PseudoRapidity>: transvers momentum = 0! return +/- 10e10
test.rb:9:in `method_missing': You provided a wrong prototype (TH1F&) for TH1F#Add. Aborting. (fatal)
        from test.rb:9

This fixes the DeltaR issue, but fails on TH1F#Add, as that method expects a pointer!

Is there a way out of this dilemma? If I had an idea how to tackle this effectively I would be glad to write a patch to RubyRoot that implements this.

Thanks in advance!



from a short glimpse at the code I’d say that ruby does not distinguish between pointers and references. So when a call “f(obj)” happens on the ruby side, the translation engine just doesn’t know whether “f(Class&)” or “f(Class*)” needs to be called. And if there is an overload of both then we end up with an ambiguity that we cannot resolve.

So the only solution I can think of is: take “" and if that doesn’t exist try again with “&”. So far, "” was apparently pretty successful :slight_smile: That check could probably be done on the basis of minfo.InterfaceMethod() (line 652). But that * vs & check needs to be done for all permutations until a method one is found: think of f(Class*, Class&, Class&) or f(Class*, Class&, Class*).

So yes, please send us the patch :slight_smile:

Cheers, Axel.

Hi Axel,

I feared I might be told something like this :wink:. Ok, I brute forced this in drr_map_args2 and drr_method_missing, everywhere else the behavior should be unchanged. A diff to r21356 is attached. This is not terribly elegant, I assume one can do better but that seemed like a bigger change.

There is also a simplistic test attached that should fail on r21356 but work with the patch.

Btw. am I on the correct forum for this any longer? Is there a development forum for such a discussion? Having looked at the code I would like to switch some of the rb_fatals to exceptions and/or save the original method_missing as is done for const_missing if that is acceptable for you.

test.rb.txt (160 Bytes)
patch.txt (3.16 KB)

Apparently the problem is somewhat bigger than I had seen at first. Even some of the tutorial files crash in ther original 5.16, for example canvas.rb. I will file a bug report.


I have contacted Elias Athanasopoulos, author of the RubyRoot interface.
He wrote to me the following:


Hello Rene,

[quote=“brun”]I have contacted Elias Athanasopoulos, author of the RubyRoot interface.

thanks a lot! I will contact Elias and try to see if I can help. Would you prefer if I kept this in e-mail with him, or is there a correct place on this forum or a Root mailinglist for development discussions?


Up to you.
In case you communicate by email, post something at this forum to indicate what was the conclusion.


This seems to be a bug, a patch is attached to


Thanks to Jan, this problem is now fixed in SVN.