in reply to Re: Re: Thanks to Rudif
in thread Thanks to Rudif

I scratched my head over this for a while. Very clever. Here's my attempt at explaining the key parts.

()=/(.*)/s,

$_ is an alias for one of the reversed strings in @_. Assuming this is being run by Perl 5, list context forces $1 to get set in the absence of /g. (perlre notes that $1 wouldn't get set in Perl 4.) $1 now refers to the entire string held in $_ (including the "\n" in the final one, thanks to /s).
$_=reverse,
Use scalar context to set $_ to a reversed copy of itself.
print $1
Since $1 still refers to the entirety of $_, the reversed string is printed. (You could just print $_ here, but that would hardly be obfuscating.)
for @_=(" tsuJ", ...)
@_ is a false clue. It could as well be @x. The array assignment makes a copy of the array. This permits individual elements (pointed to by $_) to be reversed. Without the array assignment here, reverse would fail in an attempt to reverse a read-only string.

Replies are listed 'Best First'.
Re: Re: Re: Re: Thanks to Rudif
by japhy (Canon) on Mar 04, 2001 at 22:50 UTC
    You're 99% right, dws. As I've said before, obfuscation is quite often the masking of an abuse of the language, and this is abusing a bug that won't be present in the next version of Perl (I patched it yesterday, much to my amazement ;)).

    The bug was that the $DIGIT variables were not COPIED when a pattern was done in list context; rather, they were "linked" to portions of the string. When the string changes, so do they (sometimes unpredictably). This won't occur in 5.6.1, because my patch removed that behavior, for one of two reasons: 1) it's not documented, and 2) it's not really useful, and could cause problems for people expecting the variables to behave normally.

    If you remove the () = from the obfuscation, you'll see it doesn't "work".

    japhy -- Perl and Regex Hacker