Crystal: #subclasses method

Created on 24 Dec 2016  路  2Comments  路  Source: crystal-lang/crystal

I'm trying to write a method that returns an array of subclasses (the actual class, not the string). I have it working, but I think this is a bit of a hack.

The class variable @@subclasses gets typed properly when I instantiate it with the Animal class, and works as you can see by the output. But I also have to shift the array to remove the abstract class. It seems I should be able to do something like @@subclasses = [] of Animal though this would just be an array of instances, not classes. Is there a special grammar for types of this sort?

```crystal
abstract class Animal
@@subclasses = [Animal] # specified manually!
@@subclasses.shift # drop the class leaving the array properly typed and empty

def self.subclasses
@@subclasses
end

macro inherited
Animal.subclasses << {{@type.name}}
end

end

class Dog < Animal
end

class Cat < Animal
end

class Terrier < Dog
end

Animal.subclasses # [Dog, Cat, Terrier] : Array(Animal)
Animal.subclasses[0].new # Animal

Most helpful comment

Yeah, there's Crystal::Macros::TypeNode#subclasses.

abstract class Animal; end

class Dog < Animal; end
class Cat < Animal; end

class Terrier < Dog; end

# print all subclasses
pp {{ Animal.all_subclasses }} # => [Dog, Terrier, Cat]
# print only direct subclasses
pp {{ Animal.subclasses }} # => [Dog, Cat]

All 2 comments

Yeah, there's Crystal::Macros::TypeNode#subclasses.

abstract class Animal; end

class Dog < Animal; end
class Cat < Animal; end

class Terrier < Dog; end

# print all subclasses
pp {{ Animal.all_subclasses }} # => [Dog, Terrier, Cat]
# print only direct subclasses
pp {{ Animal.subclasses }} # => [Dog, Cat]

Thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MakeNowJust picture MakeNowJust  路  64Comments

asterite picture asterite  路  70Comments

malte-v picture malte-v  路  77Comments

rdp picture rdp  路  112Comments

sergey-kucher picture sergey-kucher  路  66Comments