Skip Menu |

This queue is for tickets about the autodie CPAN distribution.

Report information
The Basics
Id: 54777
Status: resolved
Priority: 0/
Queue: autodie

People
Owner: Nobody in particular
Requestors: mschwern [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 2.08
Fixed in: (no value)



Subject: autodie loses open pragma
Normally, "use open" changes the default encoding of a newly opened filehandle. use open ':encoding(utf8)'; open my $fh, ">", "test"; # unix, perlio, encoding(utf8), utf8 print join ", ", PerlIO::get_layers($fh); Unfortunately it doesn't work with autobox turned on. This is because the open pragma is lexical, and autobox causes the real CORE::open to happen out of open.pm's scope. I don't have a solution for this. At minimum its a caveat worth mentioning.
On Thu Feb 18 17:13:36 2010, MSCHWERN wrote: Show quoted text
> Unfortunately it doesn't work with autobox turned on. This is because > the open pragma is lexical, and autobox causes the real CORE::open to > happen out of open.pm's scope.
s/autobox/autodie/g
On Thu Feb 18 17:13:36 2010, MSCHWERN wrote: Show quoted text
> Normally, "use open" changes the default encoding of a newly opened > filehandle. > > use open ':encoding(utf8)'; > > open my $fh, ">", "test"; > # unix, perlio, encoding(utf8), utf8 > print join ", ", PerlIO::get_layers($fh); > > Unfortunately it doesn't work with autobox turned on. This is because > the open pragma is lexical, and autobox causes the real CORE::open to > happen out of open.pm's scope. > > I don't have a solution for this.
Copy ${^OPEN}, ${^WARNING_BITS}, $^H and %^H. Set them inside a BEGIN{} block right before the CORE::whatever call. Show quoted text
> At minimum its a caveat worth mentioning.
This really needs some attention. autodie even breaks the PERL_UNICODE environment variable. I've written some tests to demonstrate it: https://gist.github.com/1103863
On Sun May 15 16:06:52 2011, SPROUT wrote: Show quoted text
> Copy ${^OPEN}, ${^WARNING_BITS}, $^H and %^H. Set them inside a > BEGIN{} block right > before the CORE::whatever call.
Has this been tested yet? This bug makes using autodie and utf8::all together problematic, which is tragic.
On Thu Feb 18 17:13:36 2010, MSCHWERN wrote: Show quoted text
> Normally, "use open" changes the default encoding of a newly opened > filehandle. > > use open ':encoding(utf8)'; > > open my $fh, ">", "test"; > # unix, perlio, encoding(utf8), utf8 > print join ", ", PerlIO::get_layers($fh); > > Unfortunately it doesn't work with autobox turned on. This is because > the open pragma is lexical, and autobox causes the real CORE::open to > happen out of open.pm's scope. > > I don't have a solution for this. At minimum its a caveat worth
mentioning. The hintshash of the previous scope can be accessed using caller (on 5.10+), as in this example: perl -Mopen=:utf8 -E 'say sub { (caller 0)[10]{$_[0]} }->($_) for "open<", "open>"' Granted, this is not much of a publicized interface and very dirty, but at least in theory it should be possible to fix this for open. socket, pipe, socketpair and accept are another matter though, but I wouldn't expect them to be used with «use open» anyway. Leon
On Mon May 14 16:15:20 2012, LEONT wrote: Show quoted text
> perl -Mopen=:utf8 -E 'say sub { (caller 0)[10]{$_[0]} }->($_) for > "open<", "open>"'
I'm giving that a shot. I can get the info out of caller, and I've found how to hack autodie for the special case, but I can't get it to stick by setting ${^OPEN}. Any help?
On Tue Jun 19 16:15:41 2012, MSCHWERN wrote: Show quoted text
> On Mon May 14 16:15:20 2012, LEONT wrote:
> > perl -Mopen=:utf8 -E 'say sub { (caller 0)[10]{$_[0]} }->($_) for > > "open<", "open>"'
> > I'm giving that a shot. I can get the info out of caller, and I've > found how to hack autodie for the special case, but I can't get it to > stick by setting ${^OPEN}. Any help?
It seems that setting ${^OPEN} just sets the hints in %^H; so setting ${^OPEN} isn’t necessary I have just had a *really* quick look at autodie. I think it generates a sub wrapper for each package, so it doesn’t look like an easy fix. Basically, you have to eval the CORE::open call with the hints in place. Since the hints could be different for different lexical scopes compiled into the same package, it has to be a run- time eval. The wrapper around CORE::open would have to be something like this (untested): sub wrapper { my($h,$w,$hh) = (caller 0)[8..10]; eval ' BEGIN { ($^H,${^WARNING_BITS}) = ($h,$w); %^H = %$hh } CORE::open(....); ' } But the return value needs to be captured, of course. I don’t know how this would interact with autodie::hints. I’m not sure I want to learn how that works. No, I am not volunteering to fix autodie, because it doesn’t need fixing; it needs a rewrite. :-(
A fix is available here: https://github.com/pfenwick/autodie/pull/12 It goes the long way around, reapplying the layers via binmode.
Show quoted text
> I don’t know how this would interact with autodie::hints. I’m not > sure I want to learn how that works.
autodie::hints is all about how do non-core subroutines indicate failure, and so luckily will have nothing to do with CORE::open. :) Schwern's patches look good. I've applied them to the master repo, and unless we find any surprises, will be in the next release of autodie.
Wasn't this fixed & released to CPAN?
On Mon Sep 10 18:53:17 2012, DOHERTY wrote: Show quoted text
> Wasn't this fixed & released to CPAN?
Yes, it has been! And recently made it into blead, if I'm not mistaken. Thanks for the nudge, I'm now marking this as resolved. :) Paul