ruby-rice / rice

Ruby Interface for C++ Extensions
http://ruby-rice.github.io/
Other
378 stars 63 forks source link

Casting to derived class #127

Closed camertron closed 4 years ago

camertron commented 4 years ago

Hey @jasonroelofs, got another question for you. I'm still working on wrapping this ANTLR parser as mentioned in #126 and running into a problem. I have a base class called Context and a bunch of derived classes that look something like this:

class Context {
  Object getChildren() {
    // children is a std::vector of Contexts
    Array a(children.begin(), children.end());
    return a;
  }
};

class Single_inputContext : public Context {}
class Simple_stmtContext : public Context {}
// etc etc

In ruby if I call #children on a Context, it returns an array of instances of Context instead of an array of derived objects. I want to be able to call certain methods specific to the derived classes, but can't because Ruby/Rice thinks they are instances of the base class.

Not sure how to proceed. Thanks!

jasonroelofs commented 4 years ago

I don't think this is really a Rice question, because even at the C++ layer you wouldn't be able to call into subclass-defined methods from superclass pointers. At some point you have to know what you have and cast it down to the subclass type you want. The only other option is to have all subclass methods defined on the parent class and wrap that in a Rice::Director but that's probably not a good solution here.

I guess there might be a third option, and that would be to implement more of this structure in Ruby directly, then you don't need such strict mappings to types and methods.

If I'm not understanding the question, please let me know!

camertron commented 4 years ago

@jasonroelofs ok that makes sense. It looks like ANTLR exposes a way to do this via antlrcpp::is<T*> so I've just got a giant if statement for now that wraps whatever ANTLR ParseTree object that gets passed in.

Thanks for your help!