Problem
When a method is defined after a private keyword, it should remain private. However, after LowType redefines the method (using define_method), it becomes public.
This happens because the define_method sets method visibility to public by default, and the original visibility of the method is not restored.
For example:
class User
private
def secret
puts "hidden"
end
end
Expected behavior:
When a method is defined under the private keyword, if we call the method outside the class it should raise NoMethodError. This is Ruby's standard encapsulation rule.
User.new.secret # => NoMethodError (private method)
Actual behavior (after LowType processing):
But when LowType redefines the method using define_method, it makes the method public by default and does not restore the original private visibility.
User.new.secret # => "hidden" (method became public)
Proposed Solution
- Track where the
private keyword appears in the class (using line numbers)
- Then compare it with each method’s start_line
- If a method is defined after the private keyword then it should be treated as private method
- After redefining the method, explicitly restore its visibility
Example approach:
define_method(:method_name) do
...
end
if class_proxy.private_start_line && method_proxy.start_line >= class_proxy.private_start_line
private :method_name
end
Additional Improvement
While working on this issue, I also found that adding file_path and start_line to param proxies and return proxies helps improve the error messages by pointing to the exact location in the source file.
@maedi brother let me know if this approach looks good. I would be happy to open a PR for it.
Problem
When a method is defined after a
privatekeyword, it should remainprivate. However, after LowType redefines the method (using define_method), it becomes public.This happens because the
define_methodsets method visibility to public by default, and the original visibility of the method is not restored.For example:
Expected behavior:
When a method is defined under the
privatekeyword, if we call the method outside the class it should raiseNoMethodError. This is Ruby's standard encapsulation rule.Actual behavior (after LowType processing):
But when LowType redefines the method using
define_method, it makes the methodpublicby default and does not restore the original private visibility.Proposed Solution
privatekeyword appears in the class (using line numbers)Example approach:
Additional Improvement
While working on this issue, I also found that adding file_path and start_line to param proxies and return proxies helps improve the error messages by pointing to the exact location in the source file.
@maedi brother let me know if this approach looks good. I would be happy to open a PR for it.