TDirectory, ownership, encapsulation... c++

well,

this is a general comment and a question to the developers.

One of the most annoying things in ROOT manifested itself in code I use and made me waste much time. Someone created a TFile in another class, then I created my TNtuple, then that TFile was closed and deleted and when I wanted to use my TNtuple it had vanished. I know why it happens, so I do things like changing TDirectory to the root or SetDirectory(0).

Now the question (s):
Which one is the bug? (according to you)
a.- the missing lines around every use of my ntuple or the missing ntuple->SetDirectory(0).
b.- the other person’s missing to change directory to whatever was there previously
c.- none of the above.

Isn’t this whole thing against common C++ practice? (encapsulation and so on)

Hi,

this is just my personal opinion, both as a user (who ran into this exact same problem, too) and as someone who writes C++.

I agree that this is not the way C++ code should behave. If you want to reference a context (a TFile*, in which the ntuple is to be created), you should do that by using code (e.g. a method parameter), not by using globals. It’s gives clearer, more readable code, it has less side-effects, it prevents a lot of multi-threading pitfalls one runs into otherwise, and it corresponds better to what people are used to when talking about object orientation. Especially when using libraries that open their own files these side effects can be really nasty and hard to debug - as you stated.

On the other hand, this “register in pwd” has a tradition, e.g. in PAW (if I remember correctly :-). It’s useful e.g. for interactive use, where you save a few command lines. And nowadays code relies on it - there is no way ROOT can just back out.

So what I would prefer to see is a global switch, which turns pwd registration on or off - on being the default. This would allow a backward-compatible way of writing cleaner code with less (e.g. cross library) side-effects. I assume it would require only a tiny patch, maybe explicitely deriving auto-registering objects from a “TDirRegistrable”, which carries along its directory* as an OO replacement for gDirectory. The only issue remaining to discuss that I can see is what to do with objects read from file. IMHO those should be attached to the file by default.

Cheers, Axel.

When reading this would most likely be an error since (in the usual cases) not all the data of the nuple is loaded in memory and hence the file is required to use the ntuple. When writing this okay, as long as you have enough memory to fit all your data.

[quote] b.- the other person’s missing to change directory to whatever was there previously [/quote]It would be nicer if all part of the code where consistent (and you can use TDirectory::TContext to help) but can not be guaranteed. We recommend that whenever you would like to do something gDirectory dependent, you explicit cd to the directory you need.\

[quote]So what I would prefer to see is a global switch, which turns pwd registration on or off [/quote]There is TH1::AddDirectory (but no equivalent for TTree).

Cheers,
Philippe.