Immo Struchholz10,515 Points
Why do I have to use @ here?
I played around a little with the class from the video and added a hit method. It takes an argument(amount) and substracts that from the health of the monster. Here is my code:
class Monster attr_accessor :name, :health def initialize(name) @name = name @health = 100 end def hit(amount) health -= amount end end dragon = Monster.new("Smaug") dragon.hit(25) puts dragon.inspect
This code doesn't run, I get this error:
monster.rb:8:in `hit': undefined method `-' for nil:NilClass (NoMethodError) from scripts/ruby/monster.rb:14:in `<main>'
If I change health to @health inside the hit method however it works just fine. Why is that? I should be able to access it without the @, shouldn't I?
Andrew Stelmach12,374 Points
It's better with some spacing and, yes, you need to use
class Monster attr_accessor :name, :health def initialize(name) @name = name @health = 100 end def hit(amount) @health -= amount end end
health IS A METHOD. This is the critical piece of understanding and this is why your original code doesn't work.
A convenient Rubyism is that you can do
health = something if you have attr_writer in your code (which is provided by attr_accessor).
So, this also works:
class Monster #This provides attr_reader and attr_writer for health attr_accessor :name, :health def initialize(name) @name = name @health = 100 end def hit(amount) #This line uses attr_reader new_health = health - amount #This line uses attr_writer health = new_health end end