Issue #21783 has been updated by Eregon (Benoit Daloze). mame (Yusuke Endoh) wrote in #note-17:
Huh? `Proc` already has its `node_id` (via its ISeq), so `Prism.node_for` is implementable without `source_location`. I want to say that `source_location` is unnecessary to implement `Prism.node_for`.
No, `node_id` is CRuby-specific and this code to extract it is a hack. `source_location` with column information has the proper information, is a proper API, is portable and avoids that hack. I think it would be unacceptable to have any functionality in Prism depending on `RubyVM` for example, we need to find general solutions, not CRuby-specific hacks. FWIW I also consider the concept of `node_id` CRuby-specific, at least currently. TruffleRuby doesn't have `node_id` for instance, but it has columns and that's a general concept.
I have the following hypothesis: When people want column information, what they really need is an AST.
Yes, probably true for a lot of cases. But such column information (or byte offsets from the start of line/source, any of these works) is also necessary to locate the right node in the AST, just the `start_line` like currently is insufficient (e.g. there can be multiple blocks on a single line). For other cases it's unnecessary to have the AST, e.g. to print the source of a method, e.g. for RDoc or similar, i.e. the `method_source` use case (700 millions downloads, https://rubygems.org/gems/method_source).
Since power_assert pinpoints expressions within a block at a finer granularity, rough block's location information isn't particulary useful.
Then `power_assert` is likely incorrect/broken if there are multiple `assert { ... }` block on a single line. It could identify the correct block with column information. ---------------------------------------- Bug #21783: {Method,UnboundMethod,Proc}#source_location returns columns in bytes and not in characters https://bugs.ruby-lang.org/issues/21783#change-115754 * Author: Eregon (Benoit Daloze) * Status: Open * ruby -v: ruby 4.0.0dev (2025-12-14T07:11:02Z master 711d14992e) +PRISM [x86_64-linux] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The documentation says: ``` = Proc.source_location (from ruby core) ------------------------------------------------------------------------ prc.source_location -> [String, Integer, Integer, Integer, Integer] ------------------------------------------------------------------------ Returns the location where the Proc was defined. The returned Array contains: (1) the Ruby source filename (2) the line number where the definition starts (3) the column number where the definition starts (4) the line number where the definition ends (5) the column number where the definitions ends This method will return nil if the Proc was not defined in Ruby (i.e. native). ``` So it talks about column numbers, so it should be a number of characters and not of bytes. But currently it's a number of bytes: ``` $ ruby --parser=prism -ve 'def été; end; p method(:été).source_location' ruby 4.0.0dev (2025-12-14T07:11:02Z master 711d14992e) +PRISM [x86_64-linux] ["-e", 1, 0, 1, 14] $ ruby --parser=parse.y -ve 'def été; end; p method(:été).source_location' ruby 4.0.0dev (2025-12-14T07:11:02Z master 711d14992e) [x86_64-linux] ["-e", 1, 0, 1, 14] ``` The last number should be 12 because `"def été; end".size` is 12 characters. This is a Ruby-level API so I would never expect "byte columns" here, I think it's clear it should be a number of "editor columns" i.e. a number of characters. -- https://bugs.ruby-lang.org/