Project

General

Profile

Feature #16001

Provide an alias to Kernel#caller_locations(1,1) and Kernel#caller(1,1)

Added by piotrmurach (Piotr Murach) 8 days ago. Updated 6 days ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:93753]

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).

History

Updated by Eregon (Benoit Daloze) 7 days 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) 7 days ago

Eregon (Benoit Daloze) wrote:

Maybe direct_caller?

Would it call caller_locations(1,1) or caller(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) 7 days 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) 7 days 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) 7 days 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.

#6

Updated by piotrmurach (Piotr Murach) 7 days ago

  • Description updated (diff)

Updated by shevegen (Robert A. Heiler) 7 days 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) 7 days 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) 6 days 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) 6 days 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) 6 days 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.

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.

#12

Updated by piotrmurach (Piotr Murach) 6 days ago

  • Description updated (diff)

Also available in: Atom PDF