From: "headius (Charles Nutter) via ruby-core" Date: 2026-04-26T23:24:18+00:00 Subject: [ruby-core:125362] [Ruby Feature#21998] Add {Method,UnboundMethod,Proc}#source_range Issue #21998 has been updated by headius (Charles Nutter). > The example of define_method(:foo) { ... } was given define_method is just a method call like any other. It should not be included in the range for the syntactic construct that is the block. What about do..end with a huge piece of code attached? ``` foo( # large amount of code ) do ... end ``` It makes no sense for the range of the syntactic block here to include the entire expression of the call and its arguments. None of that is syntactically part of the block and it would parse if the block were removed. > Also foo { break } the break there breaks out of foo, so IMO a block isn't complete without the method call to which receives it. The target of the break is a semantic detail, not a syntactic one, and it is not determined at parse time. For that matter, arguments to a method would not be arguments without the call, but we you don't consider their syntactic range to include the entire call. The block is just an argument of another form. I'll turn this question around: how can I get just the range of the block syntactic element if it includes all this other stuff unrelated to the block? I think what you really want is for the call's range to include the block, not the other way around. A nested AST element's range should not include source ranges of parent nodes. ---------------------------------------- Feature #21998: Add {Method,UnboundMethod,Proc}#source_range https://bugs.ruby-lang.org/issues/21998#change-117121 * Author: Eregon (Benoit Daloze) * Status: Open ---------------------------------------- I'm using matz's suggestion almost as-is from https://bugs.ruby-lang.org/issues/6012#note-53. The only change is the proposed class name. ## Use Cases Use cases have been discussed extensively and matz said: > The use cases are real and I want to support them So I think we don't need to discuss that anymore :) ## Background Adding column and last line information to `#source_location` is deemed too incompatible given the usages of `obj.source_location.last` which expect the start line (they would get the end column instead). ## Proposal So instead we add a new method, `{Method,UnboundMethod,Proc}#source_range`, which returns a `Ruby::SourceRange` and has these methods: * `start_line`: 1-indexed (same as `source_location.first`) * `end_line`: 1-indexed * `start_column`: in bytes, 0-indexed, I think `start_byte_column` could be good for extra clarity * `end_column`: in bytes, 0-indexed, I think `end_byte_column` could be good for extra clarity * `inspect` which shows something like `#`. For the edge case of a heredoc spanning further than the end of a method/block, we would not include it in the `end_line` & `end_column` methods, but instead document it and provide a small code snippet in the docs to compute that if desired with Prism. ## Alternative An alternative could be a `Ruby::SourceLocation` class and `obj.source_location(object: true)`/`obj.source_location(extended: true)` but it feels less nice. Since we are designing something new I think it's best to go for the cleanest design. ## Consistency The above methods match the name of methods on `Prism::Node` and have the same semantics, which is good for consistency and to avoid confusion. ## Scope The scope is intentionally minimal to keep the discussion focused. ## Implementation I'm happy to implement this, it should be pretty trivial and very similar to the extended `source_location`. I would prefer to get an approval for this feature before implementing. -- 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/lists/ruby-core.ml.ruby-lang.org/