使用初始化实例作为其他类实例初始化中的参数

时间:2015-03-23 19:33:15

标签: ruby

我有这些课程(只是一个简化的例子,而不是真实的)

class Shop

  attr_accessor :name, :products

  def initialize(name, products_names=%w(apple orange apple cucumber fennel))
    self.name = name
    self.products = products_names.map {|name| Product.new(self, name)}
  end

end 

class Product

  attr_accessor :shop, :name

  def initialize(shop, name)
    self.shop = shop
    self.name = name
  end

  def existing_products_count # problem_comes_here
    shop.products #i need to process all products initialized for current shop
      .select{|p| p.name==name}.size
  end

  def uniq_code
    "#{name}_#{existing_products_count+1}"
  end

end

这是两个问题:

  1. 这是为self实例初始化
  2. 传递Product的好方法

    1. 如何解决我的案例以处理所有现有的商店产品以进行新产品初始化
    2. 谢谢

      更新

      我现在发明的是(至少它的工作方式与我的需要相同)

      class Shop
      
        attr_accessor :name, :products
      
        def initialize(name, products_names=%w(apple orange apple cucumber fennel))
          Product.class_variable_set(:@@all, []) # << added
          self.name = name
          self.products = products_names.map {|name| Product.new(self, name)}
        end
      
      end 
      
      class Product
      
        attr_accessor :shop, :name
      
        def self.all # << added
          @@all
        end
      
        def initialize(shop, name)
          self.shop = shop
          self.name = name
          self.class.all << self # << added
        end
      
        def existing_products_count # problem goes away here
          self.class.all.products  # << changed
            .select{|p| p.name==name}.size
        end
      
        def uniq_code
          "#{name}_#{existing_products_count+1}"
        end
      
      end
      

      但我对这种解决方案感到不好(我不知道为什么)并且会感谢更好的解决方案

1 个答案:

答案 0 :(得分:0)

我不确定我是否理解这个问题,但这里有一个解释。请注意我是如何更改方法Product#uniq_code

class Shop
  attr_accessor :name, :products    
  def initialize(name, products_names=%w(apple orange apple cucumber fennel))
    self.name = name
    self.products = products_names.map {|name| Product.new(self, name)}
  end    
end 

class Product    
  attr_accessor :shop, :name    
  def initialize(shop, name)
    self.shop = shop
    self.name = name
  end

  def uniq_code # problem_comes_here
    puts "buy #{self.name} #{self.shop.name}"
  end
end

现在让我们举个例子:

at_store = Shop.new("in store", ["bulldozer", "Ducati"])
online   = Shop.new("online", ["can opener", "Makita router"])
arr = [at_store, online]

我们可以这样做:

arr.flat_map { |s| s.products }.each { |p| p.send(:uniq_code) }
  # buy bulldozer in store
  # buy Ducati in store
  # buy can opener online
  # buy Makita router online

这大致是你在寻找什么?

编辑:保存给定商店实例的产品实例:

product_instances = at_store.products
  #=> [#<Product:0x007f93f984f938
  #      @shop=#<Shop:0x007f93f984f988 @name="in_store",
  #      @products=[...]>, @name="bulldozer">,
  #    #<Product:0x007f93f984f910
  #      @shop=#<Shop:0x007f93f984f988 @name="in_store",
  #      @products=[...]>, @name="Ducati">]

以后使用:

product_instances.each { |p| p.uniq_code }
  # buy bulldozer in_store
  # buy Ducati in_store