如何将一个 class 的实例添加到另一个 class (Ruby) 的数组中

How to add an instance of a class into an array of another class (Ruby)

我的目录中有两个文件,一个是 garage.rb,另一个是 car.rb

car.rb 文件只包含一个汽车对象:

class Car
end

garage.rb文件如下:

require 'car.rb' #Makes car class accessible in garage.rb

class Garage
  def initialize
    @capacity = []
  end

  attr_accessor :capacity

end

当我通过调用 car = Car.new 创建 car 的新实例时,如何将 car 对象放入我的默认 @capacity 数组中?

基本上,每当我调用 car = Car.new 时,我都希望 car 立即放入 @capacity 数组中。

我知道我可以做一个像这样的函数:

def add_car_to_garage(car)
  capacity << car
end

但是,我希望汽车在创建时从车库开始,所以我不想要将它添加到数组的方法,我只希望它在 [= 的实例时自动从车库开始20=] 已创建。

如有任何建议,我们将不胜感激。谢谢。

您可以在 Car class 中使用带有 each_object 方法的 ObjectSpace 模块来定义跟踪每个活动实例的方法,如下所示:

class Car

  def self.all
    ObjectSpace.each_object(self).to_a
  end
end
require_relative 'car' # Makes car class accessible in garage.rb 
                                                                 
class Garage                                                     
  def initialize                                                 
    @capacity = Car.all                                          
  end                                                            
                                                                 
  attr_accessor :capacity                                        
end                                                                                                       
car1 = Car.new        
car2 = Car.new        
car3 = Car.new        
                      
garage = Garage.new   
                      
print garage.capacity   # => [#<Car:0x0000563fa14128c8>, #<Car:0x0000563fa1412918>, #<Car:0x0000563fa1412990>]

另请注意,我已使用 require_relative 包含同一目录中的 car.rb class。


编辑评论问题和 Cary Swoveland 建议:

class Car
end
require_relative 'car' # Makes car class accessible in garage.rb 
                                                                 
class Garage                                                     
  def initialize; end                                            
                                                                 
  def capacity                                                   
    ObjectSpace.each_object(Car).to_a                            
  end                                                            
end                                                              
                                                                 
car1 = Car.new                                                   
garage = Garage.new                                              
car2 = Car.new                                                   
                                                                 
print garage.capacity # => [#<Car:0x000055d7bd236a00>, #<Car:0x000055d7bd236b18>]                                            

另请注意,我删除了 attr_accessor :capacity,因为在这种情况下您不需要它。

Car 的实例集合应由 class 保存和维护,并根据需要提供给其他 class。可以按如下方式完成。

class Car
  @cars = []

  class << self
    attr_reader :cars
  end

  def initialize
    self.class.cars << self
  end
  
  def self.remove_car(car)
    cars.delete(car)
  end
end
class Garage
  def self.cars
    Cars.cars
  end
end

class的创建Car初始化class实例变量@cars并为其创建getter,Cars::cars,后者通过在 Car 的单例 class.

上调用 attr_reader

让我们造一辆车:

car1 = Car.new
  #=> #<Car:0x00007fcf3db76fd8>

然后

Car.cars
  #=> [#<Car:0x00007fcf3db76fd8>]
Garage.cars
  #=> [#<Car:0x00007fcf3db76fd8>]

创造另一辆车。

car2 = Car.new
  #=> #<Car:0x00007fcf3db5c9a8>

然后

Car.cars
  #=> [#<Car:0x00007fcf3db76fd8>, #<Car:0x00007fcf3db5c9a8>]
Garage.cars
  #=> [#<Car:0x00007fcf3db76fd8>, #<Car:0x00007fcf3db5c9a8>]

现在移除一辆车。

Car.remove_car(car1)
  #=> #<Car:0x00007fcf3db76fd8>

然后

Car.cars
  #=> [#<Car:0x00007fcf3db5c9a8>]
Garage.cars
  #=> [#<Car:0x00007fcf3db5c9a8>]

要使 class 实例变量 @cars 可用于 Garage 的实例,请添加一个简单的实例方法:

class Garage
  def all_cars
    self.class.cars
  end                                                            
end
Garage.new.all_cars
  #=> [#<Car:0x00007fcf3db5c9a8>]

Car

class << self
  attr_reader :cars
end

也可以写成

singleton_class.public_send(:attr_reader, :cars)