2010-09-17 3 views
1

Я создаю новый объект типа Spam, с attr_accessor как для ура и имени, так и у меня есть метод инициализации. Я ожидаю, когда я создам новый объект, объект загружается с именем var с именем «Whammy» и пустым массивом с именем hooray. Хотя я не получаю такого поведения. Может кто-нибудь объяснить, спасибо заранее.Инициализация атрибутов в объектах 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 :: Unit имеет «Test» в качестве модуля. –

ответ

3

Вы хотите использовать переменные экземпляра внутри экземпляра класса для определения атрибутов, а не локальной переменной. локальные переменные выйдут из области действия сразу после завершения метода. Приведенный ниже код должен быть больше вдоль линий, что вам нужно:

module Test 
class Spam 
attr_accessor :hooray, :name 

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

Спасибо, даже не подумал об этом. – RoR

8

Проблема здесь состоит в том, что вы пытаетесь использовать сеттеры непосредственно в методе initialize, но Руби интерпретирует это как создание локальных переменных, не вызывая сеттеры на self.

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

Вы можете обойти это одним из двух способов; установить атрибуты непосредственно, например, @attribute:

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

Или, если вы действительно хотите, чтобы пройти через сеттер (например, если у вас есть собственные сеттера, которые делают что-то интересное), сделать это явно с self.setter:

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

Спасибо за объяснение – RoR

Смежные вопросы