in reply to DWIM: autoloading classes

If you are not exporting, why not create a file Foo.pm
package Foo; use Foo::Dates; use Foo::Customer; use Foo::Order; use Foo::Company; use Foo::Company::SalesReps; use Foo::Extremely::Long::Package::Name;

and use use Foo.

And if you want to take care of exporting, you could do something like (untested):

package Foo; use Foo::Dates (); use Foo::Customer (); use Foo::Order (); use Foo::Company (); use Foo::Company::SalesReps (); use Foo::Extremely::Long::Package::Name (); sub import { Foo::Dates -> export_to_level (2, @_); Foo::Customer -> export_to_level (2, @_); Foo::Order -> export_to_level (2, @_); ... }

Abigail

Replies are listed 'Best First'.
Re: Re: DWIM: autoloading classes
by Ovid (Cardinal) on Sep 17, 2003 at 02:47 UTC

    I can see from my original node that I (once again) was not terribly clear. The intent of this idea was to ensure that I had a general purpose module that I could point to any namespace and it would recursively travel through the directories (via File::Find or File::Find::Rule) and prepare those subroutines as I outlined above. Thus, I wouldn't have to change code in any of the classes found.

    Further, by just adopting the syntax you listed in Re: The costs of packages, I think I might get exporting to work, also. What follows is a mish-mash of pseudo-code and Perl:

    package Class::WhenNeeded; use File::Find; sub import { my ($class, $top_package, $no_top_level) = @_; my @dirs = map { find_top_level_dir($_, $top_package) } @INC; foreach my $dir (@dirs) { find({ wanted => \&create_package_sub($no_top_level), preprocess => \&perl_packages, }, $dir); } } sub create_package_sub { my $strip_top_level = shift; my $module = make_module_name($File::Find::name, $strip_top_ +level); my $call_pack = (caller(1))[1]; if (defined &{$module}) { require Carp; Carp::croak "Function $module already defined"; } *{$module} = sub { undef *{$module}; eval <<" END_EVAL"; package $call_pack; use $module; # export goes to calling package? END_EVAL if ($@) { require Carp; Carp::croak "Could not load module: $module"; } return $module; } }

    Hopefully that clears things up.

    Cheers,
    Ovid

    New address of my CGI Course.

      Your aiming at a somewhat different goal to me, in that my package don't exist as files and only come into being when they are used, but I really like where your going too.

      I'm not sure if it fits with your intent, but I really like the idea of

      use WhenNeeded qw[ HTTP::* HTML::* ]; my $headers = new HTTP::Headers; ... my $request = new HTTP::Request; ... my $content = decode( $content );

      But maybe that syntax is just too Javan :)


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.

        But maybe that syntax is just too Javan :)

        Is that a problem? I would love to use WhenNeeded if I could, although it might be a bit tough to implement.

        That is an interesting idea, but fair warning: my tests reveal that "WhenNeeded" would break indirect object syntax. I can't think of any way around that without breaking more than I would fix.

        Cheers,
        Ovid

        New address of my CGI Course.