iLLUNiS iLLUNiS - 1 year ago 38
Ruby Question

Reverse (?) Class inheritance in Ruby

just messing around with Ruby and was trying the following. I know i could do it with a case statement but what would be the proper way to achieve it?

What i want it to be able to type

Animals.new.interact


and get a proper reply depending on the Animal.

At the moment i get back a reply

You are a eagle
Not defined !
(repl):9:in `fly'
(repl):14:in `interact'
(repl):1:in `<main>'


but i would expect something along those lines (if the sample is a Penguin for example)

You are a penguin
you cannot fly !


Any ideas appreciated.

class Animals
SPECIES = []
attr_accessor :name
def initialize
@name = SPECIES.sample
end

def fly
raise "Not defined !"
end

def interact
puts "You are #{self}"
fly
end

def to_s
"a #{@name}"
end

end

class Penguin < Animals

def initialize
@name = "penguin"
SPECIES << @name
end

def fly
puts "you cannot fly !"
end

end

class Eagle < Animals

def initialize
@name = "eagle"
SPECIES << @name

end

def fly
puts "you fly high up the mountains !"
end
end
Penguin.new
Eagle.new

Answer Source

You definitely haven’t understood classes. Why do you expect to change the behavior of an object by changing one instance variable?

When you do Animals.new you request a new animal. And an Animal behaves exactly like you defined in the Animal class, in which you defined the fly method as:

def fly
raise "Not defined !"
end

So there’s absolutely no reason to expect you cannot fly !.


You could do something like this, however:

SPECIES = []
class Animals
  attr_accessor :name
  def initialize 
    @name = SPECIES.sample
  end

  def fly
  raise "Not defined !"
  end

  def interact
   puts "You are #{self}"
   fly
  end

  def to_s
    "a #{@name}"
  end

end

class Penguin < Animals
  SPECIES << self

  def initialize
    @name = "penguin"
  end

  def fly
    puts "you cannot fly !"
  end
end

class Eagle < Animals
  SPECIES << self

  def initialize
    @name = "eagle"
  end

  def fly
    puts "you fly high up the mountains !"
  end
end

SPECIES.sample.new.interact

Now the SPECIES variable that I have made global stores the different Animal subclasses. When you call SPECIES.sample you get a class like Penguin or Eagle. You instantiate that class, i.e. you get an instance of Penguin that behaves exactly like a penguin and will correctly no whether it can fly.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download