views:

72

answers:

2

I create a new object of type Spam, with attr_accessor to both hooray and name and I have the initialize method. I'm expecting when I create a new object the object is loaded with a var of name with "Whammy" and a empty array named hooray. Though I'm not getting this behavior. Can anyone explain, thank you in advance.

module Test
class Spam
 attr_accessor :hooray, :name

 def initialize
    hooray = []
    name = "Whammy"
 end
end 
end

Loading development environment (Rails 3.0.0)
irb(main):001:0> require 'Test'
=> nil
irb(main):002:0> test = Test::Spam.new
=> #<Test::Spam:0x000000031ff470>
irb(main):003:0> test.name
=> nil
irb(main):004:0> test.hooray
=> nil
irb(main):005:0> test.hooray << 5
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.<<
    from (irb):5
    from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0/lib/rails/commands/console.rb:44:in `start'
    from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0/lib/rails/commands/console.rb:8:in `start'
    from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
irb(main):006:0> 
+3  A: 

You want to use instance variables inside an instance of a class to define attributes, not a local variable. local variables will go out of scope as soon as the method is finished executing. the code below should be more along the lines of what you need:

module Test
class Spam
 attr_accessor :hooray, :name

 def initialize
    @hooray = []
    @name = "Whammy"
 end
end 
end
Pete
Thank you, didn't even think about that.
RoR
+4  A: 

The problem here is that you are trying to use the setters directly within the initialize method, but Ruby interprets this as creating local variables, not calling the setters on self.

 def initialize
    hooray = []
    name = "Whammy"
 end

You can work around this in one of two ways; set the attributes directly, such as @attribute:

 def initialize
    @hooray = []
    @name = "Whammy"
 end

Or if you really want to go through the setters (for instance, if you have custom setters which do something interesting), make it explicit with self.setter:

 def initialize
    self.hooray = []
    self.name = "Whammy"
 end
Brian Campbell
Thank you for the explanation
RoR