--20cf300faf9ba9a23004b320223a
Content-Type: text/plain; charset=UTF-8

On Fri, Dec 2, 2011 at 1:49 PM, Steve Klabnik <steve / steveklabnik.com>wrote:

> Abstract base classes are silly in Ruby; why bother with that
> inheritance? Just take advantage of duck typing.
>
> The Team class is totally useless.
>

Steve,

Could you point to an example or description of why you consider abstract
base classes pointless?

I was under the impression that it does make sense to have an abstract
base class that has a number of generic methods and then derived classes:
* add some specific methods
* add some specific attributes
* override some of the inherited methods

I have a specific example I was just implementing with an abstract
base class for an "account" (think "bank account"). There are different
derived classes, e.g. for simple money, but also for credits. Certain
functions are generic (e.g. balance), but certain functions are specific
(e.g. put funds on the account will use decimals for "money", but only
accept integers for "credits"). I have put some demo code below.

Very curious to hear how this design could be improved with duck typing.

Many thanks,

Peter

+++++++++++++++++++++++
demo code:

$ cat derived.rb
class Account

  require 'bigdecimal'

  def initialize
    @balance  
  end

  def balance
   @balance
  end

  def put(amount)
    # do some locking
    @balance + mount
    # release lock
  end
end

class MoneyAccount < Account
  def put(amount)
    raise "you can only put decimal amounts in a MoneyAccount" unless
amount.is_a?(BigDecimal)
    super
  end
end

class CreditAccount < Account
  def put(amount)
    raise "you can only put integer amounts in a CreditAccount" unless
amount.is_a?(Integer)
    super
  end
end

$ irb
1.9.3p0 :001 > require './derived.rb'
 true
1.9.3p0 :002 > ma  oneyAccount.new
 #<MoneyAccount:0x9d3b9f0 @balance
1.9.3p0 :003 > ma.put 3.14
RuntimeError: you can only put decimal amounts in a MoneyAccount
    from /home/peterv/data/derived.rb:23:in `put'
    from (irb):3
    from /home/peterv/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :004 > ma.put(BigDecimal.new("3.14"))
 #<BigDecimal:9c2fd90,'0.314E1',18(36)>
1.9.3p0 :005 > ma.balance
 #<BigDecimal:9c2fd90,'0.314E1',18(36)>
1.9.3p0 :006 > ma.balance.to_s
 "0.314E1"
1.9.3p0 :007 > ca  reditAccount.new
 #<CreditAccount:0x9c2591c @balance
1.9.3p0 :008 > ca.balance
 0
1.9.3p0 :009 > ca.put(BigDecimal.new("2.71"))
RuntimeError: you can only put integer amounts in a CreditAccount
    from /home/peterv/data/derived.rb:30:in `put'
    from (irb):9
    from /home/peterv/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
1.9.3p0 :010 > ca.put(36)
 36
1.9.3p0 :011 > ca.balance
 36

--20cf300faf9ba9a23004b320223a--