Skip to content

NameError when using user-defined classes as parameter types due to incorrect evaluation binding #31

@obsidiannnn

Description

@obsidiannnn

Description

Using user-defined classes as type annotations can raise a NameError due to incorrect constant resolution during evaluation.

Reproduction

class PaymentMethod; end

class Order
  include LowType

  def process(method: PaymentMethod)
    "Processing via #{method.class}"
  end
end

Order.new.process(method: PaymentMethod.new)

Actual Behavior

Raises:

NameError: Unknown type 'PaymentMethod'

Expected Behavior

"Processing via PaymentMethod"

Root Cause

In Evaluator#instance_evaluate, expressions are evaluated using:

eval(proxy.value, binding, ...)

The binding belongs to Low::Evaluator, not the class that includes LowType. As a result, user-defined constants are not visible during evaluation, leading to NameError.

There is also an existing TODO in the code highlighting this:

Evaluate in the binding of the class that included LowType if not a type managed by LowType.

Proposed Direction

Possible approaches to resolve this:

  • Pass the including class context into the evaluator
  • Resolve constants using const_get within the correct namespace
  • Use class_eval on the including class to evaluate expressions in the right scope

Impact

  • Breaks support for user-defined types
  • Fails for namespaced constants (e.g., MyModule::MyClass)
  • Likely affects return type evaluation as well (same evaluation path)

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