Hacker News new | ask | show | jobs
by riffraff 4960 days ago
Camelizable.new(my_string).camelize does not support polymorphism, because it does not depend on the type of my_string.

Which means if I want to add camelizable to my AnnotatedString I have to monkey patch Camelizable#initialize.

1 comments

No, it means that the implementation of Camelizable#camelize needs to be polymorphic w.r.t. my_string. Since Ruby is duck-typed, presumably the implementation of "camelize" would first check to see if the receiver responded to "gsub", then do the necessary substitutions. (Actually, a better implementation would be to first check if my_string responds to "camelize" and call that directly if it does.) In the end, this is a classic decorator pattern.
if you go the way of a decorator pattern, say, I write my `IntegerCamelDecorator` since your `Camelizable.new` does not support numbers, then what is the point of `Camelizable` to start with? You can just have a mirror hierarchy of `CamelAdapters`.

Of course, you can implement `Camelizable.new` so that it performs a dynamic dispatch itself, by looking up in a `CamelizableRegistry`. You can even have this built up magically with reflection.

You can, of course do everything, but a method call in ruby still only dispatches on self, and if that is fixed the method cannot be polymorphic, if you think otherwise we can agree to disagree.

You're focusing on the #new call. The actual #camelize call is still dispatching based on the Camelizable object which is parameterized with my_string. Ok, so it's not true call-site polymorphism...fine. I'd argue that's an unimportant implementation detail, but if you prefer (and what I frequently do in my own code) you could have something more like:

    Camelizable(my_string).camelize
where now Camelizable does the dynamic class lookup to choose the correct decorator for my_string. This turns #camelize into a truly call-site polymorphic call and, at least in my opinion, is far more readable/reasonable than either monkeypatching or refinements.