简体   繁体   English

Ruby 2.1:组成零件自行车->调用nil:NilClass的私有方法“ select”(NoMethodError)

[英]Ruby 2.1: Composing a Bicycle of Parts -> private method `select' called for nil:NilClass (NoMethodError)

I am getting an error when running this code. 运行此代码时出现错误。 The Following is the output: 以下是输出:

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>'

Here is the code: 这是代码:

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

It is clear this line --> puts road_bike.spares.size is given the error NoMethodError, however, I am not sure how I can make a work around to correct this issue for this example. 很明显,这行-> puts road_bike.spares.size出现错误NoMethodError,但是,我不确定如何才能解决此示例的问题。 The spares method is returning an array of Part objects, however it seems my problem lies in the fact the spares method .select is private from the calling object. 备用方法返回一个Part对象数组,但是似乎我的问题在于备用方法.select是调用对象私有的。

Any advice to revise this code would be great. 任何修改此代码的建议都很好。 Thanks. 谢谢。

What's happening here is that Parts#parts is nil . 这里发生的是Parts#partsnil You're getting the error on this line: 您在此行得到错误:

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

In the initializer of Parts , its parts attribute does not get assigned properly: Parts的初始化程序中,未正确分配其parts属性:

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

So when being initialized, it assigns @parts with the value of parts . 因此,在初始时,其分配@parts与价值parts But since parts is not a local variable there, it calls the Parts#parts method, which returns nil . 但是由于parts不是那里的局部变量,所以它将调用Parts#parts方法,该方法返回nil

If you change the initializer to the following: 如果将初始化程序更改为以下内容:

def initialize(parts)
  @parts = parts
end

You'll be able to run the code. 您将能够运行代码。 But subclasses of Parts seem to expect a Hash in the initializer, rather than an Array like their super class does though. 但是, Parts子类似乎希望在初始化程序中使用Hash ,而不是像其父类那样使用Array

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM