Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

if only blocks were avoidable...

by yosefm (Friar)
on Sep 21, 2003 at 19:05 UTC ( #293020=perlquestion: print w/replies, xml ) Need Help??
yosefm has asked for the wisdom of the Perl Monks concerning the following question:

Or are they? I'm trying to write a module that uses only if it was requested in the import list, like - use module qw(LegacyEncoding and other options);

The problem is that if I use if, bytes will only be scoped to the if block. And anyway if I manage to avoid that (like with $legacy and use bytes) it will still be scped to the import sub.

Any way around it?

Replies are listed 'Best First'.
Re: if only blocks were avoidable...
by liz (Monsignor) on Sep 21, 2003 at 20:58 UTC
    The use bytes is basically setting $^H at compile time.

    According to that documentation, you should be able to do:

    BEGIN { require bytes; bytes->import if $condition }
    inside the block where you want the use bytes to be conditionally set. Of course, if you don't put it in a block, the file in which the source sits, will be your scope.

    This seems the right thing according to the docs and seems to work with stricture:

    $foo = $a; BEGIN { require strict; strict->import if 1 } $foo = $a; __END__ Variable "$foo" is not imported at x line 3. Global symbol "$foo" requires explicit package name at x line 3. x had compilation errors.
    If the import is not done, this runs without any errors:
    $foo = $a; BEGIN { require strict; strict->import if 0 } $foo = $a; __END__

    Hope this made sense and helps.


      OK, it turns out that this isn't what I need, because if I use BEGIN, I can't use parameters passed to sub in order to decide on the condition. I can only use environment variables, perl variables and other stuff that already exists before anything happens.

      What I need is this:

      sub import { $_[1] eq 'StoneAge' and use bytes globally; #no such thing. }

      BEGIN can't achieve that.

        Ok, I guess I missed that particular point. Well, I think it is possible, but it's rather yucky and it suffers from the same problems that AutoLoader and the likes have. Basically, you compile your code in a two step process. First to compile the "import" routine. Then, when the import routine is called, the rest of the source is compiled Consider module Foo:
        package Foo; require bytes; # make sure the module is loaded without (un)import $bytes = 0; # flag: whether bytes should be enforced $evalled = 0; # flag: whether rest of source has been compiled sub import { unless ($evalled++) { # we haven't evalled the rest +before $bytes = ($_[1] eq "usebytes"); # should bytes be enforced? local $/; # enable slurp mode eval <DATA>; # compile rest of source (afte +r __DATA__) die $@ if $@; # die now if an error occurred } }; 1; # in order for require of to be + successful __DATA__ # actual source of module starts here BEGIN {bytes->import if $bytes} # activate bytes if flag set sub new { bless {},shift } # example routine
        Then, in an example program, you would do:
        use Foo 'usebytes'; # or something else to not use bytes my $foo = Foo->new;
        Hope this will help you in your quest.


      So if I understand what you (and perlvar) say correctly, the BEGIN block is what's going to make my import globally scoped? If that's the case then I guess that's what I was looking for.
        No. Wrapping an import call in a BEGIN block will make it happen at compile time.
Re: if only blocks were avoidable...
by jeffa (Bishop) on Sep 21, 2003 at 20:22 UTC
    Not quite sure if i am following you, but have you tried require instead? The "problem" with use is that no matter where it is, the module will be loaded. Consider this:
    if (0) { use CGI qw(:standard); } print header,"\n";
    Which does load and no compile error happens because there really is a header() method available. Try using require instead.


    (the triplet paradiddle with high-hat)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://293020]
Approved by herveus
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (5)
As of 2017-08-19 21:59 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (312 votes). Check out past polls.