On Jul 22, 2005, at 10:50 AM, EdUarDo wrote:

> Hi all again :),
>
> How could I implement this model?
>
> Window <>--------------------- Button
>                                  ^
>                                  |
>                                  |
>                          -----------------
>                          |               |
>                       BigButton      LittleButton
>
>
> Being 'Button' an abstract class or an interface.
> I mean, how do I define an interface? Must I use modules?

In Ruby, we take a relaxed approach to interface.  Quite literally,  
an interface is simply a provided set of methods to call, right?

Our philosophy, Duck Typing, is:  If it walks like a duck and talks  
like a duck, it's a duck.  In other words, if it supports the methods  
we want to call, that's all we care about.

This probably sounds a little unstructured.  I know it scared the  
Java side of me when I came over.  Don't be surprised it you find  
yourself liking it when it finally "clicks" though.  It frees you do  
surprising things:

irb(main):001:0> # The following method needs an object supporting <<...
irb(main):002:0* def append_one_to_ten( target )
irb(main):003:1>   (1..10).each { |n| target << n }
irb(main):004:1> end
=> nil
irb(main):008:0> arr = Array.new
=> []
irb(main):009:0> append_one_to_ten arr
=> 1..10
irb(main):010:0> arr
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):011:0> class Sumation
irb(main):012:1>   def initialize
irb(main):013:2>     @total = 0
irb(main):014:2>   end
irb(main):015:1>   def <<( amount )
irb(main):016:2>     @total += amount
irb(main):017:2>   end
irb(main):018:1>   attr_reader :total
irb(main):019:1> end
=> nil
irb(main):020:0> sum = Sumation.new
=> #<Sumation:0x30bab8 @total=0>
irb(main):021:0> append_one_to_ten sum
=> 1..10
irb(main):022:0> sum.total
=> 55

How did I define the interface?  The comment above the method.  No,  
I'm not kidding.

Don't check type, generally you shouldn't even check for the method.   
Just call it.  The caller was warned what to pass and if they ignore  
that an Exception will be thrown, as it should.

Obviously, there are great uses for classes and modules when you do  
need to share some implementation.  However, in Ruby loosen your  
strangle hold on interface.  You'll be surprised what it can do for you.

"Free your mind."  ;)

James Edward Gray II