perl5i Makes More Simple Things Simple

Suppose that you want to load a module dynamically (you have the name in a
scalar), then alias a function from that module to a new name in another class.
In other words, you want a renaming import. How do you do that in Perl 5?

There's a lot of magic going on there. Aliasing requires using symbolic refs
which means turning off strict. Because you want strict off in as small a
hunk of code as possible you have to enclose it in braces. Then, require
Class and require $class work differently, so you have to trick require
into seeing a bareword by evaling it. Don't forget to catch and rethrow the
error! Finally, to do the aliasing you need to get a code ref with can() and
assign it to the symbol table via the magic of typeglobs.

Guh. There's an idea in interface design called The Gulf of
Execution which
measures the distance between the user's goal and the actions she must take to
achieve that goal. The goals here are to:

Release the breath you've been holding in for the last 15 years of Perl 5.

Through the magic of autoboxing,
perl5i lets you call methods on unblessed scalars, hashes, arrays, regexes,
references... anything. It also implements some handy methods. Some, like
require(), are core functions redone as methods. Others, like alias(),
should be core functions never made it in for whatever reason. autoboxing
gives perl5i the freedom to add handy features without polluting the global
function/method namespace with new keywords.

Recall the goals:

Load a class from a variable.

Alias a function in that class.

... and consider perl5i's actions:

Call require() to load the class.

Call can() to get a reference to the function.

Call alias() on that reference to alias it to the other class.

The gulf has narrowed to a stream you can hop over while hardly getting your
feet wet.

The goal of perl5i is to bring modern conveniences back to Perl 5. In the 15
years since the release of Perl 5, we've learned a lot. Our views of good
practices have changed. 15 years ago, aliasing a function was black magic
available only to the wildest of gurus. Now it's a technique many module
authors take advantage of. Why should it remain complicated and error prone?

Autoboxing is a big part of perl5i, allowing it to add convenience methods
without having to add new keywords. Adding new keywords--which contracts the
function names available to programmers--is a big thing holding Perl 5 back!
Every potential new keyword is a debate over compatibility. Autoboxing
eliminates that debate. It takes off the brakes.

Some other examples: how do I check if a scalar contains a number, an integer,
or a
float?
The Perl FAQ entry on the subject is two pages long offering five different
possibilities, two of which require pasting code. Code in FAQs tends to rot,
and perlfaq is no exception; without testing nobody noticed that those
venerable regexes fail to catch "+1.23". How does perl5i do it?

say "It's a number" if $thing->is_number;
say "It's an integer" if $thing->is_integer;
say "It's a decimal" if $thing->is_decimal;

It's clear, simple, fast, and tested. TMTOWTDI is great and all, but FAQs are
about getting things done, not about writing dissertations on the subject.
perl5i picks one way that's pretty good and makes it available with no fuss.

The bar for what is "simple" has moved since Perl 5 first came out. perl5i
takes the goal of "simple things should be simple" and helps us all catch up.

Tags:

5 Comments

Is it bad form to comment on your own article? Well, I figure I'll get the ball rolling. (BTW It takes OpenID so you don't really need your own account to comment if that's holding you back)

This article has obviously cherry-picked a set of features that's been implemented well, but this combination isn't something that was planned. I was writing a test and needed to do just the above, dynamically load a class and alias a function from it. The idea of having require() return the class loaded, rather than the cutesy but impractical last evaluated expression, was suggested by Matt Trout to allow chaining. I'm not as gaga about having methods return themselves to allow chaining as some others are, but its quite tidy.

I hope more folks pile on and make simple things simpler. An especially fertile ground is the perlfaqs. Take any answer that involves cutting and pasting a bunch of code or loading a module and turn it into a method.

I think you're old enough now that your mother and I can talk to you about "bugs". See, sometimes software has "bugs", especially young software that is carefree about its features. That means it won't act the way you expect. Its because of the bug.

When you see a bug, tell someone about the bug. Replying to a blog post, even if it is by the author, doesn't really count. You have to report the bug to the proper authorities. http://github.com/schwern/perl5i/issues

(The answer to your question is "because my implementation is entirely too clever")

But everything about perl5i is entirely too clever! When I encounter unexpected behavior with entirely too clever things, I'm not at all confident that it's a bug. Maybe I'm just not clever enough to understand it. When I run

$ ruby -e 'puts 0 ? "true" : "false"'
true

I think, "Huh? That can't be right." But it turns out it is right. The Ruby people have some reason for wanting 0 to be true. I don't understand it. I'm not clever enough for Ruby.

Similarly, when I run

$ perl5i -e 'say "1.0"->is_integer ? "true" : "false"'
true

I think, "Huh? That can't be right." But I don't run off the bugs page. Maybe Schwern has some reason for wanting decimal whole number strings to be integers. It says right there it's tested. Surely, this would be one of the first five or ten tests written. I'm probably just not clever enough for perl5i.

I promise you, perl5i wants to hear from you. Its not a "bug tracker", its not even really an "issue tracker". Let's call it "negative feedback". Even if it was clearly documented and tested that 1.0->is_integer is true, perl5i would still want to hear your "WTF?!" report.

Apply some hubris and tell us how perl5i sucks! You say its entirely too clever, then tell us! In painful detail! We won't yell at you, I promise. Its the only way to get things fixed. Otherwise silence is interpreted as acceptance and you accept crappy software.