Reputation: 7441
I'm convinced I've had this working before!
I have the following class. The title string is created within the class the fname and lname strings are passed in as parameters. However, I can't seem to ever get the @title object to return anything other than nil.
What am I doing wrong here?
class Person
attr_accessor :fname, :lname, :title
def initialize(fname, lname)
@fname = fname
@lname = lname
@title = title
end
def string1
@lname + ", " + @fname
end
@title = "Director"
def string2
@title
end
end
p = Person.new("Yukihiro", "Matsumoto")
p p.string1
p p.string2
Upvotes: 1
Views: 82
Reputation: 5490
You're not passing title
to the constructor. You need to have something along the lines of
def initialize(fname, lname, title)
@fname = fname
@lname = lname
@title = title
end
and call it with
p = Person.new("Yukihiro", "Matsumoto", "sensei")
The line @title = "Director"
is executed during the class definition, which sets the variable on the class Person
itself, rather than during the construction of an instance of the class, which is why the instance variable @title
is not being set to "Director" in the new object you create with Person.new
.
In fact, here's how to show that this is what's happening. Adding this method
class Person
def self.string3
@title
end
end
adds a class method to Person
to get the class's instance variable that was set during the class definition:
>> p Person.string3
"Director"
Upvotes: 1
Reputation: 5821
The following code:
class Person
attr_accessor :fname, :lname
def initialize(fname, lname)
@fname = fname
@lname = lname
end
def string1
@lname + ", " + @fname
end
def title
@@title
end
@@title = "Director"
def string2
@@title
end
end
p = Person.new("Yukihiro", "Matsumoto")
p p.string1
p p.string2
gives the following output when run with Ruby 1.9.3:
"Matsumoto, Yukihiro"
"Director"
I've assumed that you want to keep the title the same for all the objects you create. If not, then iamnotmaynard's answer is what you're after.
Upvotes: 1
Reputation: 211560
Within the context of your class, @title
refers to the class instance variable. Within the context of an instance method, @title
refers to an instance variable. You're confusing these two.
What you need instead is a lazy initializer if you have some kind of default that you need applied:
def title
@title ||= "Director"
end
Or better, to populate it in the first place. One way to fix this is to augment your initialize method:
def initialize(fname, lname, title = nil)
@fname = fname
@lname = lname
@title = title || "Director"
end
Upvotes: 2