Domanda

Currently, during debugging, I tend to insert

carp Dumper \@foo, \%bar;

statements into my code, and regularly run into the problem that Carp and Data::Dumper are not imported in the current package. To avoid this problem, I defined the following sub in a central file that's always included:

sub main::bla {
    use Carp; use Data::Dumper;
    carp Dumper @_;
}

So now I can do

main::bla \@foo, \%bar;

everywhere, but the main:: annoys me. Is there something like a global package that's always imported, in any package, automatically (just like built-ins practically are imported everywhere)?

È stato utile?

Soluzione

You could just call it

::bla( \@foo, \%bar );

In earlier days, I used to put util functions in a Ut package. And that was fine, but I noticed that my code wasn't really as modular as I thought of it. Each module that depended on Ut functions being there could only succeed if somebody took the trouble to build that namespace.

In the end, I considered use and require statements as simply documenting dependencies. There are more flexible ways to change what code is called by library modules, rather than changing their implementation in main.

For example, you could do this in a single use statement.

use Ut blah => sub { 
    use Carp; 
    use Data::Dumper;
    carp Dumper @_;
};

And define the import:

sub import { 
    shift; # It's just me
    my ( $name, $impl ) = @_;
    if ( $name eq 'blah' && ref( $impl ) eq 'CODE' ) { 
        *blah = $_[1];
    }
    ...
}

I still use the ut pattern, when I'm developing a lot of code at once. But I don't mind writing

ut:dump_var( $var )

as opposed to saving 3-4 characters (because sometimes I call it U::).

Now, it appears that you don't want to do this long term, and dumping out your variables is a useful thing for development. If you really want to do this, Smart::Comments does it like so:

### @foo
### %bar

All it takes is one use statement.

use Smart::Comments;

Altri suggerimenti

Maybe just better to make another Package with Export and needed things? Like, MyTest.pm:

package MyTest;

use strict;
use Carp;
use Data::Dumper;


use base qw( Exporter );
our @EXPORT = qw(
    debug
)

sub debug {
    carp Dumper @_;
}

1;

So you can then just write in your script:

use MyTest;

debug {a => 'b', c => 'd' }

Fun fact: Some symbols are magic in that they always refer to their values in the main package. You can assign subroutines to these symbols that and they will be visible in any package.

{
    package Foo;

    # special names _ ARGV ARGVOUT ENV INC SIG STDERR STDIN STDOUT
    sub ENV { print "In main::ENV ...\n" }
    sub STDIN { print "In main::STDIN ...\n" }
    sub _ { print "In main::_\n" }

    # names that begin with ^ + upper case letter, or all digits
    *{^T} = sub { scalar localtime };
    *{^Gmtime} = sub { scalar gmtime };
    *43 = sub { 42 };

    use Data::Dumper;
    *{^D} = \&Data::Dumper::Dumper;
}

{
    package Bar;
    &ENV;


    STDIN();
    print "The time is ", &^T, "\n";
    print "In London it is ", &{^Gmtime}, "\n";
    print "The answer is ", &43, "\n";

    print "\@foo is ", &^D( \@foo );
}

None of this is recommended, unless you want to drive the next person who maintains your code insane.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top