Reputation: 2467
I'm trying to get the following code to work.
class Animal
end
class Tiger < Animal
@hunger = 100
def self.hunger
@hunger
end
def run
puts "The Tiger runs"
@hunger += 10
end
end
class Statistics
puts "This tigers hunger is: #{Tiger.hunger}"
end
tiger = Tiger.new()
tiger.run
So the tiger has a variable called hunger
which is by itself at the top of the Tiger
class. I want to make it so this variable can be changed throughout the class methods. For example in run
the hunger is set to hunger += 10
, but when I run this code I get an undefined method '+' for nil:NilClass (NoMethodError)
. What do I do to make this program work so the variable can be changed and then displayed in the Statistics
class?
Upvotes: 0
Views: 63
Reputation: 36110
The problem is that you have completely mushed class and instance variables/methods together.
If you want to use instances (which you should):
class Animal; end
class Tiger < Animal
attr_reader :hunger
def initialize
@hunger = 100
end
def run
puts "The Tiger runs"
@hunger += 10
end
end
class Statistics
def self.show(tiger)
puts "This tigers hunger is: #{tiger.hunger}"
end
end
tiger = Tiger.new
tiger.run
Statistics.show(tiger)
If you want to use class methods/variables:
class Animal; end
class Tiger < Animal
@hunger = 100
def self.hunger
@hunger
end
def self.run
puts "The Tiger runs"
@hunger += 10
end
end
class Statistics
def self.show
puts "This tigers hunger is: #{Tiger.hunger}"
end
end
Tiger.run
Statistics.show
Note that @hunger
is now a class instance variable of Tiger
. The difference between class instance variables and class variables (ones defined with @@
) is that the latter is shared by all descendants of the said class, while the former is only tied to the class where it was defined.
I do not agree with your descision about Statistic
in either case though.
Upvotes: 2
Reputation: 222
Don't you need an initialize method in your Tiger class?
def initialize()
@hunger = 100
end
I am confused about your Statistics class. Shouldn't this be a method in the Tiger class? How does it know what Tiger to access? I would add that puts in a method taking your tiger as a parameter if you want to do that.
class Statistics
def tiger_stat(tiger_name)
puts "This tigers hunger is: #{tiger_name.hunger}"
end
end
Edit* this is the code I would use:
class Animal
def initialize(animal_type, hunger_start)
@animal_type = animal_type
@hunger = hunger_start
end
def hunger_print
puts "This #{@animal_type}'s hunger is: #{@hunger}."
end
end
class Tiger < Animal
def initialize
super("Tiger", 100)
end
def run
puts "The Tiger runs"
@hunger += 10
end
end
This way you can call hunger_print on any animal without worrying about the type or making an extra class. You could do something like.
tiger = Tiger.new
tiger.run
tiger.hunger_print
Upvotes: 1
Reputation: 166
You can use class variable that is access from both instance and class methods.
class Animal
@@hunger = 100
def self.hunger
@@hunger
end
def self.increase_hunger
@@hunger +=1
end
def hunger
@@hunger
end
def increase_hunger
@@hunger += 1
end
end
Animal.increase_hunger
puts Animal.hunger # => 101
animal = Animal.new
animal.increase_hunger
puts animal.hunger # => 102
Upvotes: 0