So, @program is passed from one class to another, and in the second one I’ve defined the receiving class variable as @program : AST::Node which is an abstract class from which AST::NodeProgram inherits
defining @program in the second class as @program : AST::NodeProgram solves the problem
I’ll be glad If someone have few minutes to tell me what’s happening
Unless I’m missing something, the challenge is that you’re stating here that @program can be any AST::Node type, including potentially AST::NodeKeywordReturn. The value at runtime happens to be AST::NodeProgram at runtime, but the compiler only sees the potential for it to be that, or anything else under the AST::Node umbrella. Hence it “helping” you in this case with the error message. Limiting the type of @program like you did, or using @program.as(AST::NodeProgram).scope, or wrapping the call in a
if @program.is_a?(AST::NodeProgram)
pp @program.scope
end
Should all help the compiler see that you intend the variable to be a AST::NodeProgram at that point in the code.
This. The compiler doesn’t know what concrete types it will be when it’s running, so it has to ensure that everything it can be is accounted for.
I wonder if the error message could be improved here to say something like:
Undefined method 'scope' for AST::NodeKeywordReturn. Compile-time type is AST::Node+, which has the following subclasses that implement 'scope`:
- AST::NodeProgram
You can downcast '@program' to one or more of those types or implement the 'scope' method on the following types:
- AST::NodeKeywordReturn
What it is currently is not very interesting. What it could be is a lot more interesting for the compiler. So in this case the interesting way to check what it is is to do a puts typeof(@program). It will likely be some sort of union type, and then it will require all the types in the union to support that method.