Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Re: $foo = "Foo::Bar"; $foo->new() works? (factories++)

by tye (Sage)
on Jan 23, 2005 at 11:40 UTC ( #424374=note: print w/replies, xml ) Need Help??

in reply to $foo = "Foo::Bar"; $foo->new() works?

A symbolic reference to a package is all there is so we can't disallow it. A symbolic reference to a variable is what use strict 'refs' disallows.

Now, I don't like symbolic references to packages much. I'd require (well, encourage anyway) that you mention the package once to load it and that process would give you a handle to the package that you use instead of repeating the package name all over the place.

Package names should be world-wide unique, which means they can get rather long. So I'd like to start my code more like:

use strict; my $Heap= require Data::Heap; my $Parser= require XML::Twig; my $q= require Net::CGI; my $Bank= require Finance::Banking::English::USA::CreditUnion::CA::Poi +ntMagu; ...

If such became well supported, then you could define a "package reference" like we defined "scalar reference", "hash reference", and the rest. Then require could default to returning this new type of non-symbolic reference and you could make using a symbolic reference optionally cause an error just like other symbolic references.

This would also solve a lot of complex problems. You could have multiple versions of the same package loaded at the same time quite easily. Modules wouldn't have to break if they were installed in the wrong place (a user could pick a non-default place to install a module and give the designation for that location to require and it would find the module file and load it and things would just work without having to change the module name declared inside the module etc.).

Well, solving those things becomes easy if you disallow symbolic references to packages like Perl disallows symbolic references to lexical variables. Rather, if you make it so that require is the only way to get a reference to a package.

This actually creates a few namespaces that are quite natural. Modules get the namespace by which they are normally referred such as "Algorithm::Diff" (no change from how things work today). When a module is loaded, it gets named by the path to the file that it was loaded from (this way you can have two different versions of one module that even have the same version number and yet they both can work fine in a single instance of the Perl interpreter at the same time). require takes "Algorithm::Diff" and uses the current scheme to transform that into a path name. But when it loads the code in that file, it gets loaded into a package specific to that path string not named by some 'package' statement in the file.

And the module code only states the base module name once for documentation purposes and the user of the module also only types in this name once.

I think that would be cool. (But having require return the factory for the module, even w/o all of the other features, would still be nice.)

- tye        

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://424374]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2022-12-06 00:47 GMT
Find Nodes?
    Voting Booth?

    No recent polls found