Reputation: 4073
How to reference to a class within a static method?
class Car
def self.new_from_xml(xml)
instance = self.class.new
#do some stuff with xml
instance
end
end
class Mercedes < Car
end
class Porsche < Car
end
IRB:
Mercedes.new_from_xml(somedata) # Output is #<Class:...>, should be #<Mercedes:...>
Porsche.new_from_xml(somedata) # Output is #<Class:...>, should be #<Porsche:...>
Upvotes: 2
Views: 680
Reputation: 8507
Since you are already in a class method, you should use self.new
(or simply new
, as @tokland wrote) instead of self.class.new
:
class Car
def self.new_from_xml(xml)
instance = new
#do some stuff with xml
end
end
class Mercedes < Car
end
class Porsche < Car
end
p Mercedes.new_from_xml(nil) #=> #<Mercedes:0x007f042d0db208>
p Porsche.new_from_xml(nil) #=> #<Porsche:0x007f042d0db118>
From a comment to this answer: Why does self.class reference to class? What's the logic here?
Inside a class block self
references the class you are editing:
class Car
puts self #=> writes Car
end
Using def self.new_from_xml
it is like if you are declaring def Car.new_from_xml
, that is a method of the Car
object (which is an instance of Class
); so inside new_from_xml
self
coincides with Car
.
Upvotes: 2
Reputation: 15979
Instead of
instance=self.class.new
just write
instance = new
Why is this?
Well, in first place, you have to understand that you are calling a class method, thus you are at a class level already. The .new method is a class method, so you can call it directly without calling self.class.new.
Why does self.class.new return Class?
Because the class of the class Car is Class (I know, sounds weird ;), because classes in Ruby are instances of Class.
This is actually a pretty deep concept, I recommend you read more about it. One nice reference I have read is the book Metaprogramming Ruby by Paolo Perrotta (ISBN-10: 1934356476) [1].
Upvotes: 4