I think there are two conflated issues here. First open classes and
their abuse and second dynamic method creation. I think they distinct
enough they should be considered separately.
I agree. But these issues and a few others (e.g. types, inheritance, encapsulation, modules, namespaces) are often combined, or conflated, deliberately, into a single solution -- the Class. For an absolutely excellent explanation of the reasoning see Bertrand Meyer's <http://en.wikipedia.org/wiki/Bertrand_Meyer> Object Oriented Software Construction 2nd Edition where he lays out Eiffel (which you really have to try seriously before you dismiss it). For an absolutely excellent experience of what happens when you relax some of this give CLOS -- or Ruby -- a try.
Considering open classes, I find many of the conventions used in
Rails, once they are understood, simplify the resulting code. Given
this, it is worth pointing out that Rails is fairly unique in Ruby
development being a mainstream library that does modify base classes.
Additionally very few of the enhancements to the base classes are
"non-obvious" even a non-programmer will recognize the purpose of
item.pluralize. It is arguable and I would not disagree that this is
still thin ice. Using different Ruby libraries may cause issues—it
would be good if such changes could be better scoped. Still in
practice I have encountered none of the sort of problems I have would
expected. And unit tests are still the best medicine
Xampl also modifies existing classes. It will, optionally, write a file that shows you exactly what it did, but the changes are very uniform and predictable. From what I've seen of Rails the changes it makes are also uniform and predictable (I don't know if it will write a file). Furthermore, it looks as though the demands of Rails and xampl are independent. I've found that the biggest problem comes from putting requirements on the inheritance structure of extended objects. Ruby lets you side-step that problem very neatly (Java does not -- it is horribly complex what you have to do).
Unit tests are necessary I think. But they are not sufficient. Back in the Old Days when we worked in assembler, there was this horrid practice of 'patching' that worked by loading the original code then over-writing parts, maybe just a few bytes, of that with new code that fixed problems. This was a nightmare. Assembler is bad enough, patches are over top. Now, in Ruby, what if some clever 'programmer' decides to fix a problem by replacing a method without removing the original from the source? Though this is better than the assembler situation it is still outrageous... well, at least I'd be outraged not to mention enraged And unit tests won't detect this behaviour.
Never-the-less, I *like* open classes. They are very powerful, very useful.
The second issue of dynamic method generation (which I think was the
meat of the above quote) seems more like a documentation issue than
anything else. Consider a different framework that used a data file to
code generate a large number of access methods into a database,
similar to the functionality which is dynamically generated within
ActiveRecord—would this be the monkey patching that is so troubling?
Similarly, while it can take some acclimation, who cannot understand
code like:
item_list = Item.find_all_upc(upc)
Yes, you would look long and hard to find this particular method in
the API, but once the convention is understood (as it should be by
anyone who has developed in Rails for more than a day or two) it is
very intuitive.
A little more than just a documentation issue I think, but certainly related. What if a soon-to-be-unemployed 'programmer' built up a string in memory, maybe computing the name somehow, then evaled it? The fact that the original method is also generated, and that you know that because Rails is consistent, will only make it harder to even recognise what is happening.
(I still like this capability, don't forget, just pointing out a stupid thing to do)
In the end, I think it is a matter of trust. Any programming language
worth using, can be used poorly. Ruby and Python are no exception in
this regard. Writing good code which by definition is maintainable
code by both first and second generation coders is difficult. Rails
uses much of the power of the Ruby language to map the code to the
problem domain (database driven web applications).
I agree. But a lot of people think programmers need safety shields.
As always the devil is in the details. I would be very curious which
aspects of Ruby/Rails development in particular anyone thinks will be
a long term maintenance issue.
Not the code generation part I think, in fact, it might turn out to be a major boon to maintenance (fix it in one place kind of thing). I'd be more concerned with having to re-factor a controller and breaking a bunch of URLs (but I don't know Rails well enough to know if this is actually a possible issue).
Cheers,
Bob
···
On Dec 22, 2005, at 5:30 PM, Patrick Hurley wrote:
pth
----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>
Raconteur -- <http://www.raconteur.info/>