On Thu, 2004-10-14 at 05:29, Robert Klemme wrote:
> In those cases I prefer to switch to a type mapping based approach (although
> that has it's drawbacks in the light of singleton methods) like I
> demonstrated in another posting (basically, create a HashMap with classes
> as keys and lambdas as values).
> > If I want to write a polymorphic routine, but am not supposed to
> > test the class (since it provides no guarantee of behavour) or the
> > method signature, am not allowed to extend the core classes or sub class
> > them, how pray tell is it to be done?
>
> See above for an example. However, it's difficult to discuss this without
> a concrete example.
My main objection to this is that it is very brittle in the face of
sub-classing; if someone, for whatever reason, passes in a sub-class of
a class I am expecting (even if it is functionally identical) it will be
mishandled; the Hash of lambdas will return the default value, not the
value for the (identical) parent class.
> Hm... I prefer a simpler solution. After all, what would you do it you
> had libA and libB which both add method String#foo and which both are able
> to detect the name clash and report it? You'll most likely get an
> exception and can't use libA and libB together. Of course, those libs
> could be written to automatically choose appropriate names, possibly even
> with dynamic generated prefix. But this likely becomes unmanageable fast.
My solution (*smile* involving extending Symbol) doesn't get
unmanageable at all, so far as I've seen, uses:
class Symbol
@@unique_sym_counter = 0
def Symbol.unique(prefix="gloop")
prefix = prefix.to_s.
gsub(/\+/,'_plus_').
gsub(/\*/,'_times_').
gsub(/-/,'_minus_').
gsub(/\//,'_div_').
gsub(/\!/,'_bang_')
("#{prefix.to_s}__#{@@unique_sym_counter += 1}").intern
end
end
which is in part an example of:
> > All of these precautions can be neatly encapsulated themselves, so
> > you don't even need to mess with them while you're working on your code.
> >
> > It really does seem to me that this is a "rule" rooted more in the
> > limitations of other languages than abstract software design principles
> > and not a good match for ruby.
>
> I don't think so. Name clashes and building proper components with clean
> and consistent interfaces (i.e. interfaces that can be used by humans who
> have to understand them) are not restricted to particular programming
> languages and I think in fact are quite fundamental to software
> engineering.
With ruby you can have clean human visible interfaces which (at run
time) instantiate as name-clash free computer usable interfaces for a
small, one-time cost (defs become slightly slower).
> > There are too many good ways to deal
> > with the potential problems to write the whole technique off with an
> > "almost never" prohibition.
>
> As you might have guessed, I don't regard the ways to cope with name
> clashes of auxiliary methods in std classes as good as you do. :-) But
> that's a personal judgement and we're all free to differ here.
>
> > For my part, I am not saying it is _always_ bad to extend standard
> > classes, but (if done judiciously) it can be a very useful technique,
>
> I couldn't agree more. (Ooops, something wrong here? :-))
*laugh* Not at all. The main value of a thread like this is we
get to learn from each other, including learning how to understand how
the other thinks. Occasional agreement is just one of the many risks we
face.
> > and is no more dangerous than any other language feature of similar
> > power and generality.
>
> I leave that judgement for another thread. :-)
>
> Thanks for taking the time to go through all this! I'm sorry that I'm so
> stubborn about things that I'm convinced of.
No, thank you. Almost every valuable thing I know came from either
watching or listening to someone who was stubborn about things they
believe in. All in all, they came much cheaper than the small fraction
I acquired through (often painfully) personally discovering what didn't
work, and why.
-- Markus