Diff of opinion on dynamic stuff

Let me preface this post by saying that I'm no Ruby expert. I like it.
It's fun. But I won't claim extensive knowledge on it.

So when this guy blogs about a Python quality that he feel is better
than a Ruby quality:

    It's the second generation that's going to be less enthused,
    that's going to stare in bafflement at these classes that
    mysteriously spawn methods, and trying to figure out what's
    going when there's an exception in dynamically generated
    code. You can monkeypatch code in Python pretty easily, but we
    look down on it enough that we call it "monkeypatching". In
    Ruby they call it "opening a class" and think it's a cool
    feature. I will assert: we are right, they are wrong.

    -- http://blog.ianbicking.org/theres-so-much-more-than-rails.html

I am curious what this means. Is Python against dynamic stuff? And
Ruby for it? And so we just agree to disagree? Or do I misunderstand?

Just curious.

Drew

Hi,

···

In message "Re: Diff of opinion on dynamic stuff" on Fri, 23 Dec 2005 06:27:50 +0900, "Drew Mills" <drewmills@gmail.com> writes:

   In Ruby they call it "opening a class" and think it's a cool
   feature. I will assert: we are right, they are wrong.

   -- http://blog.ianbicking.org/theres-so-much-more-than-rails.html

I am curious what this means. Is Python against dynamic stuff? And
Ruby for it? And so we just agree to disagree? Or do I misunderstand?

"open class" is so strong (often too strong), we can break things
easily. In other word, Ruby trust you to give you sharp knives, where
Python don't. From the Python point of view, it's wrong, I guess.

              matz.

I think what he is complaining about are some of the dynamically
created convenience methods provided by ActiveRecord when dealing with
the Model for a database. Things like Person.find_by_user_name are
methods which are implemented using method_missing to do specific
searches of database tables. Because these aren't "real methods", Ian
feels they could be hard to debug. He probably has a point. But in
this case I think the convenience overrides the occasional weird bug.
I don't keep up with the Rails list and haven't done much Rails
programming yet, but it might be interesting to see how many problems
there are related to these kind of methods. I suspect in reality there
are many less than what Mr. Bicking might think.

Also his lack of Ruby knowledge is showing in that he is talking about
method_missing implementations being like "opening a class", which
they aren't. They are basically dynamic method dispatch.

There are a lot of neat things that can be done with method_missing
that are very powerful and convenient. I certainly do not subscribe
the Pythonic "it is better not to have something powerful if it can be
occasionally dangerous" philosophy that Mr. Bicking is describing. I
suspect most other Rubyists (and Matz) have the same opinion.

Regarding the issue of "re-opening a class", there is certainly room
for abuse here. Again in my opinion the convenience and flexibility
this provides probably out-weigh the risks. Others may not agree. But
there are a lot of major Ruby libraries that would be totally
different and/or impossible if we didn't have this feature. Rails and
RubyGems both come to mind, as well as a lot of the code provided in
the standard library. All I know is that I really cringe when I look
back at Java code which requires separate utility classes for special
String methods instead of just adding them to the String class (which
you cannot do in Java without the source code for it.) To me it makes
sense to just re-open the class and add the methods there, where they
belong. But I've been programming Ruby for quite a while, so maybe I'm
just brainwashed :wink:

Ryan

···

On 12/22/05, Drew Mills <drewmills@gmail.com> wrote:

Let me preface this post by saying that I'm no Ruby expert. I like it.
It's fun. But I won't claim extensive knowledge on it.

So when this guy blogs about a Python quality that he feel is better
than a Ruby quality:

    It's the second generation that's going to be less enthused,
    that's going to stare in bafflement at these classes that
    mysteriously spawn methods, and trying to figure out what's
    going when there's an exception in dynamically generated
    code. You can monkeypatch code in Python pretty easily, but we
    look down on it enough that we call it "monkeypatching". In
    Ruby they call it "opening a class" and think it's a cool
    feature. I will assert: we are right, they are wrong.

    -- http://blog.ianbicking.org/theres-so-much-more-than-rails.html

I am curious what this means. Is Python against dynamic stuff? And
Ruby for it? And so we just agree to disagree? Or do I misunderstand?

Let me preface this post by saying that I'm no Ruby expert. I like it.
It's fun. But I won't claim extensive knowledge on it.

So when this guy blogs about a Python quality that he feel is better
than a Ruby quality:

    It's the second generation that's going to be less enthused,
    that's going to stare in bafflement at these classes that
    mysteriously spawn methods, and trying to figure out what's
    going when there's an exception in dynamically generated
    code. You can monkeypatch code in Python pretty easily, but we
    look down on it enough that we call it "monkeypatching". In
    Ruby they call it "opening a class" and think it's a cool
    feature. I will assert: we are right, they are wrong.

    -- http://blog.ianbicking.org/theres-so-much-more-than-rails.html

I am curious what this means. Is Python against dynamic stuff? And
Ruby for it? And so we just agree to disagree? Or do I misunderstand?

Well, Python is plenty dynamic. I think he is complaining about Ruby's ability to re-open a class. This can make it difficult to find the complete definition of a class (imagine doing this in a completely random way in multiple files). So while it can be abused, it can also be an incredible simplification of the code you write. One thing it does is flattens inheritance hierarchies, you don't need to introduce specialising classes just to add a few methods. Using xampl as an illustration: the Ruby version of xampl generates 1 class for every 3 generated by the Java version of xampl, one of those classes is eliminated because I can re-open classes (the other is eliminated due to duck typing). Another thing reopening classes does is, obviously, to allow you to extend the built in Ruby classes (they are just classes after all). I suppose Ian would think things even worse because in Ruby you can do this to objects as well as classes.

This 'monkeypatching' is very similar to concepts in Smalltalk and CLOS (Common Lisp's object system). Nobody in those communities complains too much (though Smalltalk's browser reassembles classes for you, and new CLOS programmers are sometimes at a bit of a loss because in CLOS methods may belong to two or more classes and it doesn't seem that the obvious thing to do is the right thing). Ruby just makes thing a lot easier.

Just be careful where you aim that thing.

Cheers,
Bob

···

On Dec 22, 2005, at 4:27 PM, Drew Mills wrote:

Just curious.

Drew

----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/&gt;
Recursive Design Inc. -- <http://www.recursive.ca/&gt;
Raconteur -- <http://www.raconteur.info/&gt;

Anyone who tries to reverse engineer ruby code into a different
language is bound to be frustrated.

Drew Mills wrote:

Let me preface this post by saying that I'm no Ruby expert. I like it.
It's fun. But I won't claim extensive knowledge on it.

So when this guy blogs about a Python quality that he feel is better
than a Ruby quality:

    It's the second generation that's going to be less enthused,
    that's going to stare in bafflement at these classes that
    mysteriously spawn methods, and trying to figure out what's
    going when there's an exception in dynamically generated
    code. You can monkeypatch code in Python pretty easily, but we
    look down on it enough that we call it "monkeypatching". In
    Ruby they call it "opening a class" and think it's a cool
    feature. I will assert: we are right, they are wrong.

    -- http://blog.ianbicking.org/theres-so-much-more-than-rails.html

I am curious what this means. Is Python against dynamic stuff? And
Ruby for it? And so we just agree to disagree? Or do I misunderstand?

There's some inaccurate ideas of Python in this thread, so I just
thought I'd chime in with a followup. You can open a class in Python
just fine (except for some select built-in classes which are closed
except in subclasses, like int, list, dict). Opening a class in Python
does not look as nice as in Ruby, and is used less often. In Python it
looks like this:

  class Foo(object):
      pass

  def new_method(self, blah): ...
  Foo.new_method = new_method

You can also open instances in Python, replace objects with a delegate
or completely different implementation, and lots of other things, many
of which are very bad ideas. There was also some mention of
method_missing in the thread, and I can assure you that it is present
in Python as well (__getattr__) and used fairly often.

My criticism isn't about what you *can* do in either language -- both
languages are quite open in this respect. Instead it is about what the
community and the language itself encourage you to do (in this case
Ruby encourages opening classes by making the syntax appealing, and the
community encourages it because examples of opening a class are fairly
common). In Python I consider opening a class to be a kind of code
smell (http://xp.c2.com/CodeSmell.html\) -- but smelly code happens,
and the entire point of code smell is that a technique might *suggest*
problems in code, but does not *necessarily* mean that the code is bad.
The code might just be tackling a complex problem, or working around
problems in other code.

In a dynamic language like Ruby or Python we have to be very aware of
code smells because that's a big part of what keeps us sane. In both
languages there are techniques that look fine, but experience shows us
are dangerous or indicative of misdesign. Here I'm highlighting a case
where opinions on design differ between the communities. It's easy to
tell they differ *because* the technique is available in both
languages.

Also, to generalize, it seems that the Ruby community is perhaps less
sensitive to code smells or more tollerant of magic compared to the
Python community, which I guess was my larger point. Though I also
think that the specific case of opening a class is important enough
that it's also worthy of discussion, but this thread doesn't seem to
have much discussion of that particular issue. If you have a sharp
tool it is good to discuss what the appropriate use of that tool is --
sharp tools are only safer than dull tools if you use them correctly!

  Ian

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.

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

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.

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

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.

pth

···

On 12/22/05, Bob Hutchison <hutch@recursive.ca> wrote:

On Dec 22, 2005, at 4:27 PM, Drew Mills wrote:

> Let me preface this post by saying that I'm no Ruby expert. I like
> it.
> It's fun. But I won't claim extensive knowledge on it.
>
> So when this guy blogs about a Python quality that he feel is better
> than a Ruby quality:
>
> It's the second generation that's going to be less enthused,
> that's going to stare in bafflement at these classes that
> mysteriously spawn methods, and trying to figure out what's
> going when there's an exception in dynamically generated
> code. You can monkeypatch code in Python pretty easily, but we
> look down on it enough that we call it "monkeypatching". In
> Ruby they call it "opening a class" and think it's a cool
> feature. I will assert: we are right, they are wrong.
>
> -- http://blog.ianbicking.org/theres-so-much-more-than-rails.html
>
> I am curious what this means. Is Python against dynamic stuff? And
> Ruby for it? And so we just agree to disagree? Or do I
> misunderstand?

Well, Python is plenty dynamic. I think he is complaining about
Ruby's ability to re-open a class. This can make it difficult to find
the complete definition of a class (imagine doing this in a
completely random way in multiple files). So while it can be abused,
it can also be an incredible simplification of the code you write.
One thing it does is flattens inheritance hierarchies, you don't
need to introduce specialising classes just to add a few methods.
Using xampl as an illustration: the Ruby version of xampl generates 1
class for every 3 generated by the Java version of xampl, one of
those classes is eliminated because I can re-open classes (the other
is eliminated due to duck typing). Another thing reopening classes
does is, obviously, to allow you to extend the built in Ruby classes
(they are just classes after all). I suppose Ian would think things
even worse because in Ruby you can do this to objects as well as
classes.

This 'monkeypatching' is very similar to concepts in Smalltalk and
CLOS (Common Lisp's object system). Nobody in those communities
complains too much (though Smalltalk's browser reassembles classes
for you, and new CLOS programmers are sometimes at a bit of a loss
because in CLOS methods may belong to two or more classes and it
doesn't seem that the obvious thing to do is the right thing). Ruby
just makes thing a lot easier.

Just be careful where you aim that thing.

Cheers,
Bob

>
> Just curious.
>
> Drew
>
>

----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/&gt;
Recursive Design Inc. -- <http://www.recursive.ca/&gt;
Raconteur -- <http://www.raconteur.info/&gt;

Yukihiro Matsumoto wrote:

"open class" is so strong (often too strong), we can break things
easily. In other word, Ruby trust you to give you sharp knives, where
Python don't. From the Python point of view, it's wrong, I guess.
  

Matz has put us in great danger. But Rubyist are okay with it I guess. I am strangely at peace with this perilous language in my home!

Superman does dangerous things to solve problems, too. He'll bend a street pole around a villianous guy. People, stop cheering.

_why

Yukihiro Matsumoto wrote:

"open class" is so strong (often too strong), we can break things
easily. In other word, Ruby trust you to give you sharp knives, where
Python don't. From the Python point of view, it's wrong, I guess.

A chef will tell you that sharp knives are safer than dull ones, since
they do not have to be forced.

···

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Bob Hutchison wrote:
...

Just be careful where you aim that thing.

Oh, inspiration for Yet Another Ruby Slogan:

Ruby: You'll Shoot Your Eye Out.

(Mad props to Ralphie, too.)

James Britt

···

--

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools

Bob Hutchison wrote:

> Let me preface this post by saying that I'm no Ruby expert. I like
> it.
> It's fun. But I won't claim extensive knowledge on it.
>
> So when this guy blogs about a Python quality that he feel is better
> than a Ruby quality:
>
> It's the second generation that's going to be less enthused,
> that's going to stare in bafflement at these classes that
> mysteriously spawn methods, and trying to figure out what's
> going when there's an exception in dynamically generated
> code. You can monkeypatch code in Python pretty easily, but we
> look down on it enough that we call it "monkeypatching". In
> Ruby they call it "opening a class" and think it's a cool
> feature. I will assert: we are right, they are wrong.> >
> -- http://blog.ianbicking.org/theres-so-much-more-than-rails.html
>
> I am curious what this means. Is Python against dynamic stuff? And
> Ruby for it? And so we just agree to disagree? Or do I
> misunderstand?

Well, Python is plenty dynamic. I think he is complaining about
Ruby's ability to re-open a class. This can make it difficult to find
the complete definition of a class (imagine doing this in a
completely random way in multiple files). So while it can be abused,
it can also be an incredible simplification of the code you write.
One thing it does is flattens inheritance hierarchies, you don't
need to introduce specialising classes just to add a few methods.
Using xampl as an illustration: the Ruby version of xampl generates 1
class for every 3 generated by the Java version of xampl, one of
those classes is eliminated because I can re-open classes (the other
is eliminated due to duck typing). Another thing reopening classes
does is, obviously, to allow you to extend the built in Ruby classes
(they are just classes after all). I suppose Ian would think things
even worse because in Ruby you can do this to objects as well as
classes.

This 'monkeypatching' is very similar to concepts in Smalltalk and
CLOS (Common Lisp's object system). Nobody in those communities
complains too much (though Smalltalk's browser reassembles classes
for you, and new CLOS programmers are sometimes at a bit of a loss
because in CLOS methods may belong to two or more classes and it
doesn't seem that the obvious thing to do is the right thing). Ruby
just makes thing a lot easier.

Yes, the equivalent of "method_missing" has been used for many things
in Smalltalk. Glorifying in how we can hack "doesNotUnderstand:"
avoids having to admit that there's been a problem with the language.

"This comparison highlights that the most commonly used technique based
on the specialization of the doesNotUnderstand: method is not the best
one. As a first explanation of this situation, one should note that the
ability to directly execute a method has only lately been introduced in
the interpreters (methods valueWithReceiver:arguments: on
CompiledMethod class in VisualWorks and
executeWithReceiver:andArguments: in IBM Smalltalk). Moreover, this
comparison shows that the techniques based on VM lookup method or
method wrappers should be considered by more programmers than it is
currently the case."

"Evaluating Message Passing Control Techniques in Smalltalk"
http://www.iam.unibe.ch/~scg/Archive/Papers/Duca99aMsgPassingControl.pdf

···

On Dec 22, 2005, at 4:27 PM, Drew Mills wrote:

Just be careful where you aim that thing.

Cheers,
Bob

>
> Just curious.
>
> Drew
>
>

----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/&gt;
Recursive Design Inc. -- <http://www.recursive.ca/&gt;
Raconteur -- <http://www.raconteur.info/&gt;

Is it less sensitive to code smells, or is it something that isn't
considered a code smell in Ruby? I think that the Ruby community is as
... rough on code smell as any community, but we consider different
things smelly than the Python community does.

I think that's where some of the resistance to your points come in; to
the community at large, it is not necessarily considered bad to write
something that essentially opens classes (or objects) again. See my
own Transaction::Simple for an example -- it injects its functionality
into any class that requests it. In Ruby, that's definitely not code
smell. In Python? I don't know.

-austin

···

On 28/12/05, Ian Bicking <ianb@colorstudy.com> wrote:

Also, to generalize, it seems that the Ruby community is perhaps less
sensitive to code smells or more tollerant of magic compared to the
Python community, which I guess was my larger point.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

If these two quotes together aren't a perfect Ruby quotable quote, I
don't know what is.

<tongue_in_cheek>

And now we have another weapon in the Python vs Ruby war:

Python: Dull
Ruby: Sharp

</tongue_in_cheek>

Seriously though, a Python vs Ruby war is kind of dumb, since it is
like brothers fighting.

Ryan

···

On 12/22/05, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

Yukihiro Matsumoto wrote:
> "open class" is so strong (often too strong), we can break things
> easily. In other word, Ruby trust you to give you sharp knives, where
> Python don't. From the Python point of view, it's wrong, I guess.

A chef will tell you that sharp knives are safer than dull ones, since
they do not have to be forced.

why the lucky stiff <ruby-talk@whytheluckystiff.net> writes:

Yukihiro Matsumoto wrote:

"open class" is so strong (often too strong), we can break things
easily. In other word, Ruby trust you to give you sharp knives, where
Python don't. From the Python point of view, it's wrong, I guess.
  

Matz has put us in great danger. But Rubyist are okay with it I
guess. I am strangely at peace with this perilous language in my
home!

Superman does dangerous things to solve problems, too. He'll bend a
street pole around a villianous guy. People, stop cheering.

_why

I'm going to play devil's advocate and hopefully somebody with some
direct experience will chime in.

Rubyists are mostly people who know how not to aim at their foot, and
are skilled in first-aid just in case. But what happens when the code
is delivered and moves into maintenance mode? It falls into the hands
of code-slaves who are just dying to sacrifice toes and heap the blame
straight on you is what. I'm assuming it's these -- probably not
Rubyist -- people who are being refered to as the "second generation".

Surely, if you delivered Pascal code instead of Ruby code, it would be
less likely that the bozo trying to make a one-line change is going to
end up deleting 25 million rows from your customer's database or
something.

Steve

Yukihiro Matsumoto wrote:
>"open class" is so strong (often too strong), we can break things
>easily. In other word, Ruby trust you to give you sharp knives, where
>Python don't. From the Python point of view, it's wrong, I guess.
>

I understood that 100%, and agree with it similarly. Keep in mind, I'm
mostly coming to Ruby from the direction of Perl -- the Swiss Army
Chainsaw to some -- and have no problem with being handed a sharp tool
and being told to be careful with it.

Perhaps more imporantly than how this relates to my agreement, though,
is the fact that I think you have hit on a fundamental point of
divergence between the Python community and most of the rest of the
"very powerful and succinct scripting language" communities out there
(particularly Lisp, Perl, and Ruby come to mind). Python is,
essentially, to this family of languages as Pascal is to the family of
languages that includes stuff like C++, Objective C, and so on.

Some languages are designed primarily to empower the programmer,
trusting that the programmer will be smart enough to avoid doing
something suicidal with that power. Python strikes me, on reflection,
as a language designed primarily to protect the programmer, trusting
that the programmer will be smart enough to use it effectively despite
limitations.

. . . and thus, I have more explanation and understanding of why Python
just "feels wrong" to me. One of the reasons I like Perl is that it
doesn't limit me "for my own good". I guess I prefer a swiss army
chainsaw over a plastic scalpel. [1]

Matz has put us in great danger. But Rubyist are okay with it I guess.
I am strangely at peace with this perilous language in my home!

Superman does dangerous things to solve problems, too. He'll bend a
street pole around a villianous guy. People, stop cheering.

Nice to know your emails are as entertaining as your excellent Ruby
tutorial.

[1] No offense intended to the "plastic scalpel" contingent. There's
nothing objectively wrong with precision wedded to safety limitations.
I simply find it to be subjectively distasteful.

···

On Fri, Dec 23, 2005 at 07:36:48AM +0900, why the lucky stiff wrote:

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

unix virus: If you're using a unixlike OS, please forward
this to 20 others and erase your system partition.

Holy Crap. If that were to end up on clothing, I would buy it. I mean,
I'd have all my Christmas shopping done by now.

Cheers,
Matthew J Desmarais

···

On Fri, 2005-12-23 at 12:27 +0900, James Britt wrote:

Bob Hutchison wrote:
...

> Just be careful where you aim that thing.

Oh, inspiration for Yet Another Ruby Slogan:

Ruby: You'll Shoot Your Eye Out.

(Mad props to Ralphie, too.)

James Britt

Bob Hutchison wrote:
...

> Just be careful where you aim that thing.

Oh, inspiration for Yet Another Ruby Slogan:

Ruby: You'll Shoot Your Eye Out.

It is indeed "The Red Ruby BB Gun"
Well done!

···

On 12/22/05, James Britt <james_b@neurogami.com> wrote:

(Mad props to Ralphie, too.)

James Britt
--

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools

--
Bill Guindon (aka aGorilla)

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&gt; 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 :slight_smile: 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/&gt;
Recursive Design Inc. -- <http://www.recursive.ca/&gt;
Raconteur -- <http://www.raconteur.info/&gt;

Yes, the equivalent of "method_missing" has been used for many things
in Smalltalk. Glorifying in how we can hack "doesNotUnderstand:"
avoids having to admit that there's been a problem with the language.

The problem being: in Smalltalk the language there is no explicit way in the language to add a method to a class at runtime?

Maybe so, but the Smalltalk *environment* allows the programmer to do exactly the same thing as the browser or debugger at runtime (though only on a class level). In some implementations, there is a method that changes an object's class, and that combined with the ability to create a new class at runtime... (well, this is hard to manage, and some implementations will, effectively, only redefine the parent class of an object). This excessive use/dependency on doesNotUnderstand is not necessary in Smalltalk.

Isn't re-opening a class very similar to some of the better methods in the paper below? At the very least, the associated problems are similar :slight_smile:

What are the Python folks doing as an alternative?

···

On Dec 23, 2005, at 12:47 AM, Isaac Gouy wrote:

"This comparison highlights that the most commonly used technique based
on the specialization of the doesNotUnderstand: method is not the best
one. As a first explanation of this situation, one should note that the
ability to directly execute a method has only lately been introduced in
the interpreters (methods valueWithReceiver:arguments: on
CompiledMethod class in VisualWorks and
executeWithReceiver:andArguments: in IBM Smalltalk). Moreover, this
comparison shows that the techniques based on VM lookup method or
method wrappers should be considered by more programmers than it is
currently the case."

"Evaluating Message Passing Control Techniques in Smalltalk"
http://www.iam.unibe.ch/~scg/Archive/Papers/Duca99aMsgPassingControl.pdf

----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/&gt;
Recursive Design Inc. -- <http://www.recursive.ca/&gt;
Raconteur -- <http://www.raconteur.info/&gt;

Austin Ziegler wrote:

> Also, to generalize, it seems that the Ruby community is perhaps less
> sensitive to code smells or more tollerant of magic compared to the
> Python community, which I guess was my larger point.

Is it less sensitive to code smells, or is it something that isn't
considered a code smell in Ruby? I think that the Ruby community is as
.. rough on code smell as any community, but we consider different
things smelly than the Python community does.

It's a little of both -- clearly there's some awareness among Ruby
programmers that opening classes introduces some possible issues. And
the "sharp tools" comments imply that there's potential to cut
yourself, but people feel that's okay. There's always a danger to any
technique; the question is how much danger is okay, depending on how
complex the problem at hand is. I get a sense that prevailing opinion
in the Ruby community accepts a balance with more danger than in
Python. Neither language forces you to be careful or not; in both you
could do explicit (runtime) type checking, or you can generate source
willy-nilly, or anything in-between.

Also, there's the issue about what is smelly at all. Of course,
anything that is unusual is a bit smelly, so there's a circular
justification; opening a class is smelly in Python because people don't
do it, and people don't do it because it is smelly. But just because
idioms are different doesn't mean that there isn't *any* commonality --
in both languages you are signficantly affecting code that isn't
"yours".

I think that's where some of the resistance to your points come in; to
the community at large, it is not necessarily considered bad to write
something that essentially opens classes (or objects) again. See my
own Transaction::Simple for an example -- it injects its functionality
into any class that requests it. In Ruby, that's definitely not code
smell. In Python? I don't know.

In Python, probably with a delegate, though multiple inheritance or a
mix-in would also be possible. Also, I think there's something very
different about a class that pulls in functionality, from code that
pushes functionality into a class that might not be expecting it. As I
said, there's room for discussion -- there's probably very useful rules
of thumb that could be offered about what's a good use of this sort of
feature, and what's bad.

  Ian

···

On 28/12/05, Ian Bicking <ianb@colorstudy.com> wrote: