2014-09-07 1 views
1

У меня возникает ошибка при запуске этого кода. Ниже приводится выход:Ruby 2.1: Составление велосипеда деталей -> частный метод `select 'для nil: NilClass (NoMethodError)

L 
Bicycle#Ex3.rb:32:in `spares': private method `select' called for nil:NilClass (NoMethodError) 
    from Bicycle#Ex3.rb:10:in `spares' 
    from Bicycle#Ex3.rb:111:in `<main>' 

Вот код:

class Bicycle 
    attr_reader :size, :parts 

    def initialize(args={}) 
    @size  = args[:size] 
    @parts = args[:parts] 
    end 

    def spares 
    parts.spares # return an array 
    end 

    def lead_days 
    1 
    end 
    #... 
end 

class Parts 
    attr_reader :parts 

    def initialize(args={}) 
    @parts = parts 
    end 

    def size 
    parts.size 
    end 

    def spares 
    parts.select{|part| part.needs_spare} 
    end 
end 

class Part 
    attr_reader :name, :description, :needs_spare 

    def initialize(args) 
    @name  = args[:name] 
    @description = args[:description] 
    @needs_spare = args.fetch(:needs_spare, true) 
    end 
end 

class RoadBikeParts < Parts 
    attr_reader :tape_color 

    def post_initialize(args) 
    @tape_color = args[:tape_color] 
    end 

    def local_spares 
    {tape_color: tape_color} 
    end 

    def default_tire_size 
    '23' 
    end 
end 

class MountainBikeParts < Parts 
    attr_reader :front_shock, :rear_shock 

    def post_initialize(args) 
    @front_shock = args[:front_shock] 
    @rear_shock = args[:rear_shock] 
    end 

    def local_spares 
     { rear_shock: rear_shock} 
    end 

    def default_tire_size 
    '2.1' 
    end 
end 

chain = Part.new(
       name: 'chain', 
       description: '10 speed') 

road_tire = Part.new(
        name: 'tape_size', 
        description: '23') 
tape = Part.new(
       name: 'tape_color', 
       description: 'red') 
mountain_tire = Part.new(
         name: 'tire_size', 
         description: '2.1') 
rear_shock = Part.new(
         name: 'rear_shock', 
         description: 'Fox') 

front_shock = Part.new(
         name: 'front_shock', 
         description: 'Manitou', 
         needs_spare: false) 

road_bike_part = Parts.new([chain, road_tire, tape])         

road_bike = Bicycle.new(
         size: 'L', 
         parts: Parts.new([chain, 
              road_tire, 
              tape])) 

puts road_bike.size 
#puts road_bike.parts.size 
puts road_bike.spares.size 

ясно эта линия -> ставит road_bike.spares.size дается NoMethodError ошибки, однако, я не конечно, как я могу сделать работу, чтобы исправить эту проблему для этого примера. Метод spares возвращает массив объектов Part, однако, похоже, моя проблема заключается в том, что метод spares .select является private из вызывающего объекта.

Любые советы по пересмотру этого кода были бы замечательными. Благодарю.

+0

Исключения говорят ясно, что вы вызываете метод 'spares' на ноль. Глядя на код, я также сомневаюсь, что вы не знаете, что делаете. Почему это не AR? –

+0

Благодарим за быстрый ответ. Я не уверен, что вы имеете в виду, когда спрашиваете о AR? Не могли бы вы пояснить, пожалуйста? – JnL

+0

Это сообщение о простом Ruby, а не Rails, поэтому это не AR (ActiveRecord) экземпляры. Хотя в Rails вы также можете иметь классы, которые не являются подклассами AR @Michal Szyndel;) – fivedigit

ответ

2

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

# parts is nil 
parts.select{|part| part.needs_spare} 

В инициализаторе Parts, его атрибут parts не получает назначен правильно:

def initialize(args={}) 
    @parts = parts 
end 

Таким образом, когда инициализируется, он присваивает @parts со значением от parts. Но так как parts не является локальной переменной, он вызывает метод Parts#parts, который возвращает nil.

Если изменить инициализатору на следующее:

def initialize(parts) 
    @parts = parts 
end 

Вы сможете выполнить код. Но подклассы Parts, похоже, ожидают Hash в инициализаторе, а не Array, как и их суперкласс.

+0

Благодарим вас за ответ и последующие действия в подклассах. Когда я следую этим примерам, в следующей части мы рассмотрели проблему с массивом и возможные варианты рефакторинга кода. – JnL

+0

А я вижу. Удачи! – fivedigit

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