Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Use of Carp outside of package won't compile...

by memnoch (Scribe)
on Dec 18, 2007 at 16:12 UTC ( [id://657697]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks,

The following code does not compile:

use strict; use warnings; use Carp qw(croak); package Test; #use Carp qw(croak); sub croak_test { croak "this is a test"; } Test::croak_test;
and produces the following output:
String found where operator expected at croaktest.pl line 8, near "cro +ak "this is a test"" (Do you need to predeclare croak?) syntax error at croaktest.pl line 8, near "croak "this is a test"" croaktest.pl had compilation errors.
But if I put the "use Carp qw(croak);" statement after the package it does work:
use strict; use warnings; #use Carp qw(croak); package Test; use Carp qw(croak); sub croak_test { croak "this is a test"; } Test::croak_test;
I don't understand why the "use Carp qw(croak)" seemingly must be declared after the package, but the "use strict" doesn't. How could I determine what is necessary for other "use" statements?

If someone could offer some insight as to what I'm not understanding, I'd really appreciate it.

Thank you,
memnoch

Replies are listed 'Best First'.
Re: Use of Carp outside of package won't compile...
by Fletch (Bishop) on Dec 18, 2007 at 16:23 UTC

    strict is lexically scoped (so it's affecting the rest of the compilation unit from that line to the end); the import from the use is to the specific package that's currently active. If the use is before the package then the import is making main::croak an alias; when you move it it's made as Test::croak.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Use of Carp outside of package won't compile...
by ikegami (Patriarch) on Dec 18, 2007 at 16:43 UTC
    Perl has two scoping mechanisms. Lexical scopes and packages. The key differences between the two are:
    • There is only one current package.

      ... package Foo; ... package Bar; ...
    • The program can be in multiple lexical scopes at a time, as long as they are nested.

      { my $foo; { my $bar; ... } ... }
    • The lexical state is cleared when the lexical scope is exited.

      for (1..2) { my $x; # New variable each time. print($x); }
    • The package state is persistent.

      package Foo; use Carp qw( carp ); carp('One'); package Bar; ... package Foo; carp('Two');
    • Since the lexical state ceases to exist when exited, it cannot be referenced from the outside.

    • The package state can be referenced from the outside

      package Foo; use Carp qw( carp ); carp('One'); package Bar; Foo::carp('Two'); package Foo; carp('Three');

    The use directive itself doesn't know or care about scope. It's all about the code in the import function of the loaded .pm.

    use pragma; changes bits in a lexically-scoped compiler variable.
    use Module qw( function ); creates a function in the current package.

Re: Use of Carp outside of package won't compile...
by shmem (Chancellor) on Dec 18, 2007 at 16:38 UTC
    I don't understand why the "use Carp qw(croak)" seemingly must be declared after the package, but the "use strict" doesn't

    strict and warnings are lexically scoped pragmas. That means:

    • they are effect in the file or block in which they have been declared until the end of that file or block, even spanning packages
    • they are by themselves no package 1, but are included via use (and not via require), because their import() functions must be executed at compile time, since they contain compile time directives (but set bits for runtime context also)

    OTOH, use Carp imports a package and defines its exported functions in the namespace which imports the package.

    If you have imported a package once, you can refer to functions in that package from other packages also, but then those have to be fully qualified:

    use strict; use warnings; use Carp qw(croak); package Test; sub croak_test { Carp::croak "this is a test"; } package main; Test::croak_test;

    1) in the sense that they don't implement functions which are exported or methods callable via objects. - update: well, not quite. warnings actually has some usefull functions ;-)

    update:

    One way to make imported functions available to all packages in one file is storing those function's references in lexical scalars, and use those to call the functions:

    use strict; use warnings; use Carp qw(croak); my $croak = \&croak; package Test; sub croak_test { $croak->("this is a test"); } package main; Test::croak_test;

    Another way would be by assigning globs

    package Test; *Test::croak = \&main::croak;
    which essentially is what the import() function of an imported package does, for the symbols which are to import.

    But if the set of functions is imported into the default package (which is main::), they can also be qualified with leading :: only from different packages:

    # package main; is implicit here use strict; use warnings; use Carp qw(croak); package Test; sub croak_test { ::croak "this is a test"; } package main; Test::croak_test;

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Use of Carp outside of package won't compile...
by friedo (Prior) on Dec 18, 2007 at 16:24 UTC
    strict and Carp operate by somewhat different mechanisms. strict is scoped lexically, and so applies for the whole scope in which it is declared (in this case file scope), covering the subsequent package declaration. Carp works by exporting its functions to the calling namespace. In your example, Carp exports croak to the default package (main) but not to your Test package. When you change it to put the use Carp statement inside your package, then it works because croak gets exported to the Test namespace.
Re: Use of Carp outside of package won't compile...
by ikegami (Patriarch) on Dec 18, 2007 at 16:50 UTC
    Actually, the use strict pragma and the package statement are not that different.
    use strict; # strict is on. { no strict; # strict is off } # strict is on.
    package Foo; # Currently in package Foo. { package Bar; # Currently in package Bar. } # Currently in package Foo.

    You can't have two current packages at the same time, just like you can't have two strict states at the same time.

Re: Use of Carp outside of package won't compile...
by sundialsvc4 (Abbot) on Dec 18, 2007 at 16:46 UTC

    My dim understanding of the issue is that the package Test declaration introduces the “‘Package’ namespace.”   Prior to that point, the default package-name (which is main) was in effect.

    The qw() statement exposes these variables into the “then-current” namespace... which changed mid-stream.

    (Post edited as suggested by ikegami. Thx.)

      Erm, no. qw() is just a special form of quoting (see perlop on "Quote-like Operators") and has nothing to do with the exporting of subs. The calling of the loaded module's import method by use is what's making things visible in the current package name space, and it would work just the same had he said use Carp 'croak' or use Carp q/croak/. It's just convention to use some variant of qw// because it allows you to easily specify a list of names to be imported with one set of delimiters.</pedant>

      Update: Added link and remark on quote-like ops.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: Use of Carp outside of package won't compile...
by benizi (Hermit) on Dec 20, 2007 at 06:06 UTC

    How could I determine what is necessary for other "use" statements?

    As a general rule, pragmas start with lowercase letters while modules start with uppercase letters. The two are different, as well-explained in previous replies. But looking at the first letter usually tells you which you're dealing with. After a while, you'll get used to the convention. Perl doesn't enforce this, but it's standard, common, and good practice.

Re: Use of Carp outside of package won't compile...
by sfink (Deacon) on Dec 20, 2007 at 05:22 UTC
    The scoping of 'use Carp' and 'use strict' is the same. The problem was that your code didn't use the effects of 'use Carp'. The following compiles:
    use strict; use warnings; use Carp qw(croak); package Test; sub croak_test { Carp::croak "this is a test"; } Test::croak_test;
    You were calling Test::croak, which doesn't exist, so the parser sees no reason to accept an unparenthesized string constant after it.

    So use Carp qw(croak) must be declared after the 'package' only so that will create the function you're actually trying to call. It could go earlier, if you wish: you could insert

    { package Test; use Carp qw(croak); }
    at any point before the 'package', and it would create the correct subroutine and allow you to call it without parens. Heck, you could just put sub Test::croak; at any point in the file before the call to croak and it would be happy.

    (Well, if you don't define the function, it'll complain if you ever try to call Test::croak, but at least it'll compile.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://657697]
Approved by Corion
Front-paged by friedo
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-03-29 12:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found