Feature #16001
openProvide an alias to Kernel#caller_locations(1,1) and Kernel#caller(1,1)
Description
As it is common to use caller_locations(1,1)
and caller(1,1)
, this proposes aliases to help get the previous backtrace frame and improve performance by avoiding getting full backtrace information - a common mistake.
The currently suggestions are:
immediate_caller
first_caller
caller_only
This feature request is based on a conversation with Charles Nutter who says:
This is such a common thing... maybe we need to add something like #caller_only or #caller1 that basically do caller(1,1).
Updated by Eregon (Benoit Daloze) over 5 years ago
Maybe direct_caller
?
Would it call caller_locations(1,1)
or caller(1,1)
? It can only be one of them.
Updated by piotrmurach (Piotr Murach) over 5 years ago
Eregon (Benoit Daloze) wrote:
Maybe
direct_caller
?Would it call
caller_locations(1,1)
orcaller(1,1)
? It can only be one of them.
That's a very good point. I'd probably lean towards modern API of caller_locations(1,1)
if we only used a single alias. However, we could follow a pattern and name caller_locations(1,1)
as direct_caller_location
and caller(1,1)
as direct_caller
?
Updated by alanwu (Alan Wu) over 5 years ago
Would this be an instance method on Kernel? If so, it seems like a very heavy handed way to shorten something that is already fairly short.
I don't see caller_locations(1,1)
or caller(1,1)
very frequently, though.
Updated by chrisseaton (Chris Seaton) over 5 years ago
If so, it seems like a very heavy handed way to shorten something that is already fairly short
For some reason nobody seems to have commented here what I think is the original motivation for this new method - it's not an alias for brevity, it's a performance thing. Getting the full backtrace is extremely expensive and nobody has a good idea how to make it fully lazy. This new method allows the user to explicitly say that they only need some of the callers.
Updated by piotrmurach (Piotr Murach) over 5 years ago
it's not an alias for brevity
Definitely not brevity but clarity certainly. The caller(1,1)
seems cryptic as compared to direct_caller
which is more expressive.
it's a performance thing. Getting the full backtrace is extremely expensive and nobody has a good idea how to make it fully lazy. This new method allows the user to explicitly say that they only need some of the callers.
That's a very important point. Limiting the full backtrace to the immediate caller will reduce unnecessary allocations.
Updated by piotrmurach (Piotr Murach) over 5 years ago
- Description updated (diff)
Updated by shevegen (Robert A. Heiler) over 5 years ago
For some reason nobody seems to have commented here what I think is the original motivation for this
new method - it's not an alias for brevity, it's a performance thing.
I think this may have been lost a bit in the discussion because typically aliases are used to use something
differentially, such as .map versus .collect. At first I also thought that there is something about an
exciting new feature :-) until I noticed that the primary use case may have been related to
speed/performance gains; which is nice (as matz has said: nobody minds if things become faster), but I
was almost hoping for something cool, new and extremely exciting! :D
To the name itself, from the suggestions, I like benoit's direct_caller the most (from the above),
for caller_locations(1,1) - but it may be best to have someone from the core team comment on the
proposal thus far in regards to the speed/performance improvement here.
Updated by Eregon (Benoit Daloze) over 5 years ago
chrisseaton (Chris Seaton) wrote:
This new method allows the user to explicitly say that they only need some of the callers.
caller
and caller_locations
already allow that with the length
argument, which is more flexible.
I don't think there would be a significant performance difference between caller_locations(1,1)
and immediate_caller
, is it?
piotrmurach (Piotr Murach) wrote:
That's a very important point. Limiting the full backtrace to the immediate caller will reduce unnecessary allocations.
Which allocations? Isn't caller_locations(1,1)
exactly the same as immediate_caller
?
Maybe the only difference is the first one returns an Array and the second just a Thread::Backtrace::Location
?
That's probably not significant for performance.
Updated by chrisseaton (Chris Seaton) over 5 years ago
@Eregon (Benoit Daloze) the answer is in the former version of this issue - 'avoid common beginner mistakes getting full backtrace information' - it improves performance by being obvious when you look in the docs and helping people avoid getting the full backtrace when they only need a bit of it.
Updated by Eregon (Benoit Daloze) over 5 years ago
Right, I'm thinking we should just improve the documentation of caller
and caller_locations
then,
to mention limit
should be used when possible, otherwise the impact on performance can be very high.
Updated by piotrmurach (Piotr Murach) over 5 years ago
Right, I'm thinking we should just improve the documentation of
caller
andcaller_locations
then,
to mentionlimit
should be used when possible, otherwise the impact on performance can be very high.
This is quite a common thing to do and it's not only about performance, though the performance aspect is equally important. I often see code caller[0]
used to refer to the immediate frame which means that the whole backtrace is retrieved and then discarded. On the syntax front, this can be likened to having Array#first
or Array#last
aliases. We could add documentation to explain what array[0]
and array[-1]
do respectively. However, having additional method calls on an array will help clarify intention. One reason that I use Ruby is its expressiveness and readability. I'm far from wanting to add aliases for the sake of it, they need to match the spirit of Ruby.
Updated by piotrmurach (Piotr Murach) over 5 years ago
- Description updated (diff)
Updated by ko1 (Koichi Sasada) over 5 years ago
- maybe it should be an alias of
caller_locations(1, 1).first
. - do you know good name on it?
caller_location(n=1)
, for example? - do people use it on performance important places? I assume it is debugging method. Other than debugging, I think it should be a bad idea because depending on (direct) caller disallows delegation, druby and other techniques.
Updated by matz (Yukihiro Matsumoto) about 5 years ago
I prefer caller_location(n=1)
or direct_caller
. For former, it might be confusing with caller_locations
. The latter is straightforward but it is restricted to the direct caller (n=1
).
Matz.
Updated by Dan0042 (Daniel DeLorme) about 5 years ago
piotrmurach (Piotr Murach) wrote:
This is quite a common thing to do and it's not only about performance, though the performance aspect is equally important. I often see code
caller[0]
used to refer to the immediate frame which means that the whole backtrace is retrieved and then discarded.
Maybe caller
without any arguments should be deprecated? Force people to use e.g. caller(1..)
if they really want the full expensive backtrace.
Updated by sawa (Tsuyoshi Sawada) about 5 years ago
What about nth_caller(n=1)
, with some CSS flavor?