Skip Menu |

This queue is for tickets about the XML-Parser CPAN distribution.

Report information
The Basics
Id: 67207
Status: resolved
Priority: 0/
Queue: XML-Parser

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

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: 2.40_01



CC: slaven [...] rezic.de
Subject: [PATCH] Avoid deprecated use of tied()
Date: Sun, 3 Apr 2011 16:57:33 -0700
To: bug-XML-Parser [...] rt.cpan.org
From: Father Chrysostomos <sprout [...] cpan.org>
In Perl 5.14, which is soon to be released, using tied($handle) is deprecated. This is because tied($foo) is supposed to act on $foo as a scalar, without regard to whatever value it might hold. (It will be changed to work this way in 5.16.) An explicit * will avoid the warning: tied(*$handle). Here is a patch to fix this. It requires a little explanation: I was going simply to change tied($arg) to eval { tied(*$arg) }, when I realised that this check is unnecessary as of 5.8.0, in which the tiedness of the handle is attached to the IO thingy itself, not to the glob. Then I also realised that the existing logic for testing for a tied handle is faulty and can’t possibly have worked: If tied($arg) returns true and the scalar $arg is not tied, then it can only be a glob, for which ref($arg) returns an empty string. So the ‘if defined &{"${class}::TIEHANDLE"}’ check looks in the main package for a TIEHANDLE subroutine. The rest of the code expects to call methods on the file handle. I do not believe that is possible in 5.6, so this patch simply removes that elsif().

Message body is not shown because sender requested not to inline it.

On Sun Apr 03 19:57:47 2011, sprout@cpan.org wrote: Show quoted text
> In Perl 5.14, which is soon to be released, using tied($handle) is > deprecated. This is because tied($foo) is supposed to act on $foo > as a scalar, without regard to whatever value it might hold. (It > will be changed to work this way in 5.16.) > > An explicit * will avoid the warning: tied(*$handle). > > Here is a patch to fix this. It requires a little explanation: > > I was going simply to change tied($arg) to eval { tied(*$arg) }, when > I realised that this check is unnecessary as of 5.8.0, in which the > tiedness of the handle is attached to the IO thingy itself, not to > the glob. > > Then I also realised that the existing logic for testing for a tied > handle is faulty and can’t possibly have worked: If tied($arg) > returns true and the scalar $arg is not tied, then it can only be a > glob, for which ref($arg) returns an empty string. So the ‘if > defined &{"${class}::TIEHANDLE"}’ check looks in the main package > for a TIEHANDLE subroutine. The rest of the code expects to call > methods on the file handle. I do not believe that is possible in > 5.6, so this patch simply removes that elsif().
I was mistaken. It is possible to call a method on a typeglob, as in *foo->bar. So this better patch makes tied handles work in 5.6 and skips the special handling in 5.8 and higher, as it is unnecessary. I added a local *@, because of the new eval{}, which rendered the existing undef $@ unnecessary. I used defined tied $arg, because the object implementing the tied could have boolean overloading that returns false (paranoid, I know).
Subject: open_Au0OLhOi.txt
diff -rup XML-Parser-2.40-lsjPau-orig/Expat/Expat.pm XML-Parser-2.40-lsjPau/Expat/Expat.pm --- XML-Parser-2.40-lsjPau-orig/Expat/Expat.pm 2010-09-15 14:44:18.000000000 -0700 +++ XML-Parser-2.40-lsjPau/Expat/Expat.pm 2011-04-03 18:01:19.000000000 -0700 @@ -442,12 +442,12 @@ sub parse { my $result = 0; if (defined $arg) { + local *@; if (ref($arg) and UNIVERSAL::isa($arg, 'IO::Handle')) { $ioref = $arg; - } elsif (tied($arg)) { - my $class = ref($arg); - no strict 'refs'; - $ioref = $arg if defined &{"${class}::TIEHANDLE"}; + } elsif ($] < 5.008 and defined tied($arg)) { + require IO::Handle; + $ioref = $arg; } else { require IO::Handle; @@ -455,20 +455,21 @@ sub parse { no strict 'refs'; $ioref = *{$arg}{IO} if defined *{$arg}; }; - undef $@; } } if (defined($ioref)) { my $delim = $self->{Stream_Delimiter}; my $prev_rs; + my $ioclass = ref $ioref; + $ioclass = "IO::Handle" if !length $ioclass; - $prev_rs = ref($ioref)->input_record_separator("\n$delim\n") + $prev_rs = $ioclass->input_record_separator("\n$delim\n") if defined($delim); $result = ParseStream($parser, $ioref, $delim); - ref($ioref)->input_record_separator($prev_rs) + $ioclass->input_record_separator($prev_rs) if defined($delim); } else { $result = ParseString($parser, $arg);
RT-Send-CC: slaven [...] rezic.de
I'm working on a release. This patch has been applied on github: https://github.com/toddr/XML-Parser