D
David Masover
Wasn't my use case.
My mistake, sorry about that.
Nice talking, though! I've been on ruby-talk less than a day, and I'm happy to
be here.
Wasn't my use case.
Well, the desired goal is in fact to recognize objects that are numeric. One
of the purposes of classes in OOP is to categorize things.
The only point of using Ruby (or any other tool in the universe) is
to get a job done. I would never use a Ruby feature just because
Ruby makes it possible.
Numeric === v is not a static typing convention (see http://en.wikipedia.org/wiki/Type_system)
. It's just OOP. It says in computer-understandable terms exactly
what you expressed in English: "v is numeric."
I don't even know what the ability to respond to :to_int means. Does
that mean the entity is numeric? Does a numeric string qualify? Does
a floating point number qualify? Could Array support this method?
Does every class that responds to to_int do semantically equivalent
things? (think Cowboy#draw and Artist#draw). The only way to tell is
to test it or look it up.
This doesn't make it "marginally" less readable than Numeric === v,
IMO.
Different strokes, of course...
:to_i is actually rather different, as it will convert a string
(even a non-numeric string like "2a"). That's an example of having
to know the implementation of the method to determine whether
testing responds_to? makes sense. For all I know, :to_i may in fact
be the desired method, but Elizabeth used :to_int, and I assume it
was for a reason.
That's true, but it wasn't my point. The question is whether all
methods with the same name in all active classes should be
semantically equivalent. I think that's a rather larger assumption
than that Numeric means "numeric."
Not really, no. That reflects an attitude that has more to do with
C++ or Java than with OOP.
Not everything which behaves as a number will inherit from Numeric,
so that makes it useless and potentially misleading as a
categorization tool.
If you want you know whether an object is in some category in an OO
way, you come up with a way to ask it.
Mark Wilden said:like Ruby isn't a tool, it's a "mindset." We don't forgo something
like Numeric === v because it's _wrong_ (the OP in fact said it was
slightly more readable), but because Ruby has duck-typing, and why use
Ruby if you can't duck type? I hope I'm not the only person to see how
From: "Mark Wilden said:So if I can solve
a programming problem simply by asking what builtin class an object
is, as opposed to seeing if it responds to a certain method name,
knowing nothing about what that method actually does, I'll go with the
former.
On 28 May 2008, at 23:23, Mark Wilden wrote:
Numeric may well mean "numeric" in some particular sense, but that is
only a subset of all objects which may have a valid numeric
representation. As I said, you're applying a static typing mindset to
a place where it's not necessary and whilst Ruby will let you do that,
in the long term you'll find yourself doing much more work with very
little (if any) gain in software robustness. In fact if you're writing
a library you'll introduce additional fragility to code interfacing
with it because Ruby programmers generally expect Duck Typing and
write accordingly.
Ellie
I must respectfully disagree. I learned OOP (in 1989) before C++ was
even hardly available on PCs, much less Java. The OOP language I
learned was an amalgam of Smalltalk and Lisp.
I can say
quite categorically, that in OOP, classes are ways to generalize. You
generalize based on characteristics and behaviors. A class is not
simply a random collection of methods. It would be rather useless if
class was unrelated to category.
But I'm finding these remarks about "attititude" kind of amusing. It's
like Ruby isn't a tool, it's a "mindset." We don't forgo something
like Numeric === v because it's _wrong_ (the OP in fact said it was
slightly more readable), but because Ruby has duck-typing,
However, the use case
might be that any object with that method is fine and dandy. In that
case, I totally agree that checking for response to it is reasonable,
if not 100% reliable. But if we're looking for Fixnums, Floats, and
other builtin classes, then checking again Numeric seems
straightforward.
True. And often the most straightforward and fundamental way to do
that is to call its #class method.
Their power is indeed to
categorize and generalize objects, which can be specialized with
inheritance (another old school concept, I suppose).
I must respectfully disagree. I learned OOP (in 1989) before C++ was even
hardly available on PCs, much less Java. The OOP language I learned was an
amalgam of Smalltalk and Lisp. I cut my teeth on Bertrand Meyer, Adele
Goldbert, Brad Cox, and Grady Booch. I can say quite categorically, that in
OOP, classes are ways to generalize. You generalize based on characteristics
and behaviors. A class is not simply a random collection of methods. It would
be rather useless if class was unrelated to category.
But I'm finding these remarks about "attititude" kind of amusing. It's like
Ruby isn't a tool, it's a "mindset." We don't forgo something like Numeric
=== v because it's _wrong_ (the OP in fact said it was slightly more
readable), but because Ruby has duck-typing, and why use Ruby if you can't
duck type? I hope I'm not the only person to see how totally back-asswords
this kind of argument is.
The idea of duck typing, as I understand it, is to embrace this
inalterable fact about Ruby objects, rather than try to wish it away,
with ancestry checks and the like. This makes sense to me; it stands
to reason that a language with objects whose types can change during
runtime would be well-served by a programming style that deals as
directly and economically as possible with precisely that condition.
I have to admit that I was quite disappointed that my implementation
of traits got so few feedback. That is not the personal disappointment
that comes simply for the reason that one wants to share a project and
cannot as it does not interest others, that is a risk to take of
course .
It surprised me though that Rubiests that I learnt to like and
respect, like e.g. you Dave, still use the terms "types" and "classes"
as
if they were not in contradiction to what they are saying about duck
typing afterwards.
s /^/So sorry, why does this always happen to me?/s/Dave/David/
Sorry, I'm not sure which contradiction you're talking about. Can you
clarify?
I'm going to have to respectfully disagree here.
Unless you are going to have branching based on type -- that is,
simple method
overloading (as in C++ and friends) -- I don't see as much point to
a rigid
type system.
It boils down to: Why should I care whether I'm being passed a
number or
something which merely behaves like a number? Why should I care if
I'm being
passed a string or an array of characters?
Now, for the simple case of a Numeric, we're probably over-analyzing
it.
But I'm finding these remarks about "attititude" kind of amusing.
It's
like Ruby isn't a tool, it's a "mindset." We don't forgo something
like Numeric === v because it's _wrong_ (the OP in fact said it was
slightly more readable), but because Ruby has duck-typing,
Well, there is some truth to that -- as an example, Ruby completely
lacks
anything resembling the C for loop. If that's what you're expecting,
you have
to build it out of a while loop:
i=0
while i < data.length
do_something_with data
i += 1
end
There's nothing wrong with that. But I hope most of us forgo it in
favor of:
data.each { |datum|
do_something_with datum
}
Which ends up being more readable, among other things.
But if you do that, I don't understand why you're using Ruby. Again,
nothing
wrong with it -- do whatever makes you happy, and maybe you're right
and I'm
wrong. But I doubt I'll ever understand it.
Can you outline a few real-world examples, where it's OK to get a
descendant
of Numeric, but not something which merely implements to_i or to_f?
Not really.
Firstly, #class doesn't provide any way to be in multiple
categories. Ruby
doesn't support multiple inheritance.
Duck typing, as a way of thinking, meshes nicely with Ruby, as a tool,
because of how Ruby objects are engineered: the *only* thing that you
can measure with certainty is what an object does when you send it a
message.
You can ask it what its class is, what its ancestors are,
what methods it responds to, and so forth... but in the end, you hit
the singularity: the sending of the message.
it stands
to reason that a language with objects whose types can change during
runtime would be well-served by a programming style that deals as
directly and economically as possible with precisely that condition.
Le 29 mai =E0 06:45, Eleanor McHugh a =E9crit :
There are more ducks in heaven and earth, Horatio, than are
dreamt of in your philosophy.
=> 123
These are simply the attributes of a type: a set of possible valuesOne of the weaknesses of classic Booch, et al OOP is that one of the
purposes of classes in OOP is to categorize things.
Classes in classic OOP languages conflate a variety of concepts and
cram them into one structure which does none of them particularly
well:
Classes are the unit of state.
Classes are the unit of access control.
Classes are the unit of functional dispatch.
it stands
to reason that a language with objects whose types can change during
runtime would be well-served by a programming style that deals as
directly and economically as possible with precisely that condition.
If classes are not categories, what are they?
For a very good reason, because it is Numeric === v.I've done a lot of C++, and I remember when RTTI (runtime type information)
was introduced. I was pretty strongly against its use, believing that
polymorphism through virtual functions was the way to "branch" on type. I
would have strongly avoided code like v === Numeric.
I boldly (my turn now state that there is no type in Ruby, but IAs I would avoid it today, in Ruby. We're actually talking about something
that I think should be rare, which is branching on type.
I would not like to ban early failure checks like that totally. AgainWe're only doing it
to validate parameters. In good Ruby, we would not do this, relying on the
runtime to tell us when we're using the wrong type. To me, duck typing
doesn't mean "ask me if I quack" as much as "quack, you!".
Right indeed, this was forgotten OP even stated so, good point.So I think this
whole discussion is about an edge case.
Yes, I don't think I would have made the same case for a less basic class.
It is even plain wrong, it specifically ask if behavior carrying aHowever, I still think using responds_to? to identify an object's type is
risky.
It really feels wrong because indeed each tool creates its ownAs I said, it relies upon a much larger namespace than class
constants, hence much more chance for accidental positives (e.g., #draw
meaning different things to different objects).
Strangely enough I see it the other way round:Exactly. It has absolutely nothing to do with Ruby's "mindset," or "the way
we do things in Ruby." We choose the latter because it's better, not because
it's the Ruby way.
It's the other way around: it's the Ruby way because it's
better; not that it's better because it's the Ruby way. The former attitude
is pragmatic, the latter is religious.
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.