Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: How relevant is the order of 'use's ?

by Eily (Monsignor)
on Oct 20, 2016 at 12:55 UTC ( #1174356=note: print w/replies, xml ) Need Help??


in reply to How relevant is the order of 'use's ?

It seems to come from the way constant works.

use Data::Dump qw/pp/; use constant { C1 => 10 }; sub C2 { 20 } say pp $::{C1}; say pp $::{C2}; __DATA__ \10 *main::C2
So constants aren't actually just functions that are added to the symbols table, because instead of a glob there is a reference to the value.

The problem with your code is that your import function replaces the whole entry in the symbols table (everything in $::{SUCCESS} is replaced by $Demo2::{SUCCESS}), instead of just the CODE section of the glob. Somehow it seems that constant makes the reference to the constant's value and the glob coexist, but when you remove the glob manually from the symbols table, perl can't find the symbol SUCCESS anymore.

Funny thing is, if you just remove the line that prints the value of the constant SUCCESS, $SUCCESS gets printed, but with the constant's value. So with : use constant { SUCCESS => 5 }; in Demo2, the line print "\$SUCCESS: $SUCCESS\n"; prints "SUCCESS: 5".

Something like $main::{SUCCESS} = $Demo2::{SUCCESS}->*{CODE} (under use feature 'postderef') may work better. (Edit: no it doesn't, since $Demo2::{SUCCESS} is a ref to a scalar, not a glob...)

Replies are listed 'Best First'.
Re^2: How relevant is the order of 'use's ?
by Anonymous Monk on Oct 20, 2016 at 14:21 UTC

    That's not exactly what constant does, it does this:

    use Data::Dump qw/pp/; use constant { C1 => 10 }; sub C2 () { 20 } say pp $::{C1}; say pp $::{C2}; __END__ \10 \20

    The empty prototype allows for inlining. See Constant Functions.

      Oh right, I forgot the prototype! Thanks :).

Re^2: How relevant is the order of 'use's ?
by Krambambuli (Curate) on Oct 20, 2016 at 13:58 UTC
    yesss.... Your response, as well the previous one, gave the right direction.

    The defined import function is *not* OK. Replacing it with something closer to what Exporter does seems to solve the problem:
    package Demo2; sub import { #${[caller]->[0].'::'}{$_} = ${__PACKAGE__."::"}{$_} *{[caller]->[0].'::'.$_} = \&{__PACKAGE__."::$_"} foreach grep { not /^(ISA|isa|BEGIN|import|Dumper)$/ } keys %{__PACKAGE__."::"}; } use constant { SUCCESS => 0, }; 1;
    Now I just have to understand how come that it works :)

      Actually I think you can do even simpler/easier to read:

      use Exporter; use base qw/Exporter/; our %constants; BEGIN { push @ISA, 'EXPORTER'; %constants = (SUCCESS => 1); @EXPORT = map "&$_", keys %constants; } use constant \%constants;
      Since I guess your goal is to export all the constants in Demo2 without having to provide the list of names twice. And with the & appended to each name, there's no risk of overwriting $SUCCESS;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1174356]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2023-02-04 08:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer not to run the latest version of Perl because:







    Results (31 votes). Check out past polls.

    Notices?