On Tue, Feb 12, 2008 at 16:10:28 -0800, Michael G Schwern wrote: > It's an interesting idea, but at the end of the article is the Fine Print > about how assert {2.0} doesn't quite work:
Actually, by rewriting the expressions like I suggested, we can work around that too: my $foo = ""; my $ar = "ar"; assert { $foo .= "bar"; # side effect $foo eq "b" . $ar; } the sub will then get rewritten into: { $foo .= "bar"; ( $deparsed{'$foo'} = $foo ) == ( $deparsed{'"b" . $ar'} = ( ( $deparsed{'"b"'} = "b" ) . ( $deparsed{'$ar'} = $ar ) ) ); } sort of, by injecting assignment nodes into the optree with B::Generate (this is the handwaving bit). The keys for %deparsed are prepared by deparsing the subexpressions. Then the expression is run once, and on failure the values are already stored. This works with side effects, closure state, short circuiting, etc. The only issue is list/scalar context. But I think generating expressions like this should work: sub list_ctx { return wantarray } ( list_ctx ? @{ $deparsed{blah} = [ $subexpr ] } : $deparsed{blah} = $subexpr } ) but only as an rvalue (assigning to an ? : where one subexpr is listy and other is scalary is a compile time error IIRC). -- Yuval Kogman <[EMAIL PROTECTED]> http://nothingmuch.woobling.org 0xEBD27418
pgp9p9hcxG80O.pgp
Description: PGP signature