Aliasing Short Names for Constructors

If you work on a large project, your code probably has a top-level namespace. If it's a large project, you probably have several secondary namespaces. I have seen this pattern time and again where you end up with:

  • MyProject
    • ::Controller
    • ::Model
    • ::Report
    • ::Role
    • ::Template
    • ::Utility

... and you get the idea. It's a little tedious typing out the full path to all of those modules when it's easy to assume what they are. Hold that thought for a moment.

One of the few things I like in Python better than Perl is that you create an object by calling a constructor function. In other words, if you have an IceCreamStore class, you get an object by writing store = IceCreamStore( ... );. I don't like it because it's obvious (Perl wins there) but I like it because it's shorter. (The other thing in Python I like better than Perl is built in support for iterators.)

You can get a lot closer in Perl using aliased, but it doesn't give you constructor functions. Hold that thought.

One of the drawbacks of the Python "a class is just a hash table of attributes and functionsmethods" design that Perl borrowed is that any function imported into a class's namespace(to make your code shorter) might be available as a method on objects of that class. Fortunately, you can use something like namespace::autoclean in Perl to unimport imported symbols after they've done their job. This works because, once Perl's parser has seen a function, the optree it builds refers to the proper function's storage location and the function's name association in the namespace can go away without changing the optree at all. Hold that thought.

While I was walking the dogs tonight, I figured out how to combine all of these things. This demo code works:

package MyDemo;

use classalias Class => qw( Foo Bar Baz );

sub get_all {
    return Foo(), Bar(), Baz();
}

1;

... and you can call it with:

#!/usr/bin/env perl

use Modern::Perl;

use MyDemo;

say $_->number for MyDemo::get_all;
say MyDemo::Foo();

Yes, the names are silly and bad, but look at what the code does. MyDemo uses three other modules, Class::Foo, Class::Bar, and Class::Baz. Within MyDemo it can construct new instances of each of those classes by calling functions named Foo(), Bar(), and Baz().

Outside of MyDemo, those functions do not exist.

The code is a little fragile because it's merely a proof of concept, but I'll post it in a few days.

Would I use this? Maybe. It needs more thought, but it only took a few minutes to write, which is a small investment for something that could save me lots of time in the future.

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

sponsored by the How to Make a Smoothie guide

Categories

Pages

About this Entry

This page contains a single entry by chromatic published on September 14, 2013 7:15 PM.

Why You Should Write Programs to Write Programs to Write Programs For You was the previous entry in this blog.

Functions Shouldn't be Methods, Yet Another Reminder is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.


Powered by the Perl programming language

what is programming?