Bug #21049
openReconsider handling of the numbered parameters and "it" parameter in `Binding#local_variables`
Description
Currently, Binding#local_variable* APIs wrongly handles the numbered parameters.
# Binding#local_variables includes numbered parameters that should not be visible
"foo".tap do
_1
"bar".tap do
p binding.local_variables #=> expected: [], actual: [:_1]
end
end
# Binding#local_variable_get can read numbered parameters that should not be readable
"foo".tap do
_1
"bar".tap do
p binding.local_variable_get(:_1) #=> expected: NameError, actual: "foo"
end
end
# Binding#local_variable_set can update numbered parameter
"foo".tap do
p _1 #=> "foo"
binding.local_variable_set(:_1, "bar") # expected: NameError, actual: updates _1
p _1 #=> "bar"
end
My proposal is to stop handling numbered parameters and "it" parameter in Binding#local_variable* APIs.
"foo".tap do
_1
binding.local_variables #=> proposed: []
binding.local_variable_get(:_1) #=> proposed: NameError
end
Here is a proof-of-concept patch.
https://github.com/ruby/ruby/pull/12601
It would be theoretically possible to fix Binding#local_variable* APIs to handle numbered parameters while maintaining compatibility as much as possible.
However, I think the implicit “it” parameter introduced in Ruby 3.4 poses a spec-level problem.
This is because there is no way to distinguish between the implicit “it” parameter and a true local variable named "it".
Also, I don't think numbered parameters are local variables, so I feel uncomfortable handling them by Binding#local_variable* APIs.
If it is absolutely necessary to access numbered parameters or "it" parameter via binding, it would be good to introduce dedicated APIs for the purpose, as:
- Binding#numbered_parameters #=> [:_1, :_2, :_3, ...]
- Binding#numbered_parameter_get(:_1) #=> obj
- Binding#numbered_parameter_defined?(:_1) #=> true or false
- Binding#it_get #=> obj
- Binding#it_defined? #=> true or false
Personally, however, I do not see the need for these APIs currently. I implemented them as proof-of-concept in PR, but I am okay that they are not introduced.
Files
Updated by mame (Yusuke Endoh) 10 months ago
- Related to Bug #20965: `it` vs `binding.local_variables` added
Updated by matz (Yukihiro Matsumoto) 9 months ago
I take all three "expected" in the first example. I'd rather wait for the request for the new (additional) APIs with real-world use-case.
Matz.
Updated by mame (Yusuke Endoh) 9 months ago
- Status changed from Open to Closed
Fixed by 993fd96ce6bb763e08207bb3d53824d5d46d07a4.
Updated by daniel.domjan (Dániel Domján) 4 days ago
- File RM-numbered-params-visible.png RM-numbered-params-visible.png added
- File RM-numbered-params-not-visible.png RM-numbered-params-not-visible.png added
@matz (Yukihiro Matsumoto), in RubyMine we show users the values of numbered parameters as well
while debugging, but after this change we can no longer do so, since we don't have access to them.
I think introducing the dedicated API proposed in this issue could be beneficial for all kinds of
debug tooling, as it would allow developers to inspect the values of such parameters conveniently.
Updated by mame (Yusuke Endoh) 3 days ago
- Status changed from Closed to Open