Just discovered Crystal a week or so ago - fascinating thing!
I have this issue to sort out: calling class methods within the scope of the class works only with a fully qualified name AClass.a_method. I would expect (and I believe the docs are saying) that within the scope of the unit (class or module) one can call static methods with self.a_static_method … no? What am I missing?
An example follows:
class AClass
def initialize(@name : String)
end
def this_fails
# Error: undefined method 'class_method' for AClass
self.class_method(@name)
end
def this_also_fails
# Error: undefined method 'class_method' for AClass
class_method(@name)
end
def this_works
AClass.class_method(@name)
end
def self.class_method(name : String) : Nil
puts "class_method called with name=#{name}"
end
end
ac = AClass.new "Bimbo"
ac.this_works
ac.this_fails
ac.this_also_fails
self in the context of an instance method is referring to the instance itself, which is a different scope compared to the class scope the class methods are defined in. The idiomatic way would be to do like self.class.class_method @name, which is an easy way to get a reference to the current instance’s class scope.
The docs could perhaps be clearer, but when it says
When called from within the same class or module scope the receiver can be self or implicit
then the scopes referred to are regions with the same self. self within an instance method refers to instances of the class. self within a class method refer to the class itself. Hence the behavior you are seeing show up.
I get it now. (You could probably sense my python background ;)
For people like me, an example in the documentation including the self.class.class_method approach might be of help. (I wonder if it makes sense to try contributing something to that page?)