ruby:未定义的局部变量或方法' car' - 修复语法错误

时间:2017-10-27 18:59:09

标签: ruby syntax

我的程序中有一些语法错误,真的很困扰我。因为我不熟悉红宝石,所以我似乎无法弄清楚如何修复它们。第一个错误在标题上,我还有一些我确定。该计划的目的是创建具有品牌,型号和年份的汽车,并让用户输入他们想要的汽车数量,然后在最后显示所有汽车。

有人能指出我正确的方向吗?

这是我的代码:

class Car

def initialize(make, model, year)
 @make = make
 @model = model
 @year = year

end

print "How many cars do you want to create? "
array_of_cars = Array.new  
num_cars = gets.to_i

c = car.new

 for i in 1..num_cars 
    end

puts
print "Enter make for car #{i}: "
make = gets.chomp

print "Enter model for car #{i}: "
model = gets.chomp

print "Enter year for car #{i}: "
year = gets.to_i

c.set_make(make)
c.set_model(model)
c.set_year(year)

array_of_cars << c 
 end 

 puts
 puts "You have the following cars: " 

 for car in array_of_cars 
   puts "#{car.get_year} #{car.get_make} #{car.get_model}" 
  end

3 个答案:

答案 0 :(得分:3)

在ruby中,类名是常量,所以应该以大写字母开头,如class Car。在创建该类的新对象时,可以在类本身上调用new。因此,您可以将car.new更改为Car.new

您还需要在类中定义set_*get_*方法,但由于这是一种常见模式,因此ruby有attr_accessor可用。有关attr_accessor的完整说明,请参阅this answer

答案 1 :(得分:2)

请考虑您的Car任何事情,它只包含数据且没有方法。发生这种情况时,请考虑将其设为Struct而不是classStruct自动生成读写器方法,甚至不指定attr_reader

Car = Struct.new(:make, :model, :year)
array_of_cars = Array.new

while true
    puts
    print "Enter make for car ('x' to exit): "
    make = gets.chomp
    break if make == 'x'

    print "Enter model for car: "
    model = gets.chomp

    print "Enter year for car: "
    year = gets.to_i

    array_of_cars << Car.new(make, model, year)
end

puts
puts 'You have the following cars:' # sorted by year for fun

array_of_cars.sort_by{ | car | car.year }.each do | car |
    puts "#{car.year} #{car.make} #{car.model}"
end

答案 2 :(得分:1)

一些建议。

使用-w选项运行Ruby:

$ ruby -w cars.rb 
cars.rb:17: warning: mismatched indentations at 'end' with 'for' at 16
cars.rb:34: warning: mismatched indentations at 'end' with 'class' at 1
cars.rb:41: warning: mismatched indentations at 'end' with 'for' at 39

并消除警告的原因。

$ ruby -w cars.rb 
How many cars do you want to create? 2
cars.rb:2:in `initialize': wrong number of arguments (given 0, expected 3) (ArgumentError)
    from cars.rb:13:in `new'
    from cars.rb:13:in `<main>'

new调用initialize,因此new必须具有相同数量的参数 作为initialize中的参数。因此,只有在您询问了所有信息后才能创建汽车。

不要在课堂上工作。如上所述,您的代码在Ruby读取时执行 类定义。对于本练习,您可以将其保留在类定义之外的主级别中,或将其放入方法中。

 for i in 1..num_cars 
 end

此循环为空,不执行任何操作。并且更喜欢强大的迭代器而不是这种C,Perl,Java风格(for,while等)。

我用撇号定义字符串并在需要插值时保留双引号(即使这是纳秒和个人选择的问题)。请参阅herethere

如果您想熟悉Ruby编程,我建议The Pickaxe

在Ruby中有很多方法可以做。以下是一个解决方案。

class Car
    attr_reader :make, :model, :year

    def initialize(make, model, year)
        @make  = make
        @model = model
        @year  = year
    end

    def self.make_car # class method (more precisely : singleton method)
        print 'How many cars do you want to create? '
        array_of_cars = Array.new
        num_cars = gets.to_i

        num_cars.times do | i |
            real_index = i + 1
            puts
            print "Enter make for car #{real_index}: "
            make = gets.chomp

            print "Enter model for car #{real_index}: "
            model = gets.chomp

            print "Enter year for car #{real_index}: "
            year = gets.to_i

=begin
            c = Car.new(make, model, year)
            array_of_cars << c 
=end
            # some will tell you to avoid unnecessary variables ...
            array_of_cars << Car.new(make, model, year)
        end

        puts
        puts 'You have the following cars:' # sorted by year for fun

        array_of_cars.sort_by{ | car | car.year }.each do | car |
            puts "#{car.year} #{car.make} #{car.model}"
        end
    end
end # class Car

Car.make_car