in reply to use, require, and constructors

Unfortunately, require will only return that value the first time you require the module, so you really shouldn't use this.

It would be nice if require and/or use would return a factory (by default, just the class name). It probably wouldn't be hard to fix require (patch Perl) since it nearly works already. And in the chatterbox Larry said that Perl6's use will return a factory (at least that was how I understood it).

In modern Perl, the closest I can come to this is initializing a factory variable. You'd use the OO module like:

use Disney::Animation::Animal::Mouse::WithGloves( \my $Mickey ); # ... my $logo= $Mickey->new( "Smiling" );

The OO module would have something like:

sub import { my( $us, $ref )= @_; $$ref= $us if ref($ref); }

Just as one example of how you could do it.

- tye        

Replies are listed 'Best First'.
Re^2: use, require, and constructors (factories++)
by ysth (Canon) on Oct 27, 2004 at 06:23 UTC
    It would be nice if require and/or use would return a factory (by default, just the class name).
    Problem with that is that other people are (ab)using require's return value for other things. Unless you just meant having require cache the true return value the first time and return it every time.

    If the module exports any subs, you can get the package name from them:

    $ cat Foo.pm package Foo; use strict; use warnings; use base "Exporter"; our @EXPORT = "bar"; sub bar { "baz" } 1; $ perl -we'use Foo; use B; print B::svref_2object(\&bar)->STASH->NAME' Foo
    (as long as the module didn't itself import the sub from elsewhere).

      If require were fixed to return the same value every time (caching the value from the first call), then I'd update all of my OO modules to end with __PACKAGE__; instead of 1; and document how to use that (if you are programming for a version of Perl where require has been fixed).

      Though my objects (like many Perl objects) very often have "user preference" type options that are best expressed once (in the use line) so I already provide a way for the module user to get a factory that can construct objects with the user's preferences already taken into account.

      An easy way to do this is to allow objects to be constructed from each other so my use lines typically let you list your preferences and where you'd like your master object to be stored. You can just use the one master object or you can use it as a factory (even though it is of the same class as the objects it will be creating).

      I'm amused that you appear to think I'd like to write

      B::svref_2object(\&function_exported_by_OO_module_of_which_there_shoul +d_not_be_any)->STASH->NAME->new( ... )

      in order to avoid typing the name of the module. :)

      - tye        

        I'm amused that you appear to think I'd like to write...
        I was hoping that would brighten your day :)