Monkeypatching is Destroying Ruby

On Wed, Feb 27, 2008 at 1:44 PM, s.ross [email protected] wrote:

FWIW, I’m in the first camp, and feel Ruby does just fine for my
needs. I understand the arguments to the contrary, but don’t
anticipate them being a problem in my application space. That’s not to
claim validity of either position, just disclosure of my predisposition.

If that’s how you personally divide things, then I’m in your camp too.
No, really.

I’m actually not very interested in any of the proposals to extend
Ruby (either with patches or with Ruby code). I’ll be completely
satisfied if, as a result of this discussion, a few more people think
“oh yeah, I could do this with [inheritance|mixins|delegation|etc.],
and it would be easier than monkey patching!” when they set out to add
some functionality to an existing class.

As far as the language goes, I’m happy with Ruby the way it is.

On Feb 27, 2008, at 6:20 AM, Jones, Brian - McClatchy Interactive wrote:

It may be enough to simply have ruby warn us when and where a class
has
been re-opened and a means to ignore it by file/path or namespace if
we
want.

This whole thing is a complex philosophical discussion about the goals
of the language and the problems that could be encountered if…

Perhaps someone could, instead of debating the theory, the impacts on
scaling, and the philosophy, come up with a patch and run it by Ruby
core for comment. Otherwise this thread could continue forever with
those who find monkey patching useful saying … um … “I find monkey
patching useful” and those who have issues with open classes
saying … um … “it’s not scalable, it’s surprising, it’s destroying
Ruby, etc.”

The arguments are out there. What it takes is a stake in the ground (a
patch) that demonstrates some “better way” that doesn’t cause Ruby to
break existing applications.

FWIW, I’m in the first camp, and feel Ruby does just fine for my
needs. I understand the arguments to the contrary, but don’t
anticipate them being a problem in my application space. That’s not to
claim validity of either position, just disclosure of my predisposition.

Cheers,

Steve

On Wed, Feb 27, 2008 at 7:12 AM, Joel VanderWerf
[email protected] wrote:

Cheers
end

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

That indeed is a truly perverse use case for MP, you have my deepest
respect ;).
It is indeed an extreme example what the enabling approach can lead
to, but it is maybe not a coincidence that it was Smalltalk which
really brought up UT first IIRC?
That is something we should add into this discussion, MP might be a
danger for Ruby to be extincted (I do not believe so but just for the
sake of argument), TDD (or BDD) might save it somehow.
But there is no doubt it is not much of a relief if somebody released
something stupid in a library and now a zillion tests do not pass
anymore.

Just out of curiosity why does Class#freeze need to exist and cannot
be inherited from Object#freeze?

Cheers
Robert


http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

On Wed, Feb 27, 2008 at 4:04 PM, Trans [email protected] wrote:

advantage.

I would now suggest that it is the FHS that is holding us back, not
the other way around --talk about your size/momentum advantage.

Suggested reading:

GoboLinux - the alternative Linux distribution

I perfectly agree that a large part of the reason the FHS is the way
it is (and why we’re using FHS or something similar on most Unix
systems) is historical momentum. I feel that’s a tangent, though.

In my opinion, the core issue is that people should be able to expect
a single directory layout on a single operating system, so the
operating system owns the directory layout. If you are going to write
a package manager that works on different operating systems, it should
be able to adopt to the conventions of those operating systems, or it
hose the users of the operating systems. Users that don’t care if a
package is written in Ruby, or in Python, or in C, or whatever.

I think having different operating systems - like GoboLinux, like Mac
OS X, like Windows - that experiment with different layouts is a good
thing. There may well be other layouts that work better than the
traditional one these days. I just think this is an area for
operating systems to experiment, not programming languages.

Eivind.

Hi,

I have read all other Statements in this thread, but as it is such a
vast collection of opinions, its hard to keep track. So: if I mention
something for the second time, please ignore it ;).

I think the problem with MonkeyPatching is clear: it is a hack and
hacks tend to die soon. I am strongly opposed to use it in an official
release without thinking twice. Usually, there is a better way to
solve the problem. When browsing Rails plugins (i don’t want to bash
rails, but thats an incredibly big source third-party-libraries), I
often see gruesome hacks to solve problems that could easily be solved
otherwise - because the author obviously didn’t know about the right
way. Some time ago, many plugins had some implementation of
String#constantize (better, worse, the same as the Rails version).
This shows one thing:
Plugin authors are not aware of everything the language has to offer.
So they do what they do best. Which is not always good. The other side
of the problem is that the target of your patch is not written to be
extended (have a look at the “render”-Method in rails) - so you only
quick resort is a hack.
Monkeypatching is cool - if you think well an at least twice about it.

The problems with meta-programming is another one:
We love it. We advertise it as core features of the language (which -
in my book - it is not).

Take the above example: Array#to_csv

Why not CSV.from(arg)? It is cumbersome to read and we need to think
about a way to split the implementation details of from(Array) and
from(otherType) in halves. But from an OO-perspective, it makes
perfect sense: an Array doesn’t have to care about the types that it
can be converted into an it is well encapsulated.

But, because we are lazy, lazy ruby programmers, we love our
object.send syntax. So we implement a shorthand method. Another
example is Object.in?(), often seen as a shorthand for
some_collection.contains?(obj) (Im not sure, but this is called
‘grief’, afaik). The first is nicer, the second is cleaner. Many vote
for the first - another Method in Object. Another well known Library
defines Object#should because they think of it to be nicer. By doing
this, we are slowly overloading the core-system. I like approach of
facets: they are a collection of such idioms, but they must be
switched on explicitly.
The question you have to answer for yourself when creating such a
method is: “Is it really that important?”. Often I have the impression
that this question is often answered with “Yeah, its cool and its the
ruby way!”

On the other hand, those features are the ones that make the little
difference. Used correctly, open classes are a way to beautiful and
well constructed code.

It all comes boils to a matter of knowledge, experience and
discipline. We have got to be aware that many ruby developers don’t
have all of those.

Greetings
Florian G.

Robert D. wrote:

Just out of curiosity why does Class#freeze need to exist and cannot
be inherited from Object#freeze?

Because Module#freeze is defined by ruby (so redefining Object#freeze
would not have the desired effect in this case).

Yes,

sorry for not mentioning. I just found that many that where developing
plugins for Rails where patching things that didn’t need to be patched
or hacked in the Framework.
Thanks for the clarification.

Florian G.

That’s what the poster said: “better, worse, the same as the Rails
version”.

Please don’t top post.

On 2/28/08, James G. [email protected] wrote:

On Feb 28, 2008, at 8:16 AM, Florian G. wrote:

Some time ago, many plugins had some implementation of
String#constantize (better, worse, the same as the Rails version).
This shows one thing:
Plugin authors are not aware of everything the language has to offer.

Just to be clear, the Ruby programming “language” does not have a
method called String#constantize. It’s provided by the Ruby on Rails
“framework.”

On Feb 28, 2008, at 8:50 AM, [email protected] wrote:

That’s what the poster said: “better, worse, the same as the Rails
version”.

Please reread the quote above where the poster hints that the method
is provided by a “language.”

James Edward G. II

On Thu, Feb 28, 2008 at 10:07 AM, James G. [email protected]
wrote:

Please don’t top post.

Sorry, that was posted from the GMail mobile interface.

but also said “Plugin authors are not aware of everything the LANGUAGE
has to offer.” which does not follow.

On Feb 28, 2008, at 8:16 AM, Florian G. wrote:

Some time ago, many plugins had some implementation of
String#constantize (better, worse, the same as the Rails version).
This shows one thing:
Plugin authors are not aware of everything the language has to offer.

Just to be clear, the Ruby programming “language” does not have a
method called String#constantize. It’s provided by the Ruby on Rails
“framework.”

James Edward G. II

On Feb 28, 2008, at 4:07 PM, James G. wrote:

offer.

Please reread the quote above where the poster hints that the method
is provided by a “language.”

James Edward G. II

As i said, it was an accidential error and should read “Framework”.
Programming Ruby for 5 years, I know the distinction ;).

Florian G.

On Thu, Feb 28, 2008 at 6:51 AM, Joel VanderWerf
[email protected] wrote:

Robert D. wrote:

Just out of curiosity why does Class#freeze need to exist and cannot
be inherited from Object#freeze?

Because Module#freeze is defined by ruby (so redefining Object#freeze
would not have the desired effect in this case).
I was not criticizing your solution(1), I only wanted to know something.

Let me rephrase my question then, why Module#freeze what has it to do
in addition to Object#freeze
Just in case you happen to know.
Thx in advance

Cheers
Robert

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


http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

“R” == Robert D. [email protected] writes:

R> Let me rephrase my question then, why Module#freeze what has it to do
R> in addition to Object#freeze

vgs% ruby -e ‘a = Class.new.freeze; p a’
#Class:0xb7cabc98
vgs%

vgs% ruby -e ‘class Module; def freeze() super() end end; a =
Class.new.freeze; p a’
-e:1:in to_s': can't modify frozen object (RuntimeError) from -e:1:in inspect’
from -e:1:in p' from -e:1:in
vgs%

Guy Decoux

On Thu, Feb 28, 2008 at 6:16 AM, Florian G. [email protected]
wrote:

But, because we are lazy, lazy ruby programmers, we love our
object.send syntax. So we implement a shorthand method. Another
example is Object.in?(), often seen as a shorthand for
some_collection.contains?(obj) (Im not sure, but this is called
‘grief’, afaik). The first is nicer, the second is cleaner. Many vote
for the first - another Method in Object. Another well known Library
defines Object#should because they think of it to be nicer. By doing
this, we are slowly overloading the core-system.

And? There’s nothing wrong with “overloading the core system” if the
end result is cleaner and more readable code. Personally, good ruby
code is all about expressiveness and readability, not proper OO
encapsulation and staying-out-of-the-core. The only real problem, as
you note, is that of conflicting extensions to the same core classes,
and care does need to be taken with that, but that’s no reason to
throw the baby out with the bathwater.

One interesting thing to do is something I’ve seen in the Javascript
world - libraries that come with an option to install themselves in
core classes or stick to a namespace, so that you can either type
MyLib.do_something(object), or turn the option on and then do
object.do_something.

martin

On Feb 24, 4:43 pm, Gary W. [email protected] wrote:

Facets defines Hash#- based on [key,value] pairs and not keys. An
argument can be made for either approach but you can’t integrate code
bases that have different expectations for Hash#-.

BTW, there is a reason for that. You can do:

ahash - otherhash.keys

T.

On Feb 29, 2008, at 1:20 PM, Trans wrote:

ahash - otherhash.keys

T.

That does not hurt the argument. If you expect this, you are fine.
If you define or expect a different interpretation, you are in a world
of pain.

But it can be argued that you should be aware of this, especially when
you
are using Facets, which consists of a high number of such cases.

Florian G.

On Feb 29, 7:33 am, Florian G. [email protected] wrote:

BTW, there is a reason for that. You can do:

ahash - otherhash.keys

T.

That does not hurt the argument. If you expect this, you are fine.
If you define or expect a different interpretation, you are in a world
of pain.

Sure. I was just pointing out why that particular functionality was
chosen, vs. the other reasonable suggestion. That’s another benefit of
using a common library --you get a lot of collective minds evolution
behind things.

T.

On Fri, Feb 29, 2008 at 6:20 AM, Trans [email protected] wrote:

ahash - otherhash.keys

I think this is the worst kind of monkey-patching - breaking existing
functionality. I didn’t realize facets went to this level. Another
reason
to never touch it.