Duck typing bunches of strings

L

listrecv

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.
 
D

Daniel Baird

------=_Part_7150_7761460.1143443414501
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

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


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.


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

------=_Part_7150_7761460.1143443414501--
 
J

Jason Hutchens

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
 
D

dblack

Hi --

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.

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! http://www.manning.com/books/black
 
L

listrecv

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.
 
L

Logan Capaldo

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
 
J

Jason Hutchens

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.
 
M

Mark T

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top