stesch / no-spoon.de (Stefan Scholl) writes:

> class Shuffle
> 	def initialize(data)
> 		raise(TypeError, "not an array") if data.type != Array

I have to tread carefully here, because there are those on this list
who feel very strongly about all of this, and I don't want to start a
long thread of flames :)

However...

In Ruby, it is generally wrong to check the type of an argument by
asking about it's class. In statically typed languages, a class
defines a type. In Ruby, a type is basically defined by the operations
an object supports.

For example, your shuffle example doesn't really need an Array
parameter. All it requires is an object that responds to #length, and
returns a value when sent #[]. If we remove the test from from your
initializer, we can show this (I also removed the #gsub from each so I
could return non-strings).

     class Shuffle
       def initialize(data)
         @store = data
         @mark = Array.new
         @marked = 0
       end

       def each
         while @marked < @store.length
           while @mark[i = rand(@store.length)]
           end
           @mark[i] = true
           @marked += 1
           yield @store[i]
         end
       end
     end

     # Shuffle a struct
     Triple = Struct.new("Triple", :f1, :f2, :f3)
     stooges = Triple.new("larry", "moe", "curly")

     Shuffle.new(stooges).each {|i| puts i}
  #=>
     larry
     curly
     moe

     # Shuffle a singleton range object
     range = 1..5
     def range.[](i)
       self.begin + i
     end
     Shuffle.new(range).each {|i| puts i}
  #=>
     4
     5
     3
     1
     2


We passed in an object of type Struct::Triple, and yet you shuffled it
fine. Similarly we created a singleton object (an object based on
class Range, but which has an added #[] method), and it shuffles fine
too. This last object doesn't even have a named class describing its
type. 

This whole comment is really independent of the actual implementation
of your Shuffle class. I just wanted to make the more general
observation: normally, you shouldn't check the types of parameters in
Ruby.  When you do, in most cases you'll want to check what messages
an object responds to, rather than what class is has.


Regards



Dave