in reply to Cheaper - Debug,Log,Errors via Slicing&dicing

I'm not convinced your endeavour is worthwhile, but I did find a problem.

Assuming it works at all, unslice executes too late in

unslice 'SomeModule'; use SomeModule;

It needs to be

BEGIN { unslice 'SomeModule'; } use SomeModule;

A better syntax might be

no slice 'SomeModule'; use SomeModule;

Further more, your slice isn't constant. You might as well remove the prototype. Using the () prototype is not enough to make a constant. The body of the function must also be constant. From perlsub:

Functions with a prototype of () are potential candidates for inlining. If the result after optimization and constant folding is either a constant or a lexically-scoped scalar which has no other references, then it will be used in place of function calls made without &.

Replies are listed 'Best First'.
Re^2: Cheaper - Debug,Log,Errors via Slicing&dicing
by rootcho (Pilgrim) on Jul 26, 2007 at 22:00 UTC
    right, I wasn't sure unslice() is working as expected..
    I agree that this syntax is better :
    no slice 'SomeModule';
    Does this mean I have to implement module called 'slice' and then implement the unimport method. Is that what you meant ? I haven't done 'no'-module !

    >>Further more, your slice isn't constant.
    That's right, that was my idea. When I don't want to do debugging it is defined as constant, so it is inlined and pruned.
    But when I need to debug it is a full blown sub. i.e. if I have the following code :
    use Slicer; use constant slice => 0;
    The constant will override the Slicer.pm definition, so no code will be executed.At least this is my understanding how it works and it seems to work.

    In short to be inlined it has to be constant/sub-constant. To be able to override a constant I need a sub with prototype (), so that I can use the same name.
    And finally to be able to call such sub() with many parameters I have to call it like this &mysub($p1,$p2)
    Is my reasoning correct or there is a hole in it ;)

      Does this mean I have to implement module called 'slice' and then implement the unimport method. Is that what you meant ? I haven't done 'no'-module !

      I meant no Slicer 'SomeModule';, so you would create an unimport function instead of of unslice.

      The constant will override the Slicer.pm definition

      It will do that even if slice has no prototype. I notice you get a warning when you override, and two if there's a prototype mismatch, so may I suggest

      use if $ENV{SLICE}, 'Slicer'; use if !$ENV{SLICE}, 'constant', slice => 0;

      or better yet, move that logic into Slicer:

      package Slicer; use base Exporter; our @EXPORT = qw( slice ); sub _slice { my @caller = caller; print $caller[0]; print ":: sliced :" , @_; return 1; } if ($ENV{SLICE}) { *slice = \&_slice; } else { require constant; import constant slice => 0; } 1;

      Update: Nevermind, still doesn't work for slice(...). You really should use two functions instead of requiring people to use &.

      package Slicer; use base Exporter; our @EXPORT = qw( slice sliced ); use constant slice => $ENV{SLICE}; sub sliced { return unless slice; my @caller = caller; print $caller[0]; print ":: sliced :" , @_; } 1;
      >set SLICE= >perl -wle"use Slicer; print('!') if slice; >perl -wle"use Slicer; sliced('!'); >set SLICE=1 >perl -wle"use Slicer; print('!') if slice; ! >perl -wle"use Slicer; sliced('!'); main:: sliced :!