Duck typing bunches of strings

In my quest to master the fine art of duck typing / overloading, I’ve
run into this probem:

How can I identify a collection?
The problem is: String mixes in Enumerable, although it ain’t a
collection.

My method wants to act differently if it’s given a collection, then if
it’s just given a single object. I would check .respond_to? :each -
but String does, unfortunately.

Currently, I’m forced to do .kind_of? Array - but this ain’t duck
typing.

Any ideas? I’d like to separate Array, Hash, Set, etc. etc. from
single member objects.

What’s wrong with “object.kind_of?(Enumerable)” and
“class.include?(Enumerable)”?

my_array = Array.new
my_array.kind_of?(Enumerable) # => true
Array.include?(Enumerable) # => true

maybe you just want anything that has respond_to? :each and isn’t a
String.

From memory String doing Enumerable is a bit of a special case; if you
eliminate just String and any of it’s subclasses you’re probably left
with
the “real” Enumerables.

;Daniel

On 27/03/06, [email protected] [email protected] wrote:

but String does, unfortunately.

Currently, I’m forced to do .kind_of? Array - but this ain’t duck
typing.

Any ideas? I’d like to separate Array, Hash, Set, etc. etc. from
single member objects.


Daniel B.
http://danielbaird.com (TiddlyW;nks! :: Whiteboard Koala :: Blog ::
Things
That Suck)
[[My webhost uptime is ~ 92%… if no answer pls call again later!]]

String is also Enumerable, see OP.

Hi –

On Mon, 27 Mar 2006, [email protected] wrote:

Currently, I’m forced to do .kind_of? Array - but this ain’t duck
typing.

Any ideas? I’d like to separate Array, Hash, Set, etc. etc. from
single member objects.

If you really want to do duck typing in your method, then you would
need to prepare the objects in advance, by having them learn a
particular method, probably via an extend operation. Then your method
can just ask each object to execute its version of that method.

David


David A. Black ([email protected])
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! Ruby for Rails

On Mar 27, 2006, at 10:43 AM, [email protected] wrote:

That wouldn’t be very duckish - I’d still need to explicitly state
which objects are acceptable - the whole point is to leave that up to
the user, as long as the object can do what it needs to, I never need
to hear it’s name.

Just curious, but what happens if you just throw a string at it?
str.each { |s| } tends to be str most of the time anyway. alternatively:

class Object
def scalar?
true # or possibly not respond_to? :each
end
end

module Enumerable
def scalar?
false
end
end

class String
def scalar?
true
end
end

Thanks to the magic of inheritance it will all work out

ri Enumerable
The +Enumerable+ mixin provides collection classes with several
traversal and searching methods, and with the ability to sort. The
class must provide a method +each+, which yields successive members
of the collection…

ri String.each
Splits str using the supplied parameter as the record separator
(+$/+ by default), passing each substring in turn to the supplied
block.

Okay, so maybe String shouldn’t mixin Enumerable in the first place.

On Tue, 28 Mar 2006 03:33:12 +0900, Logan C. wrote:

Just curious, but what happens if you just throw a string at it?
str.each { |s| } tends to be str most of the time anyway.

From the docs:

Splits str using the supplied parameter as the record separator
(+$/+ by default), passing each substring in turn to the supplied
block. If a zero-length record separator is supplied, the string is
split on +\n+ characters, except that multiple successive newlines
are appended together.

String#each is actually the same as String#each_line (one is aliased to
the other).

To the OP: why do you want to exclude String? Shouldn’t you allow your
user to consider a string as a collection of lines? That way, someone
using your library to work on data from a newline-separated file doesn’t
have to parse it themselves, just load it into a String and call your
method on it.

Mark T

That wouldn’t be very duckish - I’d still need to explicitly state
which objects are acceptable - the whole point is to leave that up to
the user, as long as the object can do what it needs to, I never need
to hear it’s name.