Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialImmo Struchholz
10,515 PointsWhy do I have to use @ here?
Hi,
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?
1 Answer
Andrew Stelmach
12,583 PointsIt's better with some spacing and, yes, you need to use @health
here:
class Monster
attr_accessor :name, :health
def initialize(name)
@name = name
@health = 100
end
def hit(amount)
@health -= amount
end
end
Check this out: http://stackoverflow.com/questions/4370960/what-is-attr-accessor-in-ruby
health
returns @health
.
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
Patrick Shushereba
10,911 PointsPatrick Shushereba
10,911 PointsNot exactly. The reason you define an instance variable to use is so that it can be accessed by any method in the class. If you don't use the @ in your hit method, Ruby doesn't know what you're talking about. Using @health lets Ruby know that you're using the variable that you defined with attr_accessor.