The following has Universe(superclass) , Common(module), FlatEarthBelievers(subclass) and RoundEarthBelievers(subclass). There is an error with the output and want to make it work, any pointers?
This is about inheritance and mixins, a scenario where child classes inherit from a common Parent and want to utilise the common methods that are not related to the Parent's behaviour. I want to be able to call the methods from the common module inside the Child class that includes/extends it . I have a confusion in its usage because I want to see those common methods as both class methods and instance methods.
class Universe
$knowledge = "Universe comprises of galaxies, stars, planets, steroids, meteoroids, comets, etc"
def universe_comprises_of
puts $knowledge
end
end
module Common
$earth_is = Hash.new
def init(earth_is)
$earth_is = earth_is
end
def statement
puts " Earth is " + $earth_is["attribute"].to_str
end
end
class FlatEarthBelievers < Universe
include Common
earth_is = { :attribute => "Flat !" }
init(earth_is)
end
class RoundEarthBelievers < Universe
include Common
earth_is = { :attribute => "Round like an Orange!" }
Common.init(earth_is)
end
moron = FlatEarthBelievers.new
moron.universe_comprises_of
moron.statement
sensible_person = RoundEarthBelievers.new
sensible_person.universe_comprises_of
sensible_person.statement
There are many things wrong with this code. Set aside the $
variable issue since that is discussed in the comments to your OP.
To begin with, you do:
moron = Flat_earth_believers.new
But you don't have any classes named Flat_earth_believers
. You probably meant FlatEarthBelievers
.
You include
the Common
module, which makes all the methods therein instance methods, but then you try to call them as class methods, here:
class FlatEarthBelievers < Universe
include Common
earth_is = { :attribute => "Flat!" }
init(earth_is) # this is calling a class method
end
and here:
class RoundEarthBelievers < Universe
include Common
earth_is = { :attribute => "Round like an Orange!" }
Common.init(earth_is) # this is calling a class method
end
There's other stuff, but you get the idea.
Anyway, I don't really know what you're trying to do, but I think I would just make Universe
like:
class Universe
KNOWLEDGE = "Universe comprises of galaxies, stars, planets, steroids, meteoroids, comets, etc"
def universe_comprises_of
puts KNOWLEDGE
end
end
And Common
like:
module Common
def statement
puts "Earth is #{self.class::EARTH_IS[:attribute]}"
end
end
Then FlatEarthBelievers
like:
class FlatEarthBelievers < Universe
include Common
EARTH_IS = { :attribute => "Flat!" }
end
Then you can do:
moron = FlatEarthBelievers.new
moron.universe_comprises_of
=> Universe comprises of galaxies, stars, planets, steroids, meteoroids, comets, etc
moron.statement
=> Earth is Flat!
I will also note that Jörg W Mittag wishes to say:
I am one of those Ruby Purists who likes to point out that there is no such thing as a class method in Ruby. I am perfectly fine, though, with using the term class method colloquially, as long as it is fully understood by all parties that it is a colloquial usage. In other words, if you know that there is no such thing as a class method and that the term "class method" is just short for "instance method of the singleton class of an object that is an instance of
Class
", then there is no problem. But otherwise, I have only seen it obstruct understanding.
Let it be fully understood by all parties that the term class method is used above in its colloquial sense.