in reply to Deparse broken or just misunderstood?

You get a feather in your obfuscated code contest cap when you are able to write code that doesn't work when deparsed. Yes, it's possible to foil deparse. Why? Only perl itself can parse Perl.

In the case of your example, how would you want deparse to deparse that construct? Something more like this?:

my $d = 'Shakespeare is the food'; foreach ( $d ) { s/food/bard/; }

The problem is that of lexical scoping, and that of deparse trying its damndest to refrain from using 'for' as a modifier. I would say that at best your nifty trick is just a trick worthy of use in obfu, but not in mainstream code. I believe that the behavior allowing it to work in the case of the 'for' modifier is not defined, and thus may change in future Perl refinements. It's certanly not discussed directly in perlsyn, though perlsyn does mention that using my() on the left hand side of a conditional modifier yields undefined behavior.


Dave

Replies are listed 'Best First'.
Re^2: Deparse broken or just misunderstood?
by Roy Johnson (Monsignor) on Nov 15, 2004 at 17:56 UTC
    Alternatively, just the declaration could be moved out of the for:
    my $d; foreach ($d = 'Shakespear is the food') { s/foo/bar/; }
    I think that would be my preference, although your suggestion (modulo typos) is perfectly fine.
    I believe that the behavior allowing it to work in the case of the 'for' modifier is not defined, and thus may change in future Perl refinements.
    Certainly the scoping of the variable is defined, and according to perlsyn, "a declaration can be put anywhere a statement can," and "apart from declaring a variable name, the declaration acts like an ordinary statement, and is elaborated within the sequence of statements as if it were an ordinary statement. That means it actually has both compile-time and run-time effects."

    I think the behavior is pretty well-defined by that. The only issue is the scoping difference between predicate-for and block-for, which Deparse didn't accout for.

    By the way, I agree that this trick is not for mainstream code. Nifty tricks are not elegant solutions, but they can be useful for getting a better understanding of what lies behind a limitation.
    And it's less ugly than

    (sub { $_[0] =~ s/foo/bar/ })->(my $d = 'Shakespear is the food');
    (which Deparse doesn't change materially) :-)

    Caution: Contents may have been coded under pressure.