Инициализация атрибутов в объектах Ruby - PullRequest
1 голос
/ 17 сентября 2010

Я создаю новый объект типа Спам, с attr_accessor для ура и имени, и у меня есть метод initialize. Я ожидаю, что когда я создаю новый объект, объект загружается с переменным именем «Whammy» и пустым массивом с именем «ура». Хотя я не понимаю этого поведения. Может кто-нибудь объяснить, заранее спасибо.

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> 

Ответы [ 2 ]

8 голосов
/ 17 сентября 2010

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

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

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

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

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

 def initialize
    self.hooray = []
    self.name = "Whammy"
 end
3 голосов
/ 17 сентября 2010

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

module Test
class Spam
 attr_accessor :hooray, :name

 def initialize
    @hooray = []
    @name = "Whammy"
 end
end 
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...