I saw TheDamian's Sufficiently Advanced Technologies presentation tonight in New York, which emphasizes minimizing interfaces. It got me thinking about one of the little annoyances I type over and over again: new. Maybe it would be nice to have an implicit constructor that just relies on the class name itself.

What I do now:

use Some::Class; my $obj = Some::Class->new( \%options );

What I want

use Some::Other::Class; my $obj = Some::Other::Class( \%options );

I've got a thrown-together version of this working and I'm looking for suggestions on a distribution name for CPAN as well as feedback as to whether this seems useful or is too off-the-wall to bother with at all.

The module is tentatively titled Classname::Constructor. It's used like this:

package Some::Other::Class; use Classname::Constructor; sub new { # whatever }

In this case, behind the scenes during import, it just installs a closure function Class() to the Some::Other namespace like this:

sub import { my $caller = caller(0); $caller = "::$caller" if $caller !~ m{::}; no strict 'refs'; *{$caller} = sub { unshift @_, $caller; goto &{"$caller\::new"} }; }

As a feature, if the class name is just a single word, it installs that as a function to the main package, and it's called like this:

package Wherever; use OneWordClass; my $obj = ::OneWordClass( \%options );

Obviously, this approach has issues if the last part of the package name collides with a function name in the parent package namespace, but that may be a limitation people are willing to accept or work around.

So what do you think? Useful? Nuts? Do you have name suggestions? (Acme?)

Your thoughts are greatly appreciated.

Update:

Ouch! As grinder points out, meryln has been there before and the sticky point is that this breaks class methods without some complicated workarounds. (Mental note: reread perlop on precedence of ->.) The version I show above also happens to break inheritance, but that's easy to fix.

Perhaps an alternative might be to export a function that resembles the class name, replacing "::" with "_". That avoids all but the strangest potential collison, and doesn't interfere with normal class methods.

use Some::Other::Class; my $obj = Some_Other_Class( \%options );

For those who prefer a constructor other than new, that could be supported with a parameter during "use".

use Classname::Constructor 'create';

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.


In reply to Getting rid of "new" by xdg

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.