[ruby-core:117180] [Ruby master Feature#20335] `Thread.each_caller_location` should accept the same arguments as `caller` and `caller_locations`
From:
"byroot (Jean Boussier) via ruby-core" <ruby-core@...>
Date:
2024-03-14 15:08:21 UTC
List:
ruby-core #117180
Issue #20335 has been updated by byroot (Jean Boussier).
> I think omitting the first N frames is useful.
Agreed, that's the only one I want. The reason I started the issue by asking for the same parameters is purely consistency.
Now, if there are valid reasons not to support some (like you exposed), I'm totally fine with deliberately not supporting them. But what I'm trying to say is we should start with the same feature set and then selectively remove the one that may be problematic.
So I suppose at that stage the proposal would be:
```ruby
Thread.each_caller_location(1) # skip first frame
Thread.each_caller_location(1, 20) # skip first frame, yield the next 20 frames
Thread.each_caller_location(1..20) # ArgumentError
```
Is that correct?
----------------------------------------
Feature #20335: `Thread.each_caller_location` should accept the same arguments as `caller` and `caller_locations`
https://bugs.ruby-lang.org/issues/20335#change-107270
* Author: byroot (Jean Boussier)
* Status: Open
----------------------------------------
`Thread.each_caller_location` was added to Ruby 3.2 as part of [Feature #16663] and is a very useful API for emitting warnings with a proper source location and similar use cases.
However in many of the cases where I used it, or seen it used, it was needed to skip the first, or a couple frames:
Examples:
Sorbet: https://github.com/Shopify/sorbet/blob/b27a14c247ace7cabdf0f348bfb11fdf0b7e9ab4/gems/sorbet-runtime/lib/types/private/caller_utils.rb#L6-L18
```ruby
def self.find_caller
skiped_first = false
Thread.each_caller_location do |loc|
unless skiped_first
skiped_first = true
next
end
next if loc.path&.start_with?("<internal:")
return loc if yield(loc)
end
nil
end
```
@fxn 's PR: https://github.com/ruby/ruby/blob/9c2e686719a5a4df5ea0b8a3b6a373ca6003c229/lib/bundled_gems.rb#L140-L146
```ruby
frames_to_skip = 2
location = nil
Thread.each_caller_location do |cl|
if frames_to_skip >= 1
frames_to_skip -= 1
next
end
# snipp...
```
### Proposal
I think it would be very useful if `Thread.each_caller_location` accepted the same arguments as `caller` and `caller_locations`:
```ruby
#each_caller_location(start = 1, length = nil)
#each_caller_location(range)
```
@jeremyevans0 what do you think?
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/