Ruby Programming Techniques: simple yet not so sim

2020-07-16 06:44发布

问题:

I want to create an object, let's say a Pie.

class Pie 
  def initialize(name, flavor) 
    @name = name 
    @flavor = flavor 
  end 
end

But a Pie can be divided in 8 pieces, a half or just a whole Pie. For the sake of argument, I would like to know how I could give each Pie object a price per 1/8, 1/4 or per whole. I could do this by doing:

class Pie 
  def initialize(name, flavor, price_all, price_half, price_piece) 
    @name = name 
    @flavor = flavor 
    @price_all = price_all
    @price_half = price_half
    @price_piece = price_piece
  end 
end 

But now, if I would create fifteen Pie objects, and I would take out randomly some pieces somewhere by using a method such as

getPieceOfPie(pie_name)

How would I be able to generate the value of all the available pies that are whole and the remaining pieces? Eventually using a method such as:

   myCurrentInventoryHas(pie_name)
   # output: 2 whole strawberry pies and 7 pieces.

I know, I am a Ruby nuby. Thank you for your answers, comments and help!

回答1:

You'll definitely want separate Pie and PiePiece classes

class Pie
  attr_accessor :pieces
  def initialize
    self.pieces = []
  end

  def add_piece(flavor)
    raise "Pie cannot have more than 8 pieces!" if pieces.count == 8
    self.pieces << PiePiece.new(flavor)
  end

  # a ruby genius could probably write this better... chime in if you can help
  def inventory
    Hash[pieces.group_by(&:flavor).map{|f,p| [f, p.size]}]
  end

end

class PiePiece
  attr_accessor :flavor
  def initialize(flavor)
    self.flavor = flavor
  end
end

sample code

p = Pie.new
p.add_piece(:strawberry)
p.add_piece(:strawberry)
p.add_piece(:apple)
p.add_piece(:cherry)
p.add_piece(:cherry)
p.add_piece(:cherry)

p.inventory.each_pair do |flavor, count|
  puts "Pieces of #{flavor}: #{count}"
end

# output
# Pieces of strawberry: 2
# Pieces of apple: 1
# Pieces of cherry: 3


回答2:

Could you create a PieSlice object, and each Pie would have an array of PieSlices?



回答3:

The Pie class could have a counter to indicate what fraction of it remains. The getPieceOfPie method would modify this counter. The myCurrentInventoryHas method could then look at each Pie and see how much of that Pie there is be examining the counter.



回答4:

A piece of pie is not a pie.

(talking in oo terms, an object should have a clear responsibility, making an object a pie AND a slice may not be a clear responsibility assignment).



标签: ruby math