Python can be just as ugly as PHP…
May. 14th, 2009 11:07 amI was reading through the Wordpress source code, trying to figure out a problem for a contractor, when I saw the function compact(). When I saw it I boggled, read the description, and shook my head.
Compact() takes a list of variable names as strings, and returns a hash of those variable names and their values. So if you have something like:
$title = "My blog";
$link = "foo";
$h = compact('title', 'link');
You get back a hash of array(’title’ => ‘My blog’, ‘link’ => ‘foo’).
That, to my thinking, is completely messed up. You’re giving this function, which has its own scope, explicit permission to twiddle with variables in the current scope and create a new variable. It’s one of those things that convinces me that PHP is an unholy mess of silliness.
And then my brain reminded me that, hey, you can do the exact same thing in python. So, I have:
import inspect
def compact(*args):
return dict([(i, inspect.currentframe().f_back.f_locals.get(i, None))
for i in args])
def foo():
a = "blargh"
b = "bleah"
c = ['1', '2', '3']
return compact('a', 'b', 'c')
print foo()
And sure enough, this spits out: {’a': ‘blargh’, ‘c’: ['1', '2', '3'], ‘b’: ‘bleah’}
I hang my head in shame for giving Django developers one more thing around which they can develop bad habits.
This entry was automatically cross-posted from Elf's technical journal, ElfSternberg.com
no subject
Date: 2009-05-14 06:34 pm (UTC)If the latter I don't see why it's quite so terrible ;)
no subject
Date: 2009-05-14 06:38 pm (UTC)no subject
Date: 2009-05-14 06:42 pm (UTC)no subject
Date: 2009-05-14 06:43 pm (UTC)I'm still not convinced it's an altogether bad thing, but like most thing could quite easily be
turned to the purposes of the dark sideused to make a horrific mess.no subject
Date: 2009-05-14 07:45 pm (UTC)When we write
$title = 'My Blog';
we create a variable in local scope, called $title, with contents of 'My Blog'.
When we call compact, we're calling it with the string 'title', not the variable $title. Which means that $title is never passed in to that function - that function should have no way of knowing the contents of $variable (which, in this example, is 'My Blog'). And yet, at the end of the unholy mess, somehow the hash that came back out has the content of that variable. Which is extremely counter to the intuitive notion of how scope ought to work; the child scope really ought to have the variables passed in explicitly if it wants to know about them.
no subject
Date: 2009-05-15 12:39 am (UTC)I thougth that was odd as well. What I still dont get is why the results of B and C are transposed in the python output?
no subject
Date: 2009-05-15 12:43 am (UTC)no subject
Date: 2009-05-15 02:50 am (UTC)use PadWalker qw(peek_my peek_our); sub compact { my(%result,%my_our,$pkg); $pkg=caller(0); %my_our=(%{peek_my(1)},%{peek_our(1)}); foreach my $var (@_) { if ($var =~ /[:']/) { no strict 'refs'; $result{$var}=$$var; } elsif (defined(my $ref=$my_our{"\$$var"})) { $result{$var}=$$ref; } else { no strict 'refs'; $result{$var}=${"${pkg}::$var"}; } } \%result; }no subject
Date: 2009-05-15 06:35 pm (UTC)