On Sat, 1 Apr 2006, [email protected] wrote:
me not very rubyish to be switching based on the class of an object. As I
understand it, the more conventional way to deal with potentially diverse
argument types is to use the respond_to? method. This keeps the door open
for duck typing.
i generally do use duck typing, but sometimes it is simply not
appropriate or
become too verbose. for example, consider a matrix class with the
following
behaviour
1d
m[true] #=> all data returned
m[] #=> all data returned
m[true] = elems #=> data along all dims set
m[] = elems #=> data along all dims set
m[int] #=> treat as 1d array, return elem
m[int] = elem #=> treat as 1d array, set idx to elem
m[off, len] #=> treat as 1d array, return elems off thru
len
m[off, len] = elem #=> treat as 1d array, set elems off thru len
to elem
m[a … b] #=> treat as 1d array, return elems in range
m[a … b] = elem #=> treat as 1d array, set elems in range to
elem
m[n] #=> idx one matrix by another
2d
generalize all above so multiple indices access in
multi-dimensional
fashion. eg
m[0,1,2] #= return idx x,y,z
m[0,30..42,true] #= return column 0, rows 30 to 42, in all height
dims
now, in case you are thinking that i’m just being difficult, this is
exactly
how the narray class works
http://narray.rubyforge.org/SPEC.en
have fun writing that with respond_to? !!
also, when working with concrete data structures (like binary output
from C
programs) it’s often quite sufficient to have a type mapping. further
more
it’s sometimes critical, for instace writing the word located at
offset=42,
len=4 with a packed int value or sending a given sequence of bytes down
a
socket that a given type is used and it’s much more natural to write
def send buf, which = nil
case which
when Fixnum
socket.write [which].pack(‘N’)
socket.write buf
when NilClass
socket.write [buf.size].pack(‘N’)
socket.write buf
when Range
length = which.last - which.first
socket.write [length].pack(‘N’)
socket.write buf[which]
else
raise TypeError, which.class
end
end
than something using respond_to?.
don’t get me wrong - i defintely advocate duck typing, but when the
number of
possible input types becomes large and behaviour is different depending
on
that type it becomes cumbersome. this is the price we pay for not
having c–
style polymorphism. in fact, it’s very common to see the two styles
combined:
case arg
when Fixnum
…
when Range
…
else # dunno - assume String and use in a duck type fashion
end
context, what would a maybe value do? Either behavior seems wrong.
i disagree - ruby (and hardware) already supports this style of logic in
several ways:
harp:~ > irb
irb(main):001:0> nan = 0.0/0.0
=> NaN
irb(main):002:0> nan * 42
=> NaN
irb(main):003:0> nan * 42 + 42.0
=> NaN
irb(main):004:0> obj = Object.new and obj.taint
=> #Object:0xb75a5fac
irb(main):005:0> (obj.to_s << “string”).tainted?
=> true
irb(main):006:0> (“string” << obj.to_s).tainted?
=> true
there’s no good reason, imho, why this style of logical behaviour could
not be
part of the logical classes (TrueClass/FalseClass) and operators (and,
or,
not).
regards.
-a