[ABE.pm] WTF is this code doing?

Ricardo SIGNES rjbs-perl-abe at lists.manxome.org
Tue Jun 5 19:25:06 PDT 2007


* Faber Fedor <faber at linuxnj.com> [2007-06-05T21:48:04]
> Since I'm on a self-modifying code kick, I googled the phrase and stumbled
> across this:
> 
> #!/util/bin/perl
> $s = q@($t = $s) =~ s/\045/\100/g;
> print "#!/util/bin/perl\n\$s = q%$s%;$t";
> @;($t = $s) =~ s/\045/\100/g;
> print "#!/util/bin/perl\n\$s = q@$s@;$t";

In perldoc perlop, there's a section on "Quote-like operators."  It basically
says something like this:

Did you know that when you write:

  if ($string =~ /abcdef/) { ... }

It's the same as:

  if ($string =~ m/abcdef/) { ... }

?

Well, it is.  The m is optional if you use // -- and I say "if you use //"
because you can use other delimiters:

  if ($string =~ m|abcdef|) { ... } # some other repeated character
  if ($string =~ m$abcdef$) { ... } # another repeated character
  if ($string =~ m{abcdef}) { ... } # an open/close pair of characters

This is really convenient when you want to have a / in there, because you can
use something other than a /, and then you don't have to \ all your /.  Not
having to \ all my / makes me feel like this:

 \o/
  |
 / \

Some pairs are magic, and have special meaning, like m?foo? -- but you can look
into that on your own.

Anyway, m// isn't the only thing that works this way.  Just like // is secretly
m// in the context above, often "" is secretly qq"" and '' is secretly q''.

  m  - matching patern
  qq - quoted string (interpolates scalars and arrays)
  q  - quoted string (no interpolation)

So!

> $s = q@($t = $s) =~ s/\045/\100/g;
> print "#!/util/bin/perl\n\$s = q%$s%;$t";
> @;($t = $s) =~ s/\045/\100/g;
> print "#!/util/bin/perl\n\$s = q@$s@;$t";

The first @ begins a non-interpolated string, which ends at the next @.  That
program says:

  $s = '($t = $s) =~ s/\045/\100/g;'
     . "\n"
     . 'print "#!/util/bin/perl\n\$s = ...

and so on.  Does that help?

-- 
rjbs


More information about the ABE-pm mailing list