What does 'Monkey Patching' exactly Mean in Ruby?

Y

Yaser Sulaiman

[Note: parts of this message were removed to make it a legal post.]

According to Wikipedia, a monkey patch[1] is:
a way to extend or modify the runtime code of dynamic languages [...]
without altering the original source code.

The following statement from the same entry confused me:
In Ruby, the term monkey patch was misunderstood to mean any dynamic
modification to a class and is often used as a synonym for dynamically
modifying any class at runtime.

I would like to know the exact meaning of monkey patching in Ruby. To be
more specific, I would like to know the answers to the following questions:

1- What does "runtime code" refer to in Ruby?

2- Are "monkey patching" and "open classes" different terms for the same
thing?

3- Is the following considered as monkey patching, or is it something else?

class String
def foo
"bar"
end
end

Regards,
Yaser Sulaiman

P.S. I originally posted this question on stackoverflow[2]. There are some
good
answers over there, but I'm still kinda confused. I hope that someone in the
Ruby
community can clarify this issue for me.

[1]: http://en.wikipedia.org/wiki/Monkey_patch
[2]:
http://stackoverflow.com/questions/394144/what-does-monkey-patching-exactly-mean-in-ruby
 
R

Robert Dober

According to Wikipedia, a monkey patch[1] is:
a way to extend or modify the runtime code of dynamic languages [...]
without altering the original source code.

The following statement from the same entry confused me:
In Ruby, the term monkey patch was misunderstood to mean any dynamic
modification to a class and is often used as a synonym for dynamically
modifying any class at runtime.

I would like to know the exact meaning of monkey patching in Ruby. To be
more specific, I would like to know the answers to the following question= s:

1- What does "runtime code" refer to in Ruby?

2- Are "monkey patching" and "open classes" different terms for the same
thing?
I guess this is the critical point why the Wikipedia article says
"misunderstood"
as in Ruby even core classes are open MP just does not really mean
anything else for core classes
and your own classes or any other imported classes.
3- Is the following considered as monkey patching, or is it something els= e?

class String
def foo
"bar"
end
end

I would consider it MP
Regards,
Yaser Sulaiman

P.S. I originally posted this question on stackoverflow[2]. There are som= e
good
answers over there, but I'm still kinda confused. I hope that someone in = the
Ruby
community can clarify this issue for me.
Hopefully ;)
Cheers
Robert



--=20
Il computer non =E8 una macchina intelligente che aiuta le persone
stupide, anzi, =E8 una macchina stupida che funziona solo nelle mani
delle persone intelligenti.
Computers are not smart to help stupid people, rather they are stupid
and will work only if taken care of by smart people.

Umberto Eco
 
D

David A. Black

Hi --

According to Wikipedia, a monkey patch[1] is:
a way to extend or modify the runtime code of dynamic languages [...]
without altering the original source code.

The following statement from the same entry confused me:
In Ruby, the term monkey patch was misunderstood to mean any dynamic
modification to a class and is often used as a synonym for dynamically
modifying any class at runtime.

I would like to know the exact meaning of monkey patching in Ruby.

There's no exact meaning. Some people use it to mean re-opening core
classes; some people use it to mean re-opening core classes in an
incompetent, unsafe manner; some people use it as a way of indicating
that any time you re-open a core class, you shouldn't (which is a
well-intentioned but reductive position); some people use it to mean
re-opening non-core classes; and so on.

It's basically a negative, uninformative, rather silly term that has
nothing going for it. I personally don't use it. I'm a minority of
about one, though :)


David
 
P

Phlip

Yaser said:
1- What does "runtime code" refer to in Ruby?

In WikiPedia's world, all applications have code that executes for the end-user,
and support code - such as compilers, test files, code generators, etc. Runtime
code is the former.
3- Is the following considered as monkey patching, or is it something else?

class String
def foo
"bar"
end
end

No, that is simply extending the class with a new method. Ruby classes are
always open for extension, and the article you cited implied the
misunderstanding was that is monkey patching. It is not.

This is monkey patching:

class String
def length
42
end
end

The method .length already existed, but we had our way with it. And this example
shows why MP is kind'a dangerous. Ruby has no mechanism to allow only our own
modules to see our patches. My example gives all library code a bogus string
length, and our runtime code would not last very long...

Unfortunately for those who fear Monkey Patching, many Ruby libraries rely on
it. They are released rough-and-ready, before any serious effort to detect where
to install "hooks" (look up "Abstract Template Design Pattern"). So to get
anything done in a big Ruby application, your monkeys will be frequently
climbing up your inheritance trees and patching the code they find there!

WP is full of biases and points-of-view; use it carefully!!
 
R

Robert Klemme

[Note: parts of this message were removed to make it a legal post.]

According to Wikipedia, a monkey patch[1] is:
a way to extend or modify the runtime code of dynamic languages [...]
without altering the original source code.

The following statement from the same entry confused me:
In Ruby, the term monkey patch was misunderstood to mean any dynamic
modification to a class and is often used as a synonym for dynamically
modifying any class at runtime.

I would like to know the exact meaning of monkey patching in Ruby. To be
more specific, I would like to know the answers to the following questions:

1- What does "runtime code" refer to in Ruby?

It refers to the code that is shipped with the interpreter or other
runtime system (e.g. String, Hash, Array, Fixnum and the like). Usually
a lot other code depends on this and a monkey patch has a certain
potential to wreck havoc on the whole application. :)
2- Are "monkey patching" and "open classes" different terms for the same
thing?

Yes, of course. "Open classes" is a general concept, while "monkey
patching" is a methodology (at least something procedural). You can use
"open classes" to do "monkey patching" - but there are other tools as
well that you can use to do it (e.g. you could try to overwrite code in
memory or in C change the pointer of a basic function like strlen).
3- Is the following considered as monkey patching, or is it something else?

class String
def foo
"bar"
end
end

I would not call this "monkey patching" because although you modify a
core class you do not modify a _core functionality_. Most of the time I
have seen "monkey patching" denote a change to core functionality with
potentially far reaching consequences, e.g. this would rather be a
monkey patch

class Object
def to_s
"boom!"
end
end

because it has potential to make certain things work but also break *a
lot* of code.

Cheers

robert
 
R

Robert Klemme

2008/12/27 David A. Black said:
It's basically a negative, uninformative, rather silly term that has
nothing going for it. I personally don't use it. I'm a minority of
about one, though :)

I'd say "about two". :)

robert
 
J

James Britt

David said:
It's basically a negative, uninformative, rather silly term that has
nothing going for it. I personally don't use it. I'm a minority of
about one, though :)

Minority of at least two.
 
M

marc

David A. Black said...
Hi --

According to Wikipedia, a monkey patch[1] is:
a way to extend or modify the runtime code of dynamic languages [...]
without altering the original source code.

The following statement from the same entry confused me:
In Ruby, the term monkey patch was misunderstood to mean any dynamic
modification to a class and is often used as a synonym for dynamically
modifying any class at runtime.

I would like to know the exact meaning of monkey patching in Ruby.

There's no exact meaning. Some people use it to mean re-opening core
classes; some people use it to mean re-opening core classes in an
incompetent, unsafe manner; some people use it as a way of indicating
that any time you re-open a core class, you shouldn't (which is a
well-intentioned but reductive position); some people use it to mean
re-opening non-core classes; and so on.

My brain is fuddled today recovering from flu, but what do you mean by
"reopening"?
 
D

David A. Black

Hi --

David A. Black said...
Hi --

According to Wikipedia, a monkey patch[1] is:

a way to extend or modify the runtime code of dynamic languages [...]
without altering the original source code.

The following statement from the same entry confused me:

In Ruby, the term monkey patch was misunderstood to mean any dynamic
modification to a class and is often used as a synonym for dynamically
modifying any class at runtime.

I would like to know the exact meaning of monkey patching in Ruby.

There's no exact meaning. Some people use it to mean re-opening core
classes; some people use it to mean re-opening core classes in an
incompetent, unsafe manner; some people use it as a way of indicating
that any time you re-open a core class, you shouldn't (which is a
well-intentioned but reductive position); some people use it to mean
re-opening non-core classes; and so on.

My brain is fuddled today recovering from flu, but what do you mean by
"reopening"?

Like this:

class Array
def my_new_method
end
end

where I'm reopening the core Array class and adding and/or overriding
methods in it.


David
 
M

marc

David A. Black said...
Hi --

David A. Black said...
Hi --

On Sun, 28 Dec 2008, Yaser Sulaiman wrote:

According to Wikipedia, a monkey patch[1] is:

a way to extend or modify the runtime code of dynamic languages [...]
without altering the original source code.

The following statement from the same entry confused me:

In Ruby, the term monkey patch was misunderstood to mean any dynamic
modification to a class and is often used as a synonym for dynamically
modifying any class at runtime.

I would like to know the exact meaning of monkey patching in Ruby.

There's no exact meaning. Some people use it to mean re-opening core
classes; some people use it to mean re-opening core classes in an
incompetent, unsafe manner; some people use it as a way of indicating
that any time you re-open a core class, you shouldn't (which is a
well-intentioned but reductive position); some people use it to mean
re-opening non-core classes; and so on.

My brain is fuddled today recovering from flu, but what do you mean by
"reopening"?

Like this:

class Array
def my_new_method
end
end

where I'm reopening the core Array class and adding and/or overriding
methods in it.

Okay, so reopening is extending or overriding (a method of) a core
class. Good to know the lingo.

And I concur with your earlier assertion regarding the MP term:

It's basically a negative, uninformative, rather silly term that has
nothing going for it.
 
G

Gavin Sinclair

It's basically a negative, uninformative, rather silly term that has
Four at the least :)

m.

Based on the evidence before you, Martin, you can only conclude "Three
at the least". James didn't declare his hand.

Cheers,
Gavin
 
Y

Yaser Sulaiman

[Note: parts of this message were removed to make it a legal post.]

Thank you for your answers, everyone. They were really informative.

There's no exact meaning.
I couldn't agree more. It almost seems like every one has his own special
understanding of the term. But I guess that this isn't always a bad thing.
After all, in a community of more than one person, there will always be a
thing that the community can't agree upon. :p

Cool! We can be a gang!
Count me in! - but I still think that the term 'monkey patching' is
cooler/funkier than 'open classes' :p

Regards,
Yaser
 
J

Jörg W Mittag

Phlip said:
No, that is simply extending the class with a new method.

Ah, but that's the interesting part: how do you know that somebody
else didn't already add a String#foo method? In that case, it *would*
be monkey patching. Even worse: which of the two methods would be
considered monkey patching and which one wouldn't, would depend
entirely on the *load order* of those two snippets of code.

That's why I don't think distinguishing between adding and changing
methods makes sense: either both are monkey patching or neither are.

jwm
 
P

Phlip

Ah, but that's the interesting part: how do you know that somebody
else didn't already add a String#foo method?

That's why it's not "elegantly patching with surgical precision".

You weren't the monkey - for publishing such a silly method. _They_ were!

(Stating this as a guideline - if it's a vanilla method name like '.length',
it's a monkey patch, and if it's application-specific you should give it a weird
name, like '.__my_boss_my_app_length'.)
 
R

Robert Dober

I'll put in a plug for what I believe is by far the safest way to
extend core functionality, namely #extend. A classic case is the
desire to have #gsub! not return nil when the string doesn't change.

module MyGsubBang
def gsub!(*args, &block)
super(*args, &block) || self
end
end

str = "abc".extend(MyGsubBang)
This indeed is a very sensible and elegant way to do things.

The true werewolf of dynamic extension (I am happy with MP but there
seems to be a consensus against that term...) however is this case

# first I am using what I have just learned from David :p
module VersionIndependentInstanceMethods
def instance_methos *args, &blk
super.map{ |mn| mn.to_sym }
end
end
Class.include Version...

class WhatEverOrMaybeEvenACoreClass
if instance_methods.include? :xxx then
raise IDoNotKnowWhatToDoError, "No I really don't"
else
def xxx ....
end
end
end

Any insights on IDoNotKnowWhatToDoError?

Cheers
Robert
 
D

David A. Black

Hi --

This indeed is a very sensible and elegant way to do things.

The true werewolf of dynamic extension (I am happy with MP but there
seems to be a consensus against that term...) however is this case

# first I am using what I have just learned from David :p
module VersionIndependentInstanceMethods
def instance_methos *args, &blk
super.map{ |mn| mn.to_sym }
end
end
Class.include Version...

I'd be careful there. You're making a class-wide (all instances of
Class) change. (include is private, but still :) That could bite you
if you're depending on instance_methods to return strings, which we
can legitimately do in 1.8.
class WhatEverOrMaybeEvenACoreClass
if instance_methods.include? :xxx then
raise IDoNotKnowWhatToDoError, "No I really don't"
else
def xxx ....
end
end
end

Any insights on IDoNotKnowWhatToDoError?

I guess you could go back to the #extend technique. I should add,
however, that even that technique isn't bullet-proof. object#a might
call object#b, so if you override object#b in a module, object#a won't
get the behavior it expects.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
 
T

Tom Link

=A0 =A0module MyGsubBang
=A0 =A0 =A0def gsub!(*args, &block)
=A0 =A0 =A0 =A0super(*args, &block) || self
=A0 =A0 =A0end
=A0 =A0end

=A0 =A0str =3D "abc".extend(MyGsubBang)

str +=3D "1"

This would return a normal string. You'd then have to extend those
strings again and again. Please correct me if I'm wrong but IMHO this
approach brings little advantage over defining a subclass of String:

class MyString < String
...
end

str =3D MyString.new("abc")

This creates a copy of "abc" in this particular case but provides IMHO
more flexibility. With some extra work you could catch those cases
where the function returns a new string, eg something in the line of:

class MyString < BasicObject

YOUR METHODS HERE

def method_missing(...)
...
end

end

The extra indirection has its drawbacks of course.

The conclusion IMHO is twofold: (1) "monkey patching" is ok if you're
the only user of your code (in which case it is okay to use a silly
name for that practice) or if the extensions are part of a well
documented supplementary library/framework where those extended
methods become some sort of standard. (2) Beware of people who are
proud of their monkey tactics.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top