The reason for this is that you want to fully attach the function in the space as a native method and this requires some closures to make work sanely. In short you want:
package foo;
use Moose;
has bar => (is => 'rw');
to behave identically as: package notfoo;
use foo;
foo::has(bar => (is=>'rw'));
If you rely on the caller the second example would add a bar accessor to the caller's namespace (notfoo) rather than to foo. In short you on't want to use "has" in the Moose namespace. You want to add a custom function to the importing namespace.As I understand it you can't do this in Python not because it is a bad idea (it is a very good idea sometimes) but rather because of limitations in the language (no multiline lambdas, which you need in order to do useful stuff with the symbol table in this regard unless there is an equivalent in terms of defining a method the calling class inside a closure in the imported package). But again, my knowledge of Perl is much better than my knowledge of Python, so I could be wrong.
When you get into this sort of metaprogramming, custom symbol table manipulations are not only helpful but downright necessary. It is what allows you to add a sophisticated MOP when such is not included in core.
Instead, in normal Python it is the importing module that must decide who has access to its own namespace, and who must live within a separated one. It has a completely different set of costs and benefits. (I sometimes wonder if Guido used Perl as a counterexample when creating Python - its principles are almost completely opposite.)
from __future__ import print_functionWhich of the following are side effects?
1. Initializing a point of sale printer, checking for errors, and raising exceptions if, say, it is out of paper? Let's say this is a cash drawer driver and the cash drawer connects through the printer, and if the printer is out of paper, the drawer won't open properly (this happens btw). I would call this a side effect as well as a separation of concerns violation btw. However it is not likely to be a visible change to other modules.
2. Check for the presence of a binary and if found, cache the path to it, perhaps instantiating another object to do so? Definitely a side effect there, but not publicly visible.
3. Initializing an external library's environment (as happened in this case)? Done wrong it crashes the system but I suspect the segfault was not intended. Again it isnt clear to me you have a publically visible side effect intended.
This is the approach taken by gevent, which allows you to replace the entire I/O stack. But importing it does not effect the change; you must explicitly call code to do that. This is done thus:
c.f. http://www.gevent.org/gevent.monkey.html