2010-09-17 6 views
1

Je crée un nouvel objet de type Spam, avec attr_accessor à la fois hourra et name et j'ai la méthode initialize. Je m'attends à ce que lorsque je crée un nouvel objet, l'objet soit chargé avec un nom de var avec "Whammy" et un tableau vide nommé hourra. Bien que je ne reçois pas ce comportement. Quelqu'un peut-il expliquer, merci d'avance.Initialisation des attributs dans les objets Ruby

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> 
+0

'Test' n'est probablement pas un bon nom de module, car Test :: Unit a' Test' en tant que module. –

Répondre

3

Vous souhaitez utiliser des variables d'instance dans une instance d'une classe pour définir des attributs, et non une variable locale. Les variables locales seront hors de portée dès que la méthode aura fini d'être exécutée. le code ci-dessous devrait être plus le long des lignes de ce que vous avez besoin:

module Test 
class Spam 
attr_accessor :hooray, :name 

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

Merci, n'y pensais même pas. – RoR

8

Le problème ici est que vous essayez d'utiliser les setters directement dans la méthode initialize, mais Ruby interprète cela comme la création de variables locales, ne pas appeler les setters sur self.

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

Vous pouvez contourner ce problème de deux manières différentes; définir les attributs directement, tels que @attribute:

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

Ou si vous voulez vraiment passer par les setters (par exemple, si vous avez setters personnalisés qui font quelque chose d'intéressant), rendre explicite avec self.setter:

def initialize 
    self.hooray = [] 
    self.name = "Whammy" 
end 
+1

Merci pour l'explication – RoR

Questions connexes