If Monkey Patching Is Permitted in Both Ruby and Python, Why Is It More Controversial in Ruby

If monkey patching is permitted in both Ruby and Python, why is it more controversial in Ruby?

As a Python programmer who has had a taste of Ruby (and likes it), I think there is somewhat of an ironic parallel to when Python was beginning to become popular.

C and Java programmers would ‘bash’ Python, stating that it wasn't a real language, and that the dynamic nature of its types would be dangerous, and allow people to create ‘bad’ code. As Python became more popular, and the advantages of its rapid development time became apparent, not to mention the less verbose syntax:

// Java
Person p = new Person();
# Python
p = Person()

we began to see some more dynamic features appear in later versions of Java. Autoboxing and -unboxing make it less troublesome to deal with primitives, and Generics allow us to code once and apply it to many types.

It was with some amusement that I saw one of the key flexible features of Ruby – Monkey Patching, being touted as dangerous by the Python crowd. Having started teaching Ruby to students this year, I think that being able to ‘fix’ the implementation of an existing class, even one that is part of the system, is very powerful.

Sure, you can screw up badly and your program can crash. I can segfault in C pretty easily, too. And Java apps can die flaming death.

The truth is, I see Monkey Patching as the next step in dynamic and meta-programming. Funny, since it has been around since Smalltalk.

Why would one want to use ruby over python or vice versa?

I just came across this comparison, b/w Ruby and Python, which is in terms of performance and memory management.

A fair comparison can be found here. Further, I tend to agree with all the three answers above.

What is a mixin and why is it useful?

A mixin is a special kind of multiple inheritance. There are two main situations where mixins are used:

  1. You want to provide a lot of optional features for a class.
  2. You want to use one particular feature in a lot of different classes.

For an example of number one, consider werkzeug's request and response system. I can make a plain old request object by saying:

from werkzeug import BaseRequest

class Request(BaseRequest):
pass

If I want to add accept header support, I would make that

from werkzeug import BaseRequest, AcceptMixin

class Request(AcceptMixin, BaseRequest):
pass

If I wanted to make a request object that supports accept headers, etags, authentication, and user agent support, I could do this:

from werkzeug import BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin

class Request(AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin, BaseRequest):
pass

The difference is subtle, but in the above examples, the mixin classes weren't made to stand on their own. In more traditional multiple inheritance, the AuthenticationMixin (for example) would probably be something more like Authenticator. That is, the class would probably be designed to stand on its own.

Most harmful misconception of beginners about programming?

Re-inventing standard library functions/classes.

After going through a language book/tutorial, most beginners - knowing how to handle strings and numbers - will invent their own date functions, their own 'compression algorithms', their own SORT implementations.

Oh, and they always spend their first day searching for clrscr();.



Related Topics



Leave a reply



Submit