Would you shoot me for this?

Ovid on 2005-01-04T21:20:14

I was going to release a module named "Aliased" which would alias long class names to short ones. However, it's only for OO modules , it sort of alters compile-time behavior so one might think of it as a pragma, and "class" is not a keyword. Thus, I could do this:

use class 'My::Company::Namespace::Customer';
use class 'My::Company::Namespace::Preferred::Customer', as => 'Preferred';

my $cust = Customer->new;
my $pref = Preferred->new;

My immediate reaction was "no!", we don't want to do that. Then I realized I couldn't think of a reason why. Can you? I certainly don't want to release that and make people mad (though Theory pointed out that "class" doesn't indicate that anything's getting exported to the current namespace).

Side note: the "as" key in the import list is important because there's a separate "import" key in case you need to pass args to the module's import() method.


Like It

Smylers on 2005-01-04T21:51:40

That's an excellent idea! Now when people submitting requests to modules@perl.org complain that they want their pet module to have a short name cos it saves typing in their programs (at the expense of being meaningful in the global hierarchy) this can provide a solution.

It's also handy when a module changes its name — just change the use line, and leave other references to the class alone.

Smylers

Re:Like It

jk2addict on 2005-01-04T22:00:36

I know I'll get biatch slapped for saying this; and it's not meant as a flame; but...

Isn't submitting namespace requests to modules@ worthless now a days? Isn't there an overall push/acceptance to abandon maintanence of "registered' modules and the modules list @ http://www.cpan.org/modules/00modlist.long.html?

http://www.perldiscuss.com/article.php?id=2803&group=perl.module-authors http://www.mail-archive.com/module-authors@perl.org/msg01752.html

Re:Like It

Smylers on 2005-01-04T22:19:01

Isn't submitting namespace requests to modules@ worthless now a days?

From the the point of view of having an official list of registered modules, quite possibly. But the process definitely is useful in moderating modules' names.

brian d foy in particular is good at spotting when a module has been submitted with an awkward name and suggesting a better one, and in general the suggestions are acted upon. That makes Cpan a more pleasant place for all of us.

Smylers

Perl or Java?

ziggy on 2005-01-04T22:30:51

On the one hand, good job. You should beat your programming language until it fits your domain.

On the other hand, it's Java all over again. Every time I look at a Java program, I see statements like import java.io.* and the like. A few lines later, I see references to classes I've never seen before from one package or another, and I don't know where to go when I'm looking up methods on some interface like XMLReader or some class like HashMap. Because the package prefixes are stripped, I've lost all context as to what's what. I wouldn't have such a severe reaction if I programmed in Java all the time, but that's like saying the way to stop making your head hurt is to keep banging it until you can't feel the pain.

This pattern is not an absolute good or bad thing. You can't get anything done in Java without using dozens of classes from at least half a dozen packages, so figuring out which class belongs in which package just by reading the source code is more difficult than it should be. So maybe the pattern isn't bad, maybe it just turns sour in Java where you can't get up to stretch your legs without touching 7 interfaces and 15 classes from some or all of the packages you've imported.

So just keep that in mind. If your code is using two or three classes that are all explicitly aliased, it's probably a good thing. But keep the counter example of Java in your mind, so you don't repeat that pattern-gone-awry.

Re:Perl or Java?

Ovid on 2005-01-04T23:11:48

This is somewhat different from the Java model (I had considered implementing that but I abandoned the idea as causing more problems than it solved). Java is frustrating because, as you point out, you can silently bring in tons of namespaces and not know their origin. However, class.pm does this one module at a time. You can always glance at the code at the top of the package to see where the package comes from.

How would it work?

phillup on 2005-01-05T00:49:17

use class 'My::Company::Namespace::Customer';
use class 'My::Company::Namespace::Preferred::Customer', as => 'Preferred';
 
my $cust = Customer->new;
my $pref = Preferred->new;
So... what would it do if you had not used 'as => 'Preferred' in the second instance?

It looks like it is "aliasing" the module name (the last part) but that is the same as the previous module... so would it re-alias Customer?

And... does it alias all modules that are used after calling it? I think I'd really, really hate that part... I'd want to be able to say "only alias what I tell you to alias".

Kinda ugly (just thrown out as a starting block) but how about:
use class ('My::Company::Namespace::Preferred::Customer', as => 'Preferred');
or even:
use class;
my $alias = new class;
$alias->add('My::Company::Namespace::Preferred::Customer', 'Preferred');
 
... later (if desired/needed)...
 
$alias->remove('My::Company::Namespace::Preferred::Custome r');
Just some thoughts... (and I have no idea where the space before the 'r' in customer is coming from)

Re:How would it work?

Ovid on 2005-01-05T01:16:07

It only aliases what you tell it to alias, so no worries there. Also, the entire point of this is to keep things really, really simple. Dirt simple. Making it all OO defeats that. All this module really does (mostly) is to use the package in question and then insert a sub into your namespace that returns the name of the module.

perl 6

wickline on 2005-01-05T05:34:12

You might want to avoid using class so that if/when someone writes (or maybe someone has already written) a Perl6:: module that supports class as a keyword folks won't be inviting confusion by trying to use both that module and yours.

Obviously "don't use that name, because someone else might" could be said of any name, but I think a potentially very popular name like 'class' might be worth extra caution.

Then again, if you call it 'class', someone who hates the name can write a thin wrapper calling it whatever they want instead.
/me shrugs

-matt

Re:perl 6

Ovid on 2005-01-05T05:39:46

Hi Matt. I'm going to call it "aka.pm" because it's short and that's a name that received fairly decent support on the module author's list. I was also hesitant about the Perl 6 issue, oddly enough. I'll probably have it uploaded in the next day or two unless there's some strenous objection from the PAUSE admins.

please, no

perrin on 2005-01-05T05:49:25

Sorry Ovid, but this is an abomination. It kind of sums up many of the problems with Perl culture: obsession with syntax over utility, willful use of obscure features like using the import list for other things, and a desire to make everything REALLY short. Give the module a normal name, call the alias method like a normal method, and give intermediate perl programmers a chance in hell of understanding your code. Otherwise, it belongs in Acme::.

Re:please, no

Ovid on 2005-01-05T06:04:45

I fear that you are in the minority. Though many have objected to the name -- leading me to change it -- you're the only person who has objected to the idea of the module.

The inspiration for this code was a module named "Aliased" that Rentrak uses extensively in their code. (They have graciously allowed me to duplicate the functionality of the code.) The reason I mention this is because while the code is new, the interface is not and it has withstood the test of time for very large scale systems (enterprise-class, if you can forgive the buzzword.)

The programmers who work there will all quite happily tell you that this is a module they can't live without. Given how very useful it has proven to be I want it for my own projects. I'd be more hesitant if I didn't know how popular it is with the programmers who have used it. Maybe this is one of those "it sounds weird but it really works" ideas? (Dynamic typing being another example :)

Re:please, no

perrin on 2005-01-05T06:23:50

I think you're misunderstanding me. I don't object to the module, only to the interface. I think it should have a simple interface with no obscure import() subversion and no pragma-like class names. The concept of aliasing is clear enough -- it's that API you came up with that I don't like.

Re:please, yes

Ovid on 2005-01-05T06:43:39

Yes, I did misunderstand you. However, even though there are a couple of people who objected to the interface, I fear you're still in the minority. As I mentioned previously, I and a number of other programmers have been using a virtually identical interface for so long without any problems (and with strong benefits) that I'm still quite comfortable with the interface.

You are someone who I generally pay extra attention to given my respect for your abilities. In this case, I must disagree due to extensive personal experience.

Re:please, no

ziggy on 2005-01-05T16:44:33

I was going to post a flame about how the whole point of programming language design is to obsess over syntax in the name of achieving greater utility. That's what gave us idioms like 'open or die' and foreach loops over hand-compiling tail recursive forms.

But I see that your clarification, and yes, the abuse of the import list is quite horrid.

Perl is a dynamic language. There's no reason why the magic fiddling must happen at compile time, nor is there any reason why it the aliasing must use a use statement to fire. This sketch should work, work clearly, work properly and not be overly abusive to perl:

use MyCorp::MyApp::Customer qw(...);
use MyCorp::MyApp::Preferred::Customer qw(...);

use PackageAlias qw(make_alias);
make_alias(MyCorp::MyApp::Customer            => "Customer");
make_alias(MyCorp::MyApp::Preferred::Customer => "Preferred");

my $cust = new Customer;
my $pref = new Preferred;
Thoughts?

Re:please, no

Ovid on 2005-01-05T17:30:54

Well, my thought is pretty straight-forward: the current code I have implemented not only works, it fits very naturally with current Perl syntax. I can't say that I like the syntax of how I handled importing, but that's not the common case. The important thing is that the common case be handled easily. The more programming people do, the more they want the common things to be short-n-sweet.

My code is ready to be uploaded and I'm merely waiting for last minute objections from the modules@cpan.org list. If you can make a convincing argument why my solution is more abusive and how your solution is better, I'm willing to hear it. However, just saying that my abusing importing is a bad thing doesn't mean that it's a bad thing (no offense.) And just to give you a fair shot at making your case, here's the code I wrote:

package aka;
$VERSION = '0.1';

use strict;

sub import {
    my ($class, $package, %properties) = @_;
    require Carp && Carp::croak("You must supply a package name to aka")
        unless defined $package;
    my $alias  = $properties{as} || _get_aka($package);
    my @import;
    if (exists $properties{import}) {
        my $import = $properties{import};
        $import = [$import] unless 'ARRAY' eq ref $import;
        @import = @$import;
    }
    unshift @import => $package;
    my $callpack = caller(0);
    {
        local $SIG{'__DIE__'};
        eval "package $callpack; require $package; sub $alias { '$package' }";
        die $@ if $@;
    }
    my $import_method = UNIVERSAL::can($package, 'import');
    @_ = @import;
    goto $import_method if $import_method;
}

sub _get_aka {
    my $package = shift;
    $package    =~ s/.*(?:::|')//;
    return $package;
}

1;

The only reservation I have is about my use of UNIVERSAL::can. It's possible that a package (or a subclass prior to UNIVERSAL) has implemented its own &can method, but I think this is so obscure a case that I'm not too worried about it. On the other hand, I did allow for single quote marks in package names :)

Re:please, no

chromatic on 2005-01-05T18:33:55

The only reservation I have is about my use of UNIVERSAL::can.

As well you should. The right code is even shorter and clearer.

Re:please, no

Ovid on 2005-01-05T18:42:08

Silly me. For some stupid reason I thought I shouldn't use $package->can('import') because there's no guarantee that there's an import method. Mentally I thought "there's no guarantee that package can('can') and that might throw an error." It's weird how muddled my mind substituted "can" for "import" in that method call :/

Re:please, no

perrin on 2005-01-05T18:24:01

I like that API much better. My beef with the original API is that it uses pragma-like names and a non-obvious use of import (which is unfortunately catching on because of Test::More), and all for the sake of syntax rather than added functionality. To me, it looks like a disregard for the larger effects on the community, i.e. if everyone did crazy stuff like this to get a particular syntax for their modules, CPAN would be a total disaster. I have also seen this kind of thing get people into trouble, as in the dangerous try/catch syntax of the otherwise useful Error.pm module.

The need to learn lots of little syntaxes is the kind of thing that people complain about when they are trying to pick up Perl after knowing another language. I think it should be avoided when possible.

Good idea, bad name

schwern on 2005-01-05T08:41:26

Like the idea. The name not so good. Two objections. One: there's got to be a better use for class.pm. Two: it doesn't say anything about the aliasing/shortening aspect of the module. If I was to guess what class.pm was I would guess it was something for writing a class.

Don't see the point.

Aristotle on 2005-01-05T13:23:30

Why does this need an entire module?

use constant Customer => 'My::Company::Namespace::Customer';
use constant Preferred => 'My::Company::Namespace::Preferred::Customer';

my $cust = Customer->new;
my $pref = Preferred->new;

I've used this… not-even-a-trick on several occasions, FWIW.

Note how it makes no difference in the actual code, just makes effective use of what's already in the core. (And you could even do without constant.pm using prototyped subs, but that is too opaque for my taste.)