Hi! I’m building an implementation of Ruby in Scala, and I have some questions about the best way to represent Ruby objects and classes using case classes and traits. I had been using classes and inheritance in an older version of this project, but I wanted to challenge myself to do things in a more functional way. In short, I’ve added a trait for each class in the Ruby class hierarchy (BasicObject, Object, String, etc.). These traits are named BasicObjectLike, ObjectLike, etc. and contain the behavior associated with the Ruby classes (i.e. the methods defined on the classes). Currently, these traits inherit from each other as their corresponding Ruby classes do (
BasicObject <: Object and so on). I’ve added a case class for each Ruby class that defines its representation and extends its corresponding trait (
BasicObjectLike <: BasicObject). I’ve also added a
RuntimeContext case class to keep track of instance-specific information (e.g. object ID); each Ruby class case class contains a
My questions are:
- Is this a fair and idiomatic way to represent Ruby class hierarchies and method overriding, or is there something less convoluted I can do?
- Should each Ruby case class contain a
RuntimeContext, or should each
RuntimeContextcontain a Ruby case class? I went with the former primarily because I’d like to be able to call methods directly on the case class instances to make equality less confusing (e.g
String#==would depend only on the value of the string itself, but
Object#==compares object identity)
If you are so inclined as to look at the source code for these changes, you can find it here (it does not currently compile): https://github.com/ethowitz/sruby/tree/refactor (
master contains the old way I was doing things, and
refactor has, well…the refactor). You can find the Ruby case classes and traits in
I hope this was comprehensible – thank you in advance!