Skip to content

Method visibility is not preserved after redefining methods #30

@nikitakar9862

Description

@nikitakar9862

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions