develooper Front page | perl.perl5.porters | Postings from July 2009

Coring Variable::Magic / autodie fights with string eval in Perl5.10.x

Thread Next
From:
Paul Fenwick
Date:
July 4, 2009 21:50
Subject:
Coring Variable::Magic / autodie fights with string eval in Perl5.10.x
Message ID:
4A5030FA.7030609@perltraining.com.au
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

G'day p5p,

I was speaking to Florian Ragwitz (rafl) on IRC today, who pointed out that
the trick I use to make autodie work under 5.10.x has a problem.

In a nutshell, autodie stuffs objects into %^H at compile time.  When Perl
reaches the end of the current lexical scope, anything in %^H turns into a
string, triggering object destruction, and allowing me to undo the magic
that autodie has inserted.  It's the mechanism which allows autodie to have
truly lexical scope.

When a string eval is compiled under 5.10.x, it copies the contents of %^H,
so that when the eval is executed, it can keep the same %^H contents as when
it was being compiled.  I understand this may be a feature (and may even be
required for 'use feature' to work).

Unfortunately, this also increases the ref-count of objects in %^H, which
means that destruction doesn't happen when I expect it to happen.  I can
demonstrate this with an example:

    {
        use autodie;
        eval "1";
    }

    open(my $fh, '<', 'no_such_file');

On Perl 5.8.x, autodie is constrained to its block, and the open at the end
executes without throwing an exception.  On Perl 5.10.x, the open at the end
(incorrectly) throws an exception.  The string eval has allows the autodie
magic to leak out of its block.  Remove the string eval, and things work fine.

The good news is that Florian and Vincent have tracked this down and have an
elegant fix which autodie can use.  It involves using Variable::Magic to
insert a magic variable into %^H, which can then execute code on its
refcount being reduced.

I've been very careful to code autodie with no mandatory dependencies at
all, and I've also been careful to keep autodie as pure Perl.  However I
can't see any way of getting around this bug without using a dependency or
writing XS, and I'm not good at XS.

So, on the assumption that having autodie in the core is a good thing, I
would like to propose:

   * Variable::Magic be strongly considered for core inclusion.  It only has
     core dependencies, and it works pretty close to Perl's guts.

   * B::Hooks::EndOfScope be considered for core inclusion.  It's a tiny
     amount of code, but provides a very useful service for anyone wanting
     to write lexical pragmas or code.  B::Hooks::EndOfScope may need to
     be tweaked to remove the CPAN dependency on Sub::Exporter.

If Variable::Magic goes core, then the situation with autodie will be:

  5.8.x:  No mandatory dependencies outside of core.
  5.10.0: Dependency upon Variable::Magic
  5.10.1: No mandatory dependencies outside of core.

In all cases, IPC::System::Simple is an optional dependency for those
wanting an autodying system.

Thoughts, questions, and discussions very welcome, particularly from
Vincent, who is the author of Variable::Magic.

All the best,

	Paul

- --
Paul Fenwick <pjf@perltraining.com.au> | http://perltraining.com.au/
Director of Training                   | Ph:  +61 3 9354 6001
Perl Training Australia                | Fax: +61 3 9354 2681
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFKUDD2x5N6j7FHnlURAhKpAJ4306IFcZAmnUeI75QIX87qz7ooZACdGQT0
iKTThupU0uurjJZ2s0fB6Is=
=bDkG
-----END PGP SIGNATURE-----

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About