Diff of opinion on dynamic stuff


#1

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


#2

Hi,

In message “Re: Diff of opinion on dynamic stuff”
on Fri, 23 Dec 2005 06:27:50 +0900, “Drew M.”
removed_email_address@domain.invalid 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.

#3

On 12/22/05, Drew M. removed_email_address@domain.invalid wrote:

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?

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


#4

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

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 H. – blogs at http://www.recursive.ca/hutch/
Recursive Design Inc. – http://www.recursive.ca/
Raconteur – http://www.raconteur.info/


#5

On 12/22/05, Bob H. removed_email_address@domain.invalid wrote:

It's the second generation that's going to be less enthused,

I am curious what this means. Is Python against dynamic stuff? And
Using xampl as an illustration: the Ruby version of xampl generates 1
complains too much (though Smalltalk’s browser reassembles classes

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


#6

Yukihiro M. 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


#7

Yukihiro M. 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.


#8

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


#9

On 12/22/05, Joel VanderWerf removed_email_address@domain.invalid wrote:

Yukihiro M. 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.

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


#10

why the lucky stiff removed_email_address@domain.invalid writes:

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


#11

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

Yukihiro M. 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.


Chad P. [ 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.


#12

On Fri, Dec 23, 2005 at 08:53:18AM +0900, Steven L. wrote:

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

I think you’re probably right, and it’s a valid concern. I just don’t
think it’s a valid reason for eschewing Ruby.

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.

That’s really only because while it might take a ten-line change to do
the same thing in Pascal, that one line in Ruby has the functionality of
about twenty lines of Pascal code. There are things I like about
Pascal, but this isn’t one of them.

By the way . . .
I have, in the past, found myself thinking Python might be the Pascal of
scripting languages, and you got me thinking about that again.

Chad P. [ 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.


#13

Bob H. 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 B.

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - 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


#14

There seems to be alot of industry inertia on static time tools. Better
runtime tools would make a dynamic language such as Ruby more
mainstream.

A number of people have proposed that the runtime tools can work with
good
unit tests in place to exercise all of the code paths.

The breakpoint library is a good start but there is more potential. For
example, a tool that analyzes the runtime paths and graphs an object’s
dependencies would be nice.


#15

Steven L. wrote:

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?

My code goes into maintenance mode almost as soon as
I’ve written 40 lines, i.e., I try to go depth-first
and then flesh out the skeleton as priorities dictate.

This is all done while creating a safety-net, a custom-
application debugger, through test-first development.
(Note: I’ve never had need of Ruby’s debugger.)

The maintenance folks (me initially) are left with
executable, non-lying specifications for how everything
should behave and recipes for building new safety net.

Later,


#16

Hi –

On Fri, 23 Dec 2005, Chad P. wrote:

and being told to be careful with it.
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.

I’ve had for a long time a kind of semi-formulated idea about all this
in my head, and have never expressed it clearly. Let me try, and
probably fail.

In the Perl world, there was (“was” as in, I’m not in that world any
more) a perennial sense that all this “shooting in the foot” stuff was
a kind of test of personal resistance and fortitude. It felt
sometimes like the power of the language was mainly serving to allow
people to demonstrate how careful and wise they were. I don’t say
that the best Perl programmers fell into this pattern, but in a wider
sense it definitely seemed that knowing about the “rope”, and
maintaining a healthy distance from it, was a kind of badge of honor.

In Ruby, I see it differently. This is where I start having trouble
expressing it. It’s a kind of wish that the gravitational forces be
aligned differently: instead of showing one’s strength by pulling
away from the vortex, perhaps the powerful things in the language
could be used in productive ways, so that one falls toward them,
but without danger.

I’m not sure what this means, in practical terms.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#17

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

(Mad props to Ralphie, too.)

James B.
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


#18

On 12/22/05, James B. removed_email_address@domain.invalid wrote:

Bob H. 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!


#19

Bill G. wrote:

It is indeed “The Red Ruby BB Gun”
Well done!

A BB gun doesn’t cut it though.
Ever seen the movie Training Day?:
http://img456.imageshack.us/img456/3705/trainingday8ry.jpg


#20

Bob H. wrote:

that's going to stare in bafflement at these classes that

misunderstand?
those classes is eliminated because I can re-open classes (the other
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