I want to be able to initialize a new Car object and pass it a Person object in the parameters, so it can be saved in that Person's @cars array. Currently, I take this approach:
person = Person.new("Michael")
car = Car.new("Honda", "Accord")
person.add_car(car)
person.add_car(Car.new("Ford", "Taurus"))
person.add_car(Car.new("Toyota", "Prius"))
person.display
However, I'd like to be able to create a new car instance and pass it the Person object I want it associated with. For example:
person = Person.new("Michael")
Car.new("Honda", "Accord", person)
Car.new("Toyota", "Camry", person)
Car.new("Chevy", "Tahoe", person)
person.display
Is that even possible?
class Person
attr_accessor :name
def initialize(name)
super
@name = name
@cars = []
end
def display
puts "#{@name} has #{@cars.length} cars"
puts "----------------------------"
@cars.each do |car|
puts "#{car.make} #{car.model}"
end
end
def add_car(car)
@cars.push(car)
end
end
class Car
attr_accessor :make, :model
def initialize(make, model)
@model = model
@make = make
end
def display
puts "#{@make} #{@model}"
end
end
Yes, that is possible, Car#initialize
can call methods on its arguments:
class Car
def initialize(make, model, person = nil)
@model = model
@make = make
person.add_car(self) if(person)
end
#...
end
This would be my implementation:
class Car
attr_accessor :make, :model
def initialize(make, model)
self.make = make
self.model= model
end
end
Person class
class Person
attr_accessor :name, :cars
def initialize(name, cars=[])
self.name = name
self.cars = cars || []
end
def add_car(*args)
raise ArgumentError, 'invalid arguments' if (
(args.size > 2 or args.size == 0) or
(args.size == 1 and !args[0].is_a?(Car))
)
new_car = (args.size == 2) ? Car.new(*args) : args[0]
self.cars << new_car
new_car
end
end
Now you can:
person = Person.new("Michael")
car = Car.new("Honda", "Accord")
person.add_car(car)
person.add_car("Ford", "Taurus")
person.add_car("Toyota", "Prius")
person.display
The add_car method creates a new car when make and model are passed as parameters.
Yes, it is possible as mu is too short
's answer demonstrated, but that doesn't really make sense in my opinion. Your cars can't be used in any context without a Person
, and said parameter contributes no data necessary to construct the Car
object.
I would design such an API as follows:
class Person
def initialize(name)
@name = name
end
def cars
@cars ||= Array.new # Equivalent to @cars || @cars = []
end
end
person = Person.new 'Michael'
taurus = Car.new 'Ford', 'Taurus'
prius = Car.new 'Toyota', 'Prius'
person.cars << taurus << prius << Car.new('Honda', 'Accord')
This is a simpler and more direct form of KandadaBoggu
's implementation that takes advantage of the Array#<<
method in order to naturally associate Car
s with a Person
, and also doubles as an attribute reader.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.