I'm writing a program in Ruby with a Product class. I have some exceptions raised whenever the Product is initialized with the wrong type of arguments. Is there a way I can DRY up my raised exceptions (am I even referring to those correctly?) I appreciate the help. Code is below:
class Product
attr_accessor :quantity, :type, :price, :imported
def initialize(quantity, type, price, imported)
raise ArgumentError.new("Type must be a string") if type.class != String
raise ArgumentError.new("Quantity must be greater than zero") if quantity <= 0
raise ArgumentError.new("Price must be a float") if price.class != Float
@quantity = quantity
@type = type
@price = price.round(2)
@imported = imported
end
end
The idiomatic way is to not do the type checks at all, and instead coerce the passed objects (using to_s
, to_f
, etc.):
class Product
attr_accessor :quantity, :type, :price, :imported
def initialize(quantity, type, price, imported)
raise ArgumentError.new("Quantity must be greater than zero") unless quantity > 0
@quantity = quantity
@type = type.to_s
@price = price.to_f.round(2)
@imported = imported
end
end
You will then get the appropriate String/Float/etc. representation of the objects passed, and if they don’t know how to be coerced to those types (because they don’t respond to that method), then you’ll appropriately get a NoMethodError.
As for the check on quantity, that looks a lot like a validation, which you may want to pull out into a separate method (especially if there gets to be a lot of them):
class Product
attr_accessor :quantity, :type, :price, :imported
def initialize(quantity, type, price, imported)
@quantity = quantity
@type = type.to_s
@price = price.to_f.round(2)
@imported = imported
validate!
end
private
def validate!
raise ArgumentError.new("Quantity must be greater than zero") unless @quantity > 0
end
end