in reply to Re: Re: if only blocks were avoidable...
in thread if only blocks were avoidable...

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 Foo.pm 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.

Liz

Replies are listed 'Best First'.
Re: Re: Re: Re: if only blocks were avoidable...
by yosefm (Friar) on Sep 22, 2003 at 15:30 UTC
    Yes, that's exactly what I need. And it also shows a very interesting feature of perl - I never thought about evaling <DATA>, so ++. Also I always think of eval BLOCK while there's also an eval EXPR that I always forget.
    Thanks.

      Note that a single script can't safely use your module twice. This means that any modules that try to use your module can't be safely used with any other such modules. I don't know what your module does, but it seems quite unfortunate to me.

      I'd probably have three packages. Here is a simplistic example:

      package Your::Module::Bytes; use bytes; do $INC{"Your/Module.pm"} . ".pl"; 1;
      and
      package Your::Module::Unicode; no bytes; do $INC{"Your/Module.pm"} . ".pl"; 1;
      and
      package Your::Module; sub import { # require the desired submodule # dispatch import to that submodule }

      Note, I'd have to test to make sure that 'use bytes' affects the code included via do, but I believe that it does.

      I'm also a bit curious what particular effect of 'use bytes' you need. I thought that such was mostly of use for the earliest versions of Perl Unicode support.

                      - tye
        I see the problem here, but if I understand your code correctly then I'll have to dispatch every subroutine call to the right module. The problem here is that my module is that import is not the only method called on this module, since it is an object, so import is only used as a class initializer.

        Oh, maybe I'll just start every subroutine with a conditional bytes->import. Not lazy enough, I know, but it seems that Laziness doesn't get me much here.

        As for what it does, this module creates a multy-level Javascript menu (I'm sure there are some available on CPAN but I didn't find quite what I need and anyway DIY is more fun).

        The reason I need 'use bytes' is for documents printed in legacy encodings. It turns out that perl spontaneously converts strings to unicode when some internal functions are used and then you get garbage in the browser. So I want to allow the user of my module to state that he uses legacy encoding and deal with it properly.