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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |