Skip Menu |

This queue is for tickets about the Test-Weaken CPAN distribution.

Report information
The Basics
Id: 64272
Status: open
Priority: 0/
Queue: Test-Weaken

People
Owner: KRYDE [...] cpan.org
Requestors: user42 [...] zip.com.au
Cc:
AdminCc:

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



Subject: 5.13 tied handle
Date: Tue, 28 Dec 2010 09:31:28 +1100
To: bug-Test-Weaken [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
I got a cpantesters report http://www.cpantesters.org/cpan/report/ad6c1138-0ef7-11e0-acf3-6b2cf3486b6f complaining Use of tied on a handle without * is deprecated at /home/src/perl/repoperls/installed-perls/perl/v5.13.8-6-gc8536af/lib/site_perl/5.13.8/Test/Weaken.pm line 139. # Saw 1 warning(s): # # Trace begun at t/MyTestHelpers.pm line 48 # MyTestHelpers::nowarnings_handler('Use of tied on a handle without * is deprecated at /home/src/perl/repoperls/installed-perls/perl/v5.13.8-6-gc8536af/lib/site_perl/5.13.8/Test/Weaken.pm line 139.^J') called at /home/src/perl/repoperls/installed-perls/perl/v5.13.8-6-gc8536af/lib/site_perl/5.13.8/Test/Weaken.pm line 139 # Test::Weaken::Internal::follow('Test::Weaken=HASH(0x14a0f38)', 'REF(0xfd6880)') called at /home/src/perl/repoperls/installed-perls/perl/v5.13.8-6-gc8536af/lib/site_perl/5.13.8/Test/Weaken.pm line 321 # Test::Weaken::test('Test::Weaken=HASH(0x14a0f38)') called at /home/src/perl/repoperls/installed-perls/perl/v5.13.8-6-gc8536af/lib/site_perl/5.13.8/Test/Weaken.pm line 387 # Test::Weaken::leaks('HASH(0x123f5e8)') called at t/Gtk2-PodDialog-weaken.t line 63 Dunno what it means, another incompatible change or forced code change in perl I suppose. I always thought perl6 was designed as a sink for such nonsense :-(. It'll be coming from something in Gtk2::Ex::PodViewer. The only handle that looks like it may still be open is an IO::Scalar, if that helps. (My code gives a filename, but the PodViewer parser looks like it reads that into a string.) You could think about a test case trying IO::Scalar, if available, or maybe copy some of that code into a test case (some tricky tied ref to a localized file handle or whatever).
I'll treat this as something to watch. Warning messages are hard things to get right -- what's weird code in one context may turn out to be Best Practice in some other context you're not aware of, and warnings take a while to get right even in official versions. If it makes it's way into an official version, then I'll silence the warning. I don't see any use asking the perl-porters if this warning will survive into 5.14 -- they probably just don't know at this point. After all, ironing out this sort of thing is what development versions are for. I'll leave this in the queue, so that it will remind me to follow up.
Subject: Re: [rt.cpan.org #64272] 5.13 tied handle
Date: Sun, 02 Jan 2011 09:45:51 +1100
To: bug-Test-Weaken [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
"Jeffrey Kegler via RT" <bug-Test-Weaken@rt.cpan.org> writes: Show quoted text
> > I don't see any use asking the perl-porters
I wondered if it was trying to demand everyone change their code to tie *$fh, ... or something if tying a handle. And if tied() was going to be similar. If so then it could be annoying for generic code like Test::Weaken which wants the tied object underneath any ref. May be worth checking the intended syntax before it goes too far ... But I've never had to do either of those things, so perhaps it's completely different.
Subject: Re: [rt.cpan.org #64272] 5.13 tied handle
Date: Mon, 30 May 2011 11:11:59 +1000
To: bug-Test-Weaken [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
"Jeffrey Kegler via RT" <bug-Test-Weaken@rt.cpan.org> writes: Show quoted text
> > If it makes it's way into an official version, then I'll silence the > warning.
It looks like 5.14 has this. Looks like an incompatible change being forced on users, but which might hurt generic code using tied(). Hard to tell for sure.
On Sun May 29 21:12:26 2011, user42@zip.com.au wrote: Show quoted text
> "Jeffrey Kegler via RT" <bug-Test-Weaken@rt.cpan.org> writes:
> > > > If it makes it's way into an official version, then I'll silence the > > warning.
> > It looks like 5.14 has this. Looks like an incompatible change being > forced on users, but which might hurt generic code using tied(). Hard > to tell for sure.
Dunno what's up here. I do see the warning in some versions, but also recently there have been a lot of false negatives.
On Sun Jan 01 20:47:09 2012, JKEGL wrote: Show quoted text
> On Sun May 29 21:12:26 2011, user42@zip.com.au wrote:
> > "Jeffrey Kegler via RT" <bug-Test-Weaken@rt.cpan.org> writes:
> > > > > > If it makes it's way into an official version, then I'll silence the > > > warning.
> > > > It looks like 5.14 has this. Looks like an incompatible change being > > forced on users, but which might hurt generic code using tied(). Hard > > to tell for sure.
> > Dunno what's up here. I do see the warning in some versions, but also > recently there have been a lot of false negatives.
I’ve just noticed this ticket. What happens in 5.14 and earlier is that tied($var) will do two different things, depending on whether $var looks like a typeglob. If you have a tied scalar, say $tied, and you assign a typeglob to it: $tied = *foo; Then STORE gets called as usual, with $_[1] set to a copy of *foo. The problem now is that, due to the way tied scalars work (the scalar itself is actually modified, then a special internal callback is triggered), $tied is now a typeglob, even if a subsequent FETCH would stop it from being one (behind the scenes, $tied is set to the value return from FETCH, the that value is read from $tied). So, until that FETCH, tied($var) will return undef. If FETCH returns a non-glob, ‘$x=$tied, tied($tied)’ will return the object implementing the tie. It affected untie as well. Trying to untie a scalar that has had a typeglob assigned to or returned from it will not untie that scalar. So this was a bug that needed fixing. The deprecation warning was added in 5.14 for the sake of code that might be relying on the old erratic behaviour. In 5.15 it was changed such that tied($foo) will treat $foo as a scalar, but tied(*$foo) will treat it as a handle. So if you want to check for tied handles, you will have to do the latter, but in the case of Test::Weaken, it only makes sense after checking for a tied scalar first. Now, to complicate matters, a scalar aliased to a typeglob (as in for my $var(*foo) {...}) is indistinguishable from a regular typeglob, so tied($var) will treat it as a handle in that case. Assigning a typeglob to a scalar (which creates a special typeglob internally flagged as being just a copy) is what triggers the erratic behaviour.
Ok. Attached is a proposed fix -- simply breaking out treatment of the GLOB and adding the star (*). It passes the current test suite, which does have a file handle test in it: t/filehandle.t My version of Perl is 5.10, so I cannot test that this fix in fact silences the warning. I can't imagine that it would not, but I've been programming for over 40 years, and much that I never imagined has come to pass in that time. :-) This fix is also in the dev branch at the github repository.
Subject: tied.fix
Download tied.fix
application/octet-stream 1.3k

Message body not shown because it is not plain text.

On Sun Jan 01 22:31:16 2012, JKEGL wrote: Show quoted text
> Ok. Attached is a proposed fix -- simply breaking out treatment of the > GLOB and adding the star (*). It passes the current test suite, which > does have a file handle test in it: t/filehandle.t > > My version of Perl is 5.10, so I cannot test that this fix in fact > silences the warning. I can't imagine that it would not, but I've been > programming for over 40 years, and much that I never imagined has come > to pass in that time. :-) > > This fix is also in the dev branch at the github repository.
Concerning this part: if ( $object_type eq 'SCALAR' - or $object_type eq 'GLOB' or $object_type eq 'VSTRING' or $object_type eq 'LVALUE' ) I would suggest leaving GLOB there, in case it is a tied scalar that just happened to have a glob assigned to it last. The abstraction of tied scalars actually leaks out, but I’m not sure whether it’s supposed to be a feature or a bug: sub TIESCALAR{bless[]} sub STORE{} tie $x, ""; $x = *foo; print ref \$x, "\n"; That snippet prints ‘GLOB’.
If you look at the larger context, you'll see the cases are mutually exclusive, with the first to apply ending the FIND_CHILDREN block via a last statement. I added a case dedicated to 'GLOB'. Leaving the test for $object_type eq 'GLOB' in a case tested for later, such the one quoted below, would be useless and highly misleading. On Sun Jan 01 22:47:39 2012, SPROUT wrote: Show quoted text
> Concerning this part: > > if ( $object_type eq 'SCALAR' > - or $object_type eq 'GLOB' > or $object_type eq 'VSTRING' > or $object_type eq 'LVALUE' ) > > I would suggest leaving GLOB there, in case it is a tied scalar that > just happened to have a > glob assigned to it last. The abstraction of tied scalars actually > leaks out, but I’m not sure > whether it’s supposed to be a feature or a bug: > > sub TIESCALAR{bless[]} > sub STORE{} > tie $x, ""; > $x = *foo; > print ref \$x, "\n"; > > That snippet prints ‘GLOB’.
On Sun Jan 01 22:55:46 2012, JKEGL wrote: Show quoted text
> If you look at the larger context, you'll see the cases are mutually > exclusive, with the first to apply ending the FIND_CHILDREN block via a > last statement. I added a case dedicated to 'GLOB'. Leaving the test > for $object_type eq 'GLOB' in a case tested for later, such the one > quoted below, would be useless and highly misleading.
OK, then how about the attached patch?
Subject: open_kUM4qX2X.txt
diff -rup Test-Weaken-3.006000-HkuAjM/lib/Test/Weaken.pm Test-Weaken-3.006000-HkuAjM-copy/lib/Test/Weaken.pm --- Test-Weaken-3.006000-HkuAjM/lib/Test/Weaken.pm 2012-01-01 20:45:25.000000000 -0800 +++ Test-Weaken-3.006000-HkuAjM-copy/lib/Test/Weaken.pm 2012-01-01 20:51:07.000000000 -0800 @@ -135,6 +135,10 @@ sub follow { if ( my $tied_var = tied *${$follow_probe} ) { push @child_probes, \($tied_var); } + # tied scalar that happens to hold a glob: + if ($] > 5.015 and my $tied_var2 = tied ${$follow_probe}) { + push @child_probes, \($tied_var2); + } last FIND_CHILDREN; } ## end if ( $object_type eq 'GLOB' )
@Father Chrysostomos: In the patch, should the test be if $] >= 5.015? That is greater-than-or-equal instead of greater-than? My idea is that you're telling me something like the following: 1.) A GLOB (call it a "pure-GLOB") and a scalar assigned a GLOB (call it a "scalar-GLOB") are distinct internally, but both test as GLOB's. 2.) Before 5.15, I've no choice but to work only with the GLOB for both pure- and scalar-GLOBs. 3.) 5.15 and after, the warning is gone and I can and should look at both the GLOB and the scalar. 4.) Your patch avoids the warning because "tied *$x" avoids it for both pure- and scalar-GLOBs in both versions. "tied $x" does not avoid the warning before 5.15, so you test for the perl version. 5.) Your patch deals with pure-GLOBs because "if ($] > 5.015 and my $tied_var2 = tied ${$follow_probe})" will be false if "tied ${$follow_probe}" is undef, which it will be in the case of a pure-GLOB. (Or will it?) 6.) But can't tied ${$follow_probe} be a Perl false in the case of some scalar GLOB's? Do all GLOB's test Perl true? I wonder if the best way to deal with the scalar side of a scalar GLOB is to note in my documentation that it is discarded? I'd much rather take a change on a poorly featured release than a buggy one. I am concerned about these things: As I am currently set up, I cannot really test that code targeted at 5.15 and later works. And it looks like this stuff is tricky enough that I really would want to test, and not just via cpantesters. Also, at present, my test suite coverage for GLOB's is very meager -- although I suspect that it adequately reflects the level of user interest. Another thing is, is any of this in the main Perl docs? I don't want to aggressively track undocumented behaviors which I can avoid it. And I really wonder if in this case the payoff for being aggressive about catching this corner case is there. By default, GLOB's are not tracked by Test::Weaken at all. Their lifetime is rarely expected to be the same as that of the object which contains them, so most users prefer to ignore them entirely. With a note in the Test::Weaken docs, users will be alerted, and I'll be able to revisit this issue once things settle. Maybe by then I'll have new hardware and can perlbrew 5.15. @Father Chrysostomos: Thanks for your guidance in this matter, which have clarified this matter a great deal. On Sun Jan 01 23:52:30 2012, SPROUT wrote: Show quoted text
> On Sun Jan 01 22:55:46 2012, JKEGL wrote:
> > If you look at the larger context, you'll see the cases are mutually > > exclusive, with the first to apply ending the FIND_CHILDREN block via a > > last statement. I added a case dedicated to 'GLOB'. Leaving the test > > for $object_type eq 'GLOB' in a case tested for later, such the one > > quoted below, would be useless and highly misleading.
> > OK, then how about the attached patch?
On Mon Jan 02 01:05:39 2012, JKEGL wrote: Show quoted text
> @Father Chrysostomos: > > In the patch, should the test be if $] >= 5.015? That is > greater-than-or-equal instead of greater-than?
Yes, you’re right. I wrote it sloppily based on the assumption that no one would be using a development version. Show quoted text
> > My idea is that you're telling me something like the following: > > 1.) A GLOB (call it a "pure-GLOB") and a scalar assigned a GLOB (call it > a "scalar-GLOB") are distinct internally, but both test as GLOB's.
Yes. The main difference is that assigning over the former will do a special glob assignment (e.g, *foo = \&bar assigns to a single slot), whereas assigning over the latter will clobber the glob entirely, as in $foo = *foo; $foo = \&bar;. This distinction is something left over from Perl 4 that is impossible to remove. (Personally I think it was a bad design to begin with.) Show quoted text
> 2.) Before 5.15, I've no choice but to work only with the GLOB for both > pure- and scalar-GLOBs.
Unless you use B.pm, but such solutions are usually fragile. Another thing you could do is assume the tie is well-behaved and do local($var)=undef; to see whether that causes tied($var) to return anything. Show quoted text
> 3.) 5.15 and after, the warning is gone and I can and should look at > both the GLOB and the scalar.
Come to think of it, my patch is flawed. If the glob is something returned by a tied method, you probably don’t want to visit it at all, do you? To me it would make sense to do the scalar-tied check first and only do the handle-tied check after that. Looking at your handling of REF, I see that you don’t skip the usual code when there is a tie. Is that code really correct? A tied variable could return a strong copy of an internal weak reference, resulting in false positives. Show quoted text
> > 4.) Your patch avoids the warning because "tied *$x" avoids it for both > pure- and scalar-GLOBs in both versions. "tied $x" does not avoid the > warning before 5.15, so you test for the perl version.
That’s right. Before 5.15, tied($x) and tied(*$x) would do the same thing in the case of reftype(\$x) eq 'GLOB'. Show quoted text
> > 5.) Your patch deals with pure-GLOBs because "if ($] > 5.015 and my > $tied_var2 = tied ${$follow_probe})" will be false if "tied > ${$follow_probe}" is undef, which it will be in the case of a pure-GLOB. > (Or will it?)
Well, this is one of the things I don’t like about the typeglob model to begin with. On a pure- GLOB, tied ($x) and tied (*$x) return exactly the same thing. This means that the same tied object will be pushed on to @child_probes twice, but you have a check for duplicates elsewhere. Show quoted text
> 6.) But can't tied ${$follow_probe} be a Perl false in the case of some > scalar GLOB's?
Yes it can. I don’t understand your concern. If the scalar ${$follow_probe} is tied, it will return true; otherwise false. If the handle *${$follow_probe} is tied, tied ${$follow_probe} will return false (unless ${$follow_probe} is a tied scalar returning a tied handle), but tied *${$follow_probe} will return true. Show quoted text
> Do all GLOB's test Perl true?
Do you mean !!tied $glob or !!$glob? The former, not necessarily; the latter, yes. I don’t think I understand (the purpose of) your question. Show quoted text
> I wonder if the best way to deal with the scalar side of a scalar GLOB > is to note in my documentation that it is discarded? I'd much rather > take a change on a poorly featured release than a buggy one.
That would be reasonable. Show quoted text
> I am concerned about these things: > > As I am currently set up, I cannot really test that code targeted at > 5.15 and later works. And it looks like this stuff is tricky enough > that I really would want to test, and not just via cpantesters. Also, > at present, my test suite coverage for GLOB's is very meager -- although > I suspect that it adequately reflects the level of user interest. > > Another thing is, is any of this in the main Perl docs? I don't want to > aggressively track undocumented behaviors which I can avoid it.
The edge cases are not all documented, but I could change that. I stated above that it would be reasonable not to support scalar ties on globs, simply because this is one area of perl that is so buggy that you’ll find different behaviours in different versions. In 5.12 and earlier, this sets $foo to \&bar, believe it or not: my $foo = *thing; *$foo = \&bar; # clobbers the glob, despite the * As of 5.14, *$foo actually returns a copy of the glob, with flagged internally as a pure-GLOB, so that assignments like that will work. Show quoted text
> And I really wonder if in this case the payoff for being aggressive > about catching this corner case is there. By default, GLOB's are not > tracked by Test::Weaken at all.
Well, this is what it comes down to in the end. Globs and tied variables are buggy enough that the cases where these things matter are probably rare, if at all existent. Show quoted text
> Their lifetime is rarely expected to be > the same as that of the object which contains them, so most users prefer > to ignore them entirely. > > With a note in the Test::Weaken docs, users will be alerted, and I'll be > able to revisit this issue once things settle. Maybe by then I'll have > new hardware and can perlbrew 5.15. > > @Father Chrysostomos: Thanks for your guidance in this matter, which > have clarified this matter a great deal.
With this message, I fear I may have done the opposite. :-) Show quoted text
> > On Sun Jan 01 23:52:30 2012, SPROUT wrote:
> > On Sun Jan 01 22:55:46 2012, JKEGL wrote:
> > > If you look at the larger context, you'll see the cases are mutually > > > exclusive, with the first to apply ending the FIND_CHILDREN block via a > > > last statement. I added a case dedicated to 'GLOB'. Leaving the test > > > for $object_type eq 'GLOB' in a case tested for later, such the one > > > quoted below, would be useless and highly misleading.
> > > > OK, then how about the attached patch?
> >
On Mon Jan 02 11:35:22 2012, SPROUT wrote: Show quoted text
> Looking at your handling of REF, I see that you don’t skip the usual > code when there is a tie. > Is that code really correct? A tied variable could return a strong > copy of an internal weak > reference, resulting in false positives.
And to follow up to that, it’s also possible for a tie object to have overloading that makes it false as a boolean, so defined(tied...) would be safer. Oh, and ties can hold weak references, too. :-) Have you seen my Tie::Util module? I haven’t updated it since before 5.14. At the time I wrote it I didn’t know about this glob/scalar dichotomy. I could update it to provide functions that always check for specific kind of tie (scalar or handle), and then you could use it in Test::Weaken. It has no non-core dependencies.
My next step will be to document the fact that the handling of GLOB's does not address all the intricacies, and add the code in my original patch to at least follow the GLOB. If at some later time users show interest in having Test::Weaken address the intricacies of tied GLOB's, then Tie::Util will be useful to study. Show quoted text
> Have you seen my Tie::Util module? I haven’t updated it since before > 5.14. At the time I > wrote it I didn’t know about this glob/scalar dichotomy. I could > update it to provide functions > that always check for specific kind of tie (scalar or handle), and > then you could use it in > Test::Weaken. It has no non-core dependencies.
The fix is in 3.007_001. I'll wait a few days for cpantesters and other feedback before marking this ticket resolved. On Tue Jan 03 20:35:52 2012, JKEGL wrote: Show quoted text
> My next step will be to document the fact that the handling of GLOB's > does not address all the intricacies, and add the code in my original > patch to at least follow the GLOB. If at some later time users show > interest in having Test::Weaken address the intricacies of tied GLOB's, > then Tie::Util will be useful to study. >
> > Have you seen my Tie::Util module? I haven’t updated it since before > > 5.14. At the time I > > wrote it I didn’t know about this glob/scalar dichotomy. I could > > update it to provide functions > > that always check for specific kind of tie (scalar or handle), and > > then you could use it in > > Test::Weaken. It has no non-core dependencies.
> >
I am no longer a maintainer of Test::Weaken. Glancing quickly at the preceding thread, I think this ticket is resolved. I attempted to mark it as such, but (despite the fact that I'm the owner) it denies me permission. And I can't figure out how you "dis-own" a ticket. On Sun Jan 08 12:13:23 2012, JKEGL wrote: Show quoted text
> The fix is in 3.007_001. I'll wait a few days for cpantesters and other > feedback before marking this ticket resolved. > > On Tue Jan 03 20:35:52 2012, JKEGL wrote:
> > My next step will be to document the fact that the handling of GLOB's > > does not address all the intricacies, and add the code in my original > > patch to at least follow the GLOB. If at some later time users show > > interest in having Test::Weaken address the intricacies of tied GLOB's, > > then Tie::Util will be useful to study. > >
> > > Have you seen my Tie::Util module? I haven’t updated it since before > > > 5.14. At the time I > > > wrote it I didn’t know about this glob/scalar dichotomy. I could > > > update it to provide functions > > > that always check for specific kind of tie (scalar or handle), and > > > then you could use it in > > > Test::Weaken. It has no non-core dependencies.
> > > >
> >
I had meant to try to understand the subtleties which came up, to see if I should do something more or less, but it might be beyond me. Feel free to close for now if desired.
That's the problem. When I try to close this ticket I get "Ticket 64272: Permission Denied" I also cannot figure out how to give away ownership of it. On Fri Nov 09 15:53:32 2012, KRYDE wrote: Show quoted text
> I had meant to try to understand the subtleties which came up, to see if > I should do something more or less, but it might be beyond me. Feel > free to close for now if desired.
Subject: Re: [rt.cpan.org #64272] 5.13 tied handle
Date: Wed, 21 Nov 2012 11:56:43 +1100
To: bug-Test-Weaken [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
"Jeffrey Kegler via RT" <bug-Test-Weaken@rt.cpan.org> writes: Show quoted text
> > "Ticket 64272: Permission Denied"
Ah dear. I'll try to either fix it close it ... :)