B
Brian Tickler
I have looked around for an answer to this on the mailing list and
Google searches, but I am not finding anything, so sorry if this
question seems too basic but...
I am just learning Ruby, and one of my class assignments is writing a
command line app that tracks an inventory of cars, each car having 6
attributes: VIN, year, make, model, color, and price. We are supposed
to use 2 objects for this exercise, a Car class and a "List of Cars"
class. Then a menu that allows adding a car to the list, deleting a car
from the list, and showing the list.
I could probably done this assignment as-is ...but I wanted to go a
little bit further. It did not seem to make sense that this app did not
call for any persistence and once you made your inventory of cars and
then left the app they were gone. So, armed with pickaxe, I tried to
add file handling, but...that didn't make sense either: since I was
using Car objects and a CarInventory object that is just an array of Car
objects, converting the objects all the time into a format where I could
put them into a delimited text file and then read them out again seemed
crazy.
Then I read farther in pickaxe (past what my class goes into,
unfortunately), and I found Marshalling. That seemed like exactly what
I wanted...I could just dump the CarInventory object with it's whole
array of Cars (into a file called cars.data in this case) and then read
it right back in when needed.
It is almost working, too . But, I am having a problem figuring out
how to connect all the dots from A to D. A couple of things are
nagging:
- The first time the app is run, there is no cars.data file, so I have
to handle that, which I am doing now but it's far from elegant...the app
will decide you don't have any car inventory, initialize the inventory
with a Car that has all nil attributes, and ask you to enter the first
car, then you can Save. This has some issues in that even though I
tried to write the code to later overwrite the "nil car", it is still
there somehow .
- More importantly, once I have a Saved cars.data file and I use
Marshal.load on it, I don't want that "enter the first car" routine to
kick in, so I try to check the first Car object in CarInventory and see
if its VIN number is nil or not. Somehow I am missing the boat here,
and I am sure it's something simple. When I try to get from Marshalled
object -> CarInventory instance -> first Car object -> first Car.vin I
get the following:
cars.rb:106: undefined method `[]' for #<CarInventory:0x3fb97c8>
(NoMethodError)
I am including the entire app below, it's not too big though I am sure
it is much bigger and clunkier than it needs to be ...like I said I am
jsut learning Ruby...any help would be appreciated in fixing my
immediate and dire issues, and/or anything about making the whole app
work more smoothly. You can ignore some of the other
also-not-actually-required-for-this-assignment bells and whistles I have
partially implemented for now. Sorry, I realize it's a bit messy.
----SOURCE
class Car
def initialize(vin, year, make, model, color, price)
@vin = vin
@year = year
@make = make
@model = model
@color = color
@price = price
end
def to_s
if !self.vin
@displayVIN = "(No VIN)"
else
@displayVIN = self.vin
end
if !self.color
@displayColor = ""
else
@displayColor = "(#@color)"
end
"#@displayVIN\t#@year #@make #@model #@displayColor\t#@price\n"
end
def <=> (compareThisCar)
self.year <=> compareThisCar.year
end
attr_reader :vin, :year, :make, :model, :color, rice
attr_writer :vin, :year, :make, :model, :color, rice
end
class CarInventory
@@inventoryFile = "cars.data"
def initialize
if File.exists?(@@inventoryFile)
File.open(@@inventoryFile) do |file|
@carArray = Marshal.load(file)
end
else
@carArray = Array.new
@carArray[0] = Car.new(nil, nil, nil, nil, nil, nil)
end
end
def save
File.open(@@inventoryFile, "w+") do |file|
Marshal.dump(self, file)
end
end
def addCar(car)
if car.vin == nil
@carArray[0] = car
else
@carArray << car
end
end
def updateCar(car)
updateIndex = @carArray.find {|vinMatch| car.vin == vinMatch}
if updateIndex
@carArray[updateIndex] = car
end
end
def delCar(car)
@carArray = @carArray - car
end
def to_s
@carArray.each {|car| car.to_s if car.vin}
end
def sort(sortBy)
case sortBy
when "V":
when "M":
when "P":
when "Y":
else
end
end
def filter(filterArray)
end
end
puts "Car Inventory 1.0\n"
cars = CarInventory.new
firstCar = cars.carArray
firstCar = firstCar[0]
if !firstCar.vin
puts "\nNo car inventory found, please enter the first car:"
puts "\nVIN:"
vin = gets.chomp
puts "\nYear:"
year = gets.chomp
puts "\nMake:"
make = gets.chomp
puts "\nModel:"
model = gets.chomp
puts "\nColor:"
color = gets.chomp
puts "\nPrice:"
price = gets.chomp
newCar = Car.new(vin, year, make, model, color, price)
cars.addCar(newCar)
else
cars.sort("V")
cars.filter(nil)
end
loop do
puts "\nVIN#\t\tCar:\t\t\tPrice:\n"
puts "------------------------------------------------\n"
puts cars.to_s
puts "------------------------------------------------\n"
puts "(A)dd a new car\n"
puts "(E)dit a car\n"
puts "(D)elete a car\n"
puts "(L)ist cars by VIN\n"
puts " by (M)ake and Model\n"
puts " by (P)rice\n"
puts " by (Y)ear\n"
puts "(S)ave changes\n"
puts "(Q)uit\n"
puts "\nCommand: "
command = gets.chomp.upcase
case
when command =~ /^A/ : puts "\nAdd a new car:\n"
puts "\nVIN:"
vin = gets.chomp
puts "\nYear:"
year = gets.chomp
puts "\nMake:"
make = gets.chomp
puts "\nModel:"
model = gets.chomp
puts "\nColor:"
color = gets.chomp
puts "\nPrice:"
price = gets.chomp
newCar = Car.new(vin, year, make, model, color, price)
cars.addCar(newCar)
when command =~ /^E/ : puts "\nEdit a car:\n"
when command =~ /^D/ : puts "\nDelete a car:\n"
when command =~ /^L/ : puts "\nList car inventory by VIN:\n"
when command =~ /^M/ : puts "\nList car inventory by Make and
Model:\n"
when command =~ /^P/ : puts "\nList car inventory by Price range:\n"
when command =~ /^Y/ : puts "\nList car inventory by Year\n"
when command =~ /^S/ : cars.save
when command =~ /^Q/ : puts "Are you sure? [Y/N]"
confirm = gets.chomp.upcase
exit if confirm =~ /^Y/
next
else puts "Illegal Command: #{command}"
end
end
Google searches, but I am not finding anything, so sorry if this
question seems too basic but...
I am just learning Ruby, and one of my class assignments is writing a
command line app that tracks an inventory of cars, each car having 6
attributes: VIN, year, make, model, color, and price. We are supposed
to use 2 objects for this exercise, a Car class and a "List of Cars"
class. Then a menu that allows adding a car to the list, deleting a car
from the list, and showing the list.
I could probably done this assignment as-is ...but I wanted to go a
little bit further. It did not seem to make sense that this app did not
call for any persistence and once you made your inventory of cars and
then left the app they were gone. So, armed with pickaxe, I tried to
add file handling, but...that didn't make sense either: since I was
using Car objects and a CarInventory object that is just an array of Car
objects, converting the objects all the time into a format where I could
put them into a delimited text file and then read them out again seemed
crazy.
Then I read farther in pickaxe (past what my class goes into,
unfortunately), and I found Marshalling. That seemed like exactly what
I wanted...I could just dump the CarInventory object with it's whole
array of Cars (into a file called cars.data in this case) and then read
it right back in when needed.
It is almost working, too . But, I am having a problem figuring out
how to connect all the dots from A to D. A couple of things are
nagging:
- The first time the app is run, there is no cars.data file, so I have
to handle that, which I am doing now but it's far from elegant...the app
will decide you don't have any car inventory, initialize the inventory
with a Car that has all nil attributes, and ask you to enter the first
car, then you can Save. This has some issues in that even though I
tried to write the code to later overwrite the "nil car", it is still
there somehow .
- More importantly, once I have a Saved cars.data file and I use
Marshal.load on it, I don't want that "enter the first car" routine to
kick in, so I try to check the first Car object in CarInventory and see
if its VIN number is nil or not. Somehow I am missing the boat here,
and I am sure it's something simple. When I try to get from Marshalled
object -> CarInventory instance -> first Car object -> first Car.vin I
get the following:
cars.rb:106: undefined method `[]' for #<CarInventory:0x3fb97c8>
(NoMethodError)
I am including the entire app below, it's not too big though I am sure
it is much bigger and clunkier than it needs to be ...like I said I am
jsut learning Ruby...any help would be appreciated in fixing my
immediate and dire issues, and/or anything about making the whole app
work more smoothly. You can ignore some of the other
also-not-actually-required-for-this-assignment bells and whistles I have
partially implemented for now. Sorry, I realize it's a bit messy.
----SOURCE
class Car
def initialize(vin, year, make, model, color, price)
@vin = vin
@year = year
@make = make
@model = model
@color = color
@price = price
end
def to_s
if !self.vin
@displayVIN = "(No VIN)"
else
@displayVIN = self.vin
end
if !self.color
@displayColor = ""
else
@displayColor = "(#@color)"
end
"#@displayVIN\t#@year #@make #@model #@displayColor\t#@price\n"
end
def <=> (compareThisCar)
self.year <=> compareThisCar.year
end
attr_reader :vin, :year, :make, :model, :color, rice
attr_writer :vin, :year, :make, :model, :color, rice
end
class CarInventory
@@inventoryFile = "cars.data"
def initialize
if File.exists?(@@inventoryFile)
File.open(@@inventoryFile) do |file|
@carArray = Marshal.load(file)
end
else
@carArray = Array.new
@carArray[0] = Car.new(nil, nil, nil, nil, nil, nil)
end
end
def save
File.open(@@inventoryFile, "w+") do |file|
Marshal.dump(self, file)
end
end
def addCar(car)
if car.vin == nil
@carArray[0] = car
else
@carArray << car
end
end
def updateCar(car)
updateIndex = @carArray.find {|vinMatch| car.vin == vinMatch}
if updateIndex
@carArray[updateIndex] = car
end
end
def delCar(car)
@carArray = @carArray - car
end
def to_s
@carArray.each {|car| car.to_s if car.vin}
end
def sort(sortBy)
case sortBy
when "V":
when "M":
when "P":
when "Y":
else
end
end
def filter(filterArray)
end
end
puts "Car Inventory 1.0\n"
cars = CarInventory.new
firstCar = cars.carArray
firstCar = firstCar[0]
if !firstCar.vin
puts "\nNo car inventory found, please enter the first car:"
puts "\nVIN:"
vin = gets.chomp
puts "\nYear:"
year = gets.chomp
puts "\nMake:"
make = gets.chomp
puts "\nModel:"
model = gets.chomp
puts "\nColor:"
color = gets.chomp
puts "\nPrice:"
price = gets.chomp
newCar = Car.new(vin, year, make, model, color, price)
cars.addCar(newCar)
else
cars.sort("V")
cars.filter(nil)
end
loop do
puts "\nVIN#\t\tCar:\t\t\tPrice:\n"
puts "------------------------------------------------\n"
puts cars.to_s
puts "------------------------------------------------\n"
puts "(A)dd a new car\n"
puts "(E)dit a car\n"
puts "(D)elete a car\n"
puts "(L)ist cars by VIN\n"
puts " by (M)ake and Model\n"
puts " by (P)rice\n"
puts " by (Y)ear\n"
puts "(S)ave changes\n"
puts "(Q)uit\n"
puts "\nCommand: "
command = gets.chomp.upcase
case
when command =~ /^A/ : puts "\nAdd a new car:\n"
puts "\nVIN:"
vin = gets.chomp
puts "\nYear:"
year = gets.chomp
puts "\nMake:"
make = gets.chomp
puts "\nModel:"
model = gets.chomp
puts "\nColor:"
color = gets.chomp
puts "\nPrice:"
price = gets.chomp
newCar = Car.new(vin, year, make, model, color, price)
cars.addCar(newCar)
when command =~ /^E/ : puts "\nEdit a car:\n"
when command =~ /^D/ : puts "\nDelete a car:\n"
when command =~ /^L/ : puts "\nList car inventory by VIN:\n"
when command =~ /^M/ : puts "\nList car inventory by Make and
Model:\n"
when command =~ /^P/ : puts "\nList car inventory by Price range:\n"
when command =~ /^Y/ : puts "\nList car inventory by Year\n"
when command =~ /^S/ : cars.save
when command =~ /^Q/ : puts "Are you sure? [Y/N]"
confirm = gets.chomp.upcase
exit if confirm =~ /^Y/
next
else puts "Illegal Command: #{command}"
end
end