DreamT has asked for the wisdom of the Perl Monks concerning the following question:

Hi! Is it possible to get a listing of the files/modules that has been required earlier in a script? EDIT: Thank ypu for the great answers, and the discussions surrounding them:)

Replies are listed 'Best First'.
Re: Can I see "requires"?
by Eliya (Vicar) on Mar 08, 2012 at 11:01 UTC

    Yes, check the %INC hash.  Its values hold the full paths, and its keys are the module names (with / instead of ::, and including .pm).

Re: Can I see "requires"?
by BrowserUk (Patriarch) on Mar 08, 2012 at 11:05 UTC

    If you take a copy of %INC at some point early in the program, and then later compare it to the then current value of %INC, it will tell you what has been added in the interim. It won't just contain what your code directly required, but also anything that they in turn used or required:

    C:\test>p1 %i = %INC;; require HTTP::Daemon;; exists $INC{$_} and not exists $i{$_} and print "$_ added" for keys %I +NC;; IO/Handle.pm added HTTP/Status.pm added SelectSaver.pm added Time/Local.pm added IO/Socket.pm added Fcntl.pm added Symbol.pm added HTTP/Date.pm added URI.pm added IO/Socket/INET.pm added C:/Perl64/lib/auto/Storable/autosplit.ix added Errno.pm added File/Spec.pm added HTTP/Response.pm added File/Spec/Win32.pm added LWP/MediaTypes.pm added IO/Seekable.pm added integer.pm added IO/Socket/UNIX.pm added IO.pm added HTTP/Daemon.pm added HTTP/Message.pm added File/Spec/Unix.pm added FileHandle.pm added HTTP/Request.pm added Socket.pm added IO/File.pm added URI/Escape.pm added HTTP/Headers.pm added Storable.pm added

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      exists $INC{$_} and not exists $i{$_} and print "$_ added" for keys %I +NC;;

      You know that $INC{$_} exists because you just accessed it from keys %INC!!    Did you think that it got deleted somehow?

      exists $i{ $_ } or print "$_ added" for keys %INC;

        Good point!

        A literal translation of the thought: If it's now in %INC and not in %i, it was added.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

Re: Can I see "requires"?
by rovf (Priest) on Mar 08, 2012 at 11:03 UTC

    Have a look at

    keys %INC
    It does not exactly the way you write module names (because you get relative pathnames, not module names), but maybe it's close enough to what you need...

    -- 
    Ronald Fischer <ynnor@mm.st>
Re: Can I see "requires"?
by tobyink (Canon) on Mar 08, 2012 at 15:47 UTC

    As others have already said, %INC.

    However, note that it's quite possible to directly manipulate this hash:

    use 5.010; # Trick perl into thinking that Moose.pm has # already been required. $INC{'Moose.pm'} = '/tmp/Moose.pm'; # Require it for real. But perl does nothing! require Moose; # Perl thinks Moose is loaded. say "Moose is loaded" if $INC{'Moose.pm'}; # But it isn't really, so we don't know VERSION. say 'Moose version:', Moose->VERSION;

    I have in the past had cause to directly manipulate %INC. A module I was using wanted to be passed the name of plugin module to use. It would require that plugin and then use it. However, I wanted to define the plugin inline in my code, a la

    { package My::Plugin; ... } Something::That::Uses::Plugins->load_plugin('My::Plugin');

    But this caused Something::That::Uses::Plugins to attempt to require the non-existent file "My/Plugin.pm". So...

    { package My::Plugin; ... $INC{'My/Plugin.pm'} = __FILE__; } Something::That::Uses::Plugins->load_plugin('My::Plugin');

    And everybody's happy.

    But anyway, my point is that although %INC should give you the information you want, it can't necessarily be trusted 100%.

      A similar trick can be used to make sure code that uses use warnings works under pre-5.6 as well:
      BEGIN { if ($] < 5.006) { $INC{'warnings.pm'} = __FILE__; no strict 'refs'; *{'warnings::unimport'} = sub {0}; } }
      Of course, no warnings will be enabled when run under pre-5.6, but the code will not croak on a use warnings;
Re: Can I see "requires"?
by chromatic (Archbishop) on Mar 08, 2012 at 18:44 UTC
Re: Can I see "requires"?
by Khen1950fx (Canon) on Mar 08, 2012 at 23:27 UTC
    I would do it like this. I used "push" to add to the initial array, and I also used UNIVERSAL::require to avoid using eval.
    #!/usr/bin/perl -sl use strict; use warnings; require UNIVERSAL::require; my(@modules) = qw/Test::More Test::HasVersion/; my $module = $modules[0]; $module->require or die $@; print $module; $module = $modules[1]; $module->require or die $@; print $module; push(@modules, 'Test::Simple'); $module = $modules[2]; $module->require or die $@; print $module;
    Do this each time you require. Later in the script, you can see what you required by simply calling
    print @modules;