hoodwink.d enhanced
RSS
2.0
XHTML
1.0

RedHanded

Monkeypytching? #

by why in inspect

So now some Pythonistas want monkeypatching! Will the snakes recoil? Hardly, in the comments, Harry Fuecks offers up:

 class Foo:
   def __init__(self):
     self.x = "x = 1" 
     self.y = "y = 2" 
   def showx(self):
     print self.x

 def showy(self):
   print self.y

 if __name__ == '__main__':

    # Attach at runtime...
    Foo.showy = showy
    f2 = Foo()
    f2.showx()
    f2.showy()

It’s priceless how Harry’s code gets flattened in the comments. I mean this is one example where the nesting is really essential. I’m not saying my comment layout is any better. We’ve had a real mess with plus signs here. (Nicked from Simon.)

said on 18 Jul 2006 at 12:18

and the trees whisper…

will there ever be the succinctness of
class << self; self; end
in Python?

Nay. It shall not be.

said on 18 Jul 2006 at 12:52

Where can I find a guide on what that ‘class << self; self; end’ business actually means?

said on 18 Jul 2006 at 13:30

This seems to return a virtual class object. I’m guessing its the one created when you go adding methods to a particular instance of a class.


class Mrr
  def vclass
    class &lt;&lt;self;self;end
  end
end

m = Mrr.new
m_class = m.vclass
m_class != Mrr # => true

In this case, I can’t find much use for m_class, but maybe I’m missing the point. However, I do have a curiosity question:


class &lt;&lt;m_class
  def some_method; puts 'hello'; end
end

Where does some_method go?

said on 18 Jul 2006 at 13:40

To me, class << obj means add to obj as if it were a class. You can use this to add methods to obj.

So, class << self adds methods to whatever object is stored in self.

said on 18 Jul 2006 at 13:41

I wrote up a little experiment some time ago using Python decorators for places Ruby uses blocks. At the bottom is a decorator magic_set which you can use like:

@magic_set(Foo)
def show_y(self):
    print self.y

You can use it to add class or instance methods to instances or classes (e.g., @magic_set(a_foo) also works).

said on 18 Jul 2006 at 14:09

slick

said on 18 Jul 2006 at 14:19

Is this technique actually called monkeypatching? I want a short-hand for “inject methods into existing class at runtime”.

said on 18 Jul 2006 at 14:26

well, “reopen classes” in rubyland is called “monkeypatching” in python land. Notice that they can monkeypatch a single object too (aka add a singleton method) via c.foo=(lambda self: 10).__get__(c)

said on 18 Jul 2006 at 14:40

Ian Bicking: Nice hack! What kind of reaction have you received from your fellow Python people?

Parand: ...a way to extend or modify runtime code… And I think Mr. Bicking’s to blame. :)

said on 18 Jul 2006 at 14:47

Oh, wait a min, I thought the word was Ian’s.

But it looks like the origins are from Zope. Gorilla patch, turkey patch, monkey patch. Next up: donkey patch.

said on 18 Jul 2006 at 14:49

I like guerilla patch better. It fits in with begin / rescue. Can we start using guerillapatching instead?

said on 18 Jul 2006 at 15:28

I’m interested in the philosophical background of monkey/gorilla patching. This seems like an interesting and not well known (to me anyway) technique. It’s not inheritence, but it’s similar. Are there any good deep discussions beyond “it’s bad”?

Tangent: Gorilla or Guerilla patching?

Gorilla: “a very large typically black-colored anthropoid ape” or “an ugly or brutal man”

Guerilla: “a person who engages in irregular warfare especially as a member of an independent unit carrying out harassment and sabotage”

I kinda like Guerilla for this one.

said on 18 Jul 2006 at 19:10

Guerillapatching. And so it is coined. Greatness.

said on 18 Jul 2006 at 20:31

so what exactly does the

 @ 
sign mean in Python anyway (as in
@magic_set
above)? I thought those pythonistas were always complaining about all those
@
signs in Ruby code and now they’ve gone and stolen our ‘em! Then they complained about Ruby’s ‘monkey patching’ and now they’re making off with the monkey patching too (though, I’ve gotta admit, it doesn’t look very good in Python). Next thing you know, they’ll have $:, $! and friends.

...or is it the other way around? Are we Rubyists secretly subverting Python? Very clever! One day the Pythonista’s will wake up and find that the python binary is just a link to /usr/bin/ruby, but then it will be too late.

said on 19 Jul 2006 at 00:32

@Parand : Actually this technique is very well known. In fact monkey-patching is the basis of prototype-based programming where there are in fact no classes and no inheritance. Instead you have objects which can be cloned and further specialized by adding methods and fields. Self, Io and Javascript are all prototype-based languages.

said on 19 Jul 2006 at 00:34
In Python, the @ sign signifies a decorator. Decorators are a new (introduced in Python 2.4) way of modifying existing functions.

@blah
def fn(arg):
  ...
  return x

Is exactly equivalent to:


def fn(arg):
  ...
  return x
fn = blah(fn)

So blah is a function that ‘wraps’ another function. You can do some pretty neat tricks with this stuff, but it really is just syntactical sugar.

said on 19 Jul 2006 at 06:31

@<|:{: We’d actually have to convince them to put end at the end of their blocks… at least the indenting thing isn’t a problem.

Thanks for explaining the way class << self works: it’s kinda backwards from my way of thinking, though. I’m going to go have some fun playing around with it and see what I can come up with it. How useful do you think it would be to do something like class << self; def get_self; self; end; end; would be? At all?

M.T.

said on 19 Jul 2006 at 10:45

I don’t mean to get a lexical here, but monkeypatching is the best word to come into programming in a long time, and I don’t care where it started, just as long as I get to use it in ruby.

said on 25 Jul 2006 at 01:50

<|:{ said: “Then they complained about Ruby’s ‘monkey patching’ and now they’re making off with the monkey patching too”

Not to engage in a p… contest, but monkeypatching is really nothing new in Python (FWIW, Python even let you change the class of an object at runtime…).

The difference is that, in Python, it’s considered a hack – a pretty useful one but still a hack-, not a best practice.

said on 26 Jul 2006 at 03:10

In Io we feed monkeys like this:

Io> Monkey := Object clone

=> Monkey_0×1365f30: type = “Monkey”

Io> pinupgeek := Monkey clone

==> Monkey_0×136cab0:

Io> Monkey eat_banana := method(“jumjummujjscrunch” print)

> method("jumjummujjscrunch" print)

Io> pinupgeek eat_banana

jumjummujjscrunch

> jumjummujjscrunch
said on 28 Jul 2006 at 17:54

Heh. It was nice of you to put up a version of Harry’s code with the indentation fixed. But GReader or your RSS feed ate it again.

What was that Python people always used to say about indentation not being a big deal as long as you have a good editor?

end.

11 Jul 2010 at 21:30

* do fancy stuff in your comment.

PREVIEW PANE