http://qs321.pair.com?node_id=281482


in reply to Clipboard transform keys

Nice polyglot. It's extra-defensive. In the way of explanation, since not all Windows command scripts are so complicated,
@rem = '--*-Perl-*-- @echo off perl -x -S "%~dpnx0" %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl @rem '; #!perl #line 8 YOUR PERL CODE HERE; __END__ :endofperl
This can be run as a Windows command file itself, or as a Perl script directly, and the syntax hacks are designed to fool both interpreters into ignoring the parts intended for the other.

In perl, lines 1..5 are @rem = '...'; and the resulting array is otherwise ignored. In Windows script, that's five separate commands: (1) an unechoed remark @rem, (2) an unechoed command to turn off further automatic echoes @echo off, (3) an invocation of perl on the script itself with its first nine arguments, (4) a command to skip any other lines until one matching /^:endofperl/, and another unechoed remark @rem. The first line, as a bonus, suggests the file should be edited in perl-mode for some smart editors.

The perl -x tells perl to skip anything ahead of the shebang line matching /^\#\!/. This is only seen when the command script invokes Perl. It shouldn't be necessary since the @rem=''; trick should armor these lines, but it's defensive. The odd "%~dpnx0" reconstructs the %0 variable explicitly with all possible components: drive, path, name, extension.

The #line 8 trick aligns perl's error-reporting features with the actual polyglot script's lines. Otherwise, any errors would be reported, thanks to the perl -x as numbered relative to the shebang line.

Of course, perl quits reading at the __END__ token, so anything following is ignored by perl, but the last line is the aforementioned target for the command script's goto endofperl command.

--
[ e d @ h a l l e y . c c ]

Replies are listed 'Best First'.
Re^2: Clipboard transform keys
by PhilHibbs (Hermit) on Aug 19, 2003 at 18:04 UTC
    I wasn't sure what the -S and -x did, they were there in the original that I nicked (runperl.bat from the ActiveState install). You don't mention is what the -S does, which I've now looked up - it tells perl to search the path. I've removed it because I actually don't want that happening.
      Why do you need that batchfile wrapper? Set up your .LNK to run perl.exe with the script name as an argument, rather than requiring the target to be something that directly executes.

      For that matter, why doesn't a lnk to a .pl file do the right thing anyway, just like double-clicking on the .pl file would?

        Good question(s). Force of habit, mainly, and also it doesn't require the registry association to exist. I'm a big fan of not relying on things that are outside my control, and the registry is one of those things. I have worked on machines that were locked down so tight that I couldn't install any software on it, but I could manually copy Perl onto it, and add it to the path. Making the shortcut run perl with the .pl as a parameter would have worked for the shortcuts, but not for the command line. Also Win95 can't be told to search the path for .pl files.