New to Crystal with years Ruby experience.
I could not find a way to get the super or ancestors of a class in Crystal. In ruby, we have superclass
and ancestor
methods. What are the equivalent in Crystal lang?
Thanks.
New to Crystal with years Ruby experience.
I could not find a way to get the super or ancestors of a class in Crystal. In ruby, we have superclass
and ancestor
methods. What are the equivalent in Crystal lang?
Thanks.
They also exist in crystal but are macro (compile time) level methods, i.e. you can’t get that information at runtime. See TypeNode.ancestors and TypeNode.superclass.
EDIT: Add an example
abstract class One; end
abstract class Two < One; end
class Three < Two; end
{{pp Three.superclass}} # => Two
{{pp Three.ancestors}} # => [Two, One, Reference, Object]
Thanks, Blacksmoke16. Very helpful.
But I am still not sure how to handle my use case. Essentially, I have an object, for which I want to return its ancestors. Something like:
a = MyCalss.new
ancestors = get_ancestors(a)
Based on the documentation, I tried the following, but I seemed to not able to get across the boundary of Macro and regular code:
macro add_describe_methods
def describe
"Class is: " + {{ @type.stringify }}
end
def self.describe
"Class is: " + {{ @type.stringify }}
end
def self.get_ancestors
"Ancestors are: " + {{@type.superclass}}
end
end
class Foo
add_describe_methods
end
a = Foo.new
pp a.describe # => this works
pp Foo.describe # => this works too
pp Foo.get_ancestors
The compiler complains:
Showing last frame. Use --error-trace for full trace.
There was a problem expanding macro ‘add_describe_methods’
Code in tmp.cr:16:3
16 | add_describe_methods
^
Called macro defined in tmp.cr:1:1
1 | macro add_describe_methods
Which expanded to:
8 |
9 | def self.get_ancestors
10 | "Ancestors are: " + Reference
^
Error: no overload matches ‘String#+’ with type Reference.class
Overloads are:
- String#+(other : self)
- String#+(char : Char)
How should I fix it? Thanks.
Use three backticks for code blocks like that next time, makes it a bit easier to read.
The error you’re seeing is just as it says, there is no method on String
that allows you to add a Reference.class
. Your options would be {{@type.superclass.stringify}}
so the macro result is turned into a string. Or Just do like "Ancestors are: {{@type.superclass}}"
to add the value directly into the string.