Michael T. Richter
7/16/2008 4:09:00 AM
[Note: parts of this message were removed to make it a legal post.]
On Wed, 2008-07-16 at 12:45 +0900, misterparker@gmail.com wrote:
> Hey i'm super new at ruby, This is my first class attempt. can i copy
> and paste this into the prompt? or do i need to save it as a .rb file?
Just as a general guideline for the future, if you have a question like
"can I do <foo>?" it might be best to just try it first. For example:
$ irb
irb(main):001:0> class Item
irb(main):002:1> def initialize(item,price,cost)
irb(main):003:2> @price = price
irb(main):004:2> @item = item
irb(main):005:2> @cost = cost
irb(main):006:2> @tax = 0.06
irb(main):007:2> @sales = 0
irb(main):008:2> @salesCount = 0
irb(main):009:2> @salesTaxPayable
irb(main):010:2> @remainingCost = cost
irb(main):011:2> @revPer = @price-@taxPer
irb(main):012:2> @taxPer = @price*@tax
irb(main):013:2> @cash = 0
irb(main):014:2> end
irb(main):015:1> def sale(discount_price)
irb(main):016:2> if discount_price == 0 then
irb(main):017:3* @salesTaxPayable = @salesTaxPayable + @taxPer
irb(main):018:3> @sales = @sales + @revPer
irb(main):019:3> @cash = @cash + @price
irb(main):020:3> @remainingCost = @remainingCost - @revPer
irb(main):021:3> @saleCount = @saleCount + 1
irb(main):022:3> else
irb(main):023:3* @salesTaxPayable = @salesTaxPayable + @taxPer
irb(main):024:3> @sales = @sales + (discount_price - (discount_price*@tax))
irb(main):025:3> @cash = @cash + discount_price
irb(main):026:3> @remainingCost = @remainingCost - (discount_price -
irb(main):027:4* (discount_price*@tax))
irb(main):028:3> @saleCount = @saleCount + 1
irb(main):029:3> end
irb(main):030:2> end
irb(main):031:1> def cash
irb(main):032:2> return @cash
irb(main):033:2> end
irb(main):034:1> def salesTax
irb(main):035:2> return @salesTaxPayable
irb(main):036:2> end
irb(main):037:1> end
=> nil
irb(main):038:0>
It sure looks to me like you can just cut and paste it into irb. ;) It
took me literally ten seconds (I had to wait for my terminal to load
because my memory is topped) to check this.
You'll find that Ruby is very forgiving of this kind of experimentation.
If you can do it, it will let you do it. If you can't, it will tell you
you can't without trashing your system.
Now, on to your class:
> class Item
> def initialize(item,price,cost)
> @price = price
> @item = item
> @cost = cost
> @tax = 0.06
> @sales = 0
> @salesCount = 0
> @salesTaxPayable
> @remainingCost = cost
> @revPer = @price-@taxPer
> @taxPer = @price*@tax
> @cash = 0
> end
If you want to be more concise, try:
@price, @item, @cost = [price, item, cost]
@sales = @salesCount = @remainingCost = @cash = 0
I don't know what you want to do with @salesTaxPayable because as it
stands nothing happens. You also pre-calculate some things which may be
premature. Why not calculate at need and cache?
> def sale(discount_price)
> if discount_price == 0 then
> @salesTaxPayable = @salesTaxPayable + @taxPer
@salesTaxPayable += @taxPer
In general anytime you find yourself doing the "x = x <operator> y"
thing, try "x <operator>= y" instead.
> @sales = @sales + @revPer
> @cash = @cash + @price
> @remainingCost = @remainingCost - @revPer
> @saleCount = @saleCount + 1
> else
> @salesTaxPayable = @salesTaxPayable + @taxPer
> @sales = @sales + (discount_price - (discount_price*@tax))
> @cash = @cash + discount_price
> @remainingCost = @remainingCost - (discount_price -
> (discount_price*@tax))
> @saleCount = @saleCount + 1
> end
> end
In this function you're duplicating a lot of code. There's code in the
if and in the else blocks which are identical. Take them out and
calculate them in one place:
def sale(discount_price = 0)
@salesTaxPayabe += @taxPer
if discount_price == 0 then
@sales = @sales + @revPer
@cash = @cash + @price
@remainingCost = @remainingCost - @revPer
else
@sales = @sales + (discount_price - (discount_price*@tax))
@cash = @cash + discount_price
@remainingCost = @remainingCost - (discount_price - (discount_price*@tax))
end
@saleCount += 1
end
You'll note that I've taken the liberty of giving the discount a default
value of 0. This is just a personal style choice, but I prefer to have
the most common circumstances be the defaults in my code. I've moved
the common calculations out of the branch, putting the sale count
increment at the end and the sales tax payable at the beginning. The
count can be put anywhere, but at the end makes the most sense for my
reading.
> def cash
> return @cash
> end
> def salesTax
> return @salesTaxPayable
> end
Try this instead:
attr_reader :cash, :salesTax
While you're at it, look up attr_writer and attr_accessor as well. Ruby
does a lot to help you avoid the creation of boilerplate code.
> end
--
Michael T. Richter <ttmrichter@gmail.com> (GoogleTalk:
ttmrichter@gmail.com)
All really first class designers are both artists, engineers, and men of
a powerful and intolerant temper, quick to resist the least modification
of the plans, energetic in fighting the least infringement upon what
they regard as their own sphere of action. (Nevil Shute)