Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
I've been hunting through my code, eventually coming to a bug where I had
a closure that referred to itself, as well as an object of mine. This
prevented my object's DESTROY handler from working, causing bugs.

I've been playing with Test::Memory::Cycle, but unfortunately that won't
solve this particular problem.

  my $hash = {};
  $hash-{object} = $some_object;
  $hash-{cycle} = $hash;

No amount of cycle checking in $some_object is going to find this cycle.
If the cycled object is one like this; containing the only reference to
itself, then almost by definition there's nothing that could be walked
for memory cycles.

This is where I consider a refcount-assertion module instead; something I
could do this with:

  use Test::Refcount;

  my $object = Some::Class-new( ... );

  has_onlyref( $object, '$object has only 1 reference' );

  # Synonym for
  has_refcount( $object, 1, '$object has only 1 reference' );

There's a very simple implementation for this I can think of; using:

  use B qw( svref_2object );

  sub refcount {
my $sv = svref_2object( $_[0] );
return $sv-REFCNT - 1; # Because @_ refers to it too
  }

Does this sound good?

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Andy Armstrong

On 14 Jul 2008, at 18:12, Paul LeoNerd Evans wrote:
No amount of cycle checking in $some_object is going to find this  
cycle.
If the cycled object is one like this; containing the only reference  
to

itself, then almost by definition there's nothing that could be walked
for memory cycles.



I've used Devel::Leak::Object[1] successfully in that kind of  
situation. It counts the number of blesses and destroys. It works well  
for the 'object makes a closure that references itself' scenario.


[1] http://search.cpan.org/dist/Devel-Leak-Object/

--
Andy Armstrong, Hexten





Re: Port to PyConstructs

2008-07-14 Thread David Nicol
On Sat, Jul 12, 2008 at 1:50 AM, Shlomi Fish [EMAIL PROTECTED] wrote:


   http://construct.wikispaces.com/

  In short, it's a library that parse binary structs.



Cool!
http://dev.perl.org/perl6/rfc/122.html


Re: Proposal: Test::Refcount

2008-07-14 Thread Andy Lester


On Jul 14, 2008, at 12:12 PM, Paul LeoNerd Evans wrote:


Does this sound good?



Yes, and if it sounds like it would actually supercede  
Test::Memory::Cycle, I would be glad to abandon T:M:C in favor of yours.


xoxo,
Andy

--
Andy Lester = [EMAIL PROTECTED] = www.petdance.com = AIM:petdance






Re: Proposal: Test::Refcount

2008-07-14 Thread Ivan Wills
   use B qw( svref_2object );

  sub refcount {
my $sv = svref_2object( $_[0] );
return $sv-REFCNT - 1; # Because @_ refers to it too
  }


This sounds like a very good idea to me, I was looking for a module like
this in my last job. I would suggest a two modules though say
Devel::Refcount which exports the refcount function and the Test::Refcount
for writing tests.

Ivan Wills

-- 
email/jabber: [EMAIL PROTECTED]
/
/ _ _
/ \ / | | | |
/ \/ \_| | |


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Tue, 15 Jul 2008 05:01:14 +1000
Ivan Wills [EMAIL PROTECTED] wrote:

 I would suggest a two modules though say Devel::Refcount

Is this Devel::Refcount really necessary, given how easy it is to build
using B::SV-REFCNT ?

Plus, the more levels of code, the more difficult it is to ensure the
count is correct. Consider

  sub is_1ref
  {
 my ( $object, $name ) = @_;
 my $count = refcount($object);
 ...
  }

vs

  sub is_1ref
  {
 my ( undef, $name ) = @_;
 my $count = refcount($_[0]);
 ...
  }

The $object in the first code creates a second reference, so you have to
subtract 1, whereas the @_ array seems special and doesn't have that
side-effect.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Mon, 14 Jul 2008 13:46:42 -0500
Andy Lester [EMAIL PROTECTED] wrote:

 Yes, and if it sounds like it would actually supercede  
 Test::Memory::Cycle, I would be glad to abandon T:M:C in favor of yours.

OK; see what you think to the attached initial attempt.

Not CPANned it yet; will wait and see some comments on it first.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


Test-Refcount-0.01.tar.gz
Description: GNU Zip compressed data


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Nicholas Clark
On Mon, Jul 14, 2008 at 08:32:52PM +0100, Paul LeoNerd Evans wrote:

   sub is_1ref
   {
  my ( undef, $name ) = @_;
  my $count = refcount($_[0]);
  ...
   }
 
 The $object in the first code creates a second reference, so you have to
 subtract 1, whereas the @_ array seems special and doesn't have that
 side-effect.

Until you take a reference to it, or various other things (I cant' remember the
canonical list, but push is in it, whereas shift doesn't seem to be (at least
a simple shift)):

$ perl -MDevel::Peek -e 'sub f {Dump $_[0]; warn [EMAIL PROTECTED]; Dump $_[0]; 
} f(\$v)'
SV = RV(0x817e18) at 0x800168
  REFCNT = 1
  FLAGS = (ROK)
  RV = 0x800f18
  SV = NULL(0x0) at 0x800f18
REFCNT = 2
FLAGS = ()
ARRAY(0x800f00) at -e line 1.
SV = RV(0x817e18) at 0x800168
  REFCNT = 2
  FLAGS = (ROK)
  RV = 0x800f18
  SV = NULL(0x0) at 0x800f18
REFCNT = 2
FLAGS = ()

It would be dangerous to rely on this reference counting behaviour remaining
the same.

Nicholas Clark


Re: Proposal: Test::Refcount

2008-07-14 Thread David Cantrell
On Tue, Jul 15, 2008 at 05:01:14AM +1000, Ivan Wills wrote:

 This sounds like a very good idea to me, I was looking for a module like
 this in my last job. I would suggest a two modules though say
 Devel::Refcount which exports the refcount function and the Test::Refcount
 for writing tests.

Can't you use Devel::Peek to get the refcount?

-- 
David Cantrell | http://www.cantrell.org.uk/david

  Blessed are the pessimists, for they test their backups


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Mon, 14 Jul 2008 20:59:34 +0100
David Cantrell [EMAIL PROTECTED] wrote:

 Can't you use Devel::Peek to get the refcount?

I use B:

  use B qw( svref_2object );

  my $SV = svref_2object($ref);
  my $refcount = $SV-REFCNT;

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Mon, 14 Jul 2008 20:59:20 +0100
Nicholas Clark [EMAIL PROTECTED] wrote:

 It would be dangerous to rely on this reference counting behaviour remaining
 the same.

Ah. Then perhaps it may be safer to use the normal 

  my ( $object, $count, $name ) = @_;

list assign idiom, then use -REFCNT - 1

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Ivan Wills
  I would suggest a two modules though say Devel::Refcount

 Is this Devel::Refcount really necessary, given how easy it is to build
 using B::SV-REFCNT ?

 Plus, the more levels of code, the more difficult it is to ensure the
 count is correct.


I see your point although I would contend that a Devel::Refcount module
would be useful even if Test::Refcount didn't use it as knowing about
B::SV-REFCNT is not easy. The B:: namespace not a place I would think that
may perl programers would go and try searching on CPAN for reference
counting and you will have a hard time finding out about B::svref_2object
call let alone the REFCNT parameter. This may be a problem with CPAN and
general lower level that reference counting exists in.

If Paul LeoNerd Evens doesn't want to create the module Devel::Refcount
along with Test::Refcount I would be happy to do it my self.

Ivan

-- 
email/jabber: [EMAIL PROTECTED]
/
/ _ _
/ \ / | | | |
/ \/ \_| | |


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Tue, 15 Jul 2008 06:11:25 +1000
Ivan Wills [EMAIL PROTECTED] wrote:

 If Paul LeoNerd Evens doesn't want to create the module Devel::Refcount
 along with Test::Refcount I would be happy to do it my self.

Well, it's not that I don't want to as such.. I'm just not sure it's
really justified.

It's kindof a personal thing, but I have a disliking for the mass
accumulation of really small one-liner modules around the place. Would
anyone consider

  package String::CaseInsensitive;
  sub casecmp { lc $_[0] cmp lc $_[1] }
  1;

as a module, for example?

When the module starts to get this small, I begin to wonder if it's more
of a documentation issue. Perhaps somewhere in the documentation about
objects and reference counts:

  The reference count of an object can be obtained by

use B qw( svref_2object );

my $count = svref_2object($ref)-REFCNT;

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Ivan Wills
 OK; see what you think to the attached initial attempt.


I just tried it and the tests fail on anonymous references in t/01count.t
and t/02one.t, I'm using perl 5.8.8 on linux if that is of any help.

Ivan Wills
-- 
email/jabber: [EMAIL PROTECTED]
/
/ _ _
/ \ / | | | |
/ \/ \_| | |


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Tue, 15 Jul 2008 06:33:26 +1000
Ivan Wills [EMAIL PROTECTED] wrote:

 I just tried it and the tests fail on anonymous references in t/01count.t
 and t/02one.t, I'm using perl 5.8.8 on linux if that is of any help.

Ahh.. 5.10 here.

OK; I've changed it to use a normal lexical $object, then subtract 1 from
the refcount, rather than rely on @_ not incrementing the count. Perhaps
that'll be more portable.

Try again attached...

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


Test-Refcount-0.01.tar.gz
Description: GNU Zip compressed data


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Mon, 14 Jul 2008 21:42:23 +0100
Paul LeoNerd Evans [EMAIL PROTECTED] wrote:

 OK; I've changed it to use a normal lexical $object, then subtract 1 from
 the refcount, rather than rely on @_ not incrementing the count. Perhaps
 that'll be more portable.

Actually it occurs to me this may not help, because the reference will
still be in @_ as well.

If it still fails, perhaps try

  my $object = shift;
  my $count  = shift;
  my $name   = shift;

that way it'll remove the ref. from @_ as it goes.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Jonathan Rockway
* On Mon, Jul 14 2008, Paul LeoNerd Evans wrote:
 On Tue, 15 Jul 2008 06:11:25 +1000
 Ivan Wills [EMAIL PROTECTED] wrote:

 If Paul LeoNerd Evens doesn't want to create the module Devel::Refcount
 along with Test::Refcount I would be happy to do it my self.

 Well, it's not that I don't want to as such.. I'm just not sure it's
 really justified.

 It's kindof a personal thing, but I have a disliking for the mass
 accumulation of really small one-liner modules around the place. 

I like these.  It's as important to reuse simple things as it is to
reuse complicated things.

 Would anyone consider

   package String::CaseInsensitive;
   sub casecmp { lc $_[0] cmp lc $_[1] }
   1;

 as a module, for example?

No, but that's because lc is the hard part, not the call to cmp.  If
Perl didn't have lc built in, you'd bet I'd want the lc function
from a module, rather than the simple (but wrong) tr/[A-Z]/[a-z]/.

 When the module starts to get this small, I begin to wonder if it's more
 of a documentation issue. Perhaps somewhere in the documentation about
 objects and reference counts:

   The reference count of an object can be obtained by

 use B qw( svref_2object );

 my $count = svref_2object($ref)-REFCNT;

Considering B is core, there is probably no need for a module to do
this.  But, does this always return correct results?  Does the
svref_2object call affect the REFCNT?  I am too lazy to check, but these
are nice questions for the documentation to answer.  If svref_2object
affects its argument, then it's probably best to write a module that
compensates for this behavior.

Regards,
Jonathan Rockway

-- 
print just = another = perl = hacker = if $,=$


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Mon, 14 Jul 2008 18:28:57 -0500
Jonathan Rockway [EMAIL PROTECTED] wrote:

 Considering B is core, there is probably no need for a module to do
 this.  But, does this always return correct results?  Does the
 svref_2object call affect the REFCNT?  I am too lazy to check, but these
 are nice questions for the documentation to answer.  If svref_2object
 affects its argument, then it's probably best to write a module that
 compensates for this behavior.

Actually, now I look at it there seems to be more complicated things
going on.

Originally I tried testing it with just the HASH or ARRAY based object
types people tend to use. I thought I'd try out all the reference types,
and here's the behaviour I get:

A new SCALAR ref has REFCNT 2
A new  ARRAY ref has REFCNT 1
A new   HASH ref has REFCNT 1
A new   CODE ref has REFCNT 2
A new   GLOB ref has REFCNT 3
A new  Regex ref has REFCNT 1

[see attached program]

It seems interesting that a new SCALAR or CODE ref has 2 references
already, and a GLOB has 3. I guess the CODE one -might- be explained by
its PAD or something, and maybe the GLOB one has more references in the
Perl symbol table, but these are pure guesses. I also cannot explain the
SCALAR one.

This behaviour seems to complicate the idea of simply asserting
REFCNT == 1.

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/
#!/usr/bin/perl -w

use strict;

use B qw( svref_2object );

my %refs = (
   SCALAR = do { \my $var },
   ARRAY  = [],
   HASH   = +{},
   CODE   = sub {},
   GLOB   = \*SomeNewName,
   Regex  = qr/foo/,
);

foreach my $type (qw( SCALAR ARRAY HASH CODE GLOB Regex )) {
   my $REFCNT = svref_2object($refs{$type})-REFCNT;
   printf A new %6s ref has REFCNT %d\n, $type, $REFCNT;
}


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Paul LeoNerd Evans
On Tue, 15 Jul 2008 00:44:12 +0100
Paul LeoNerd Evans [EMAIL PROTECTED] wrote:

SCALAR = do { \my $var },

It seems I can make the SCALAR ref have refcount 1 by changing this to

 SCALAR = do { my $var; \$var },

Various initialisations {e.g my $var = 1} also keep it happy.

Just the CODE and GLOB to go then...

-- 
Paul LeoNerd Evans

[EMAIL PROTECTED]
ICQ# 4135350   |  Registered Linux# 179460
http://www.leonerd.org.uk/


signature.asc
Description: PGP signature


Re: Proposal: Test::Refcount

2008-07-14 Thread Jonathan Rockway
* On Mon, Jul 14 2008, Paul LeoNerd Evans wrote:
 On Tue, 15 Jul 2008 00:44:12 +0100
 Paul LeoNerd Evans [EMAIL PROTECTED] wrote:

SCALAR = do { \my $var },

 It seems I can make the SCALAR ref have refcount 1 by changing this to

  SCALAR = do { my $var; \$var },

 Various initialisations {e.g my $var = 1} also keep it happy.

 Just the CODE and GLOB to go then...

Hmm, it might be a good idea to ask about this on p5p.  It would be good
to get this right Once And For All and make it really easy to use.
Memory cycles are the most common cause of memory leaks in Perl, and
they're really easy to fix once you know about them.  So a module that
makes them easy to find would be very good for everyone :)

Thanks for your work so far ;)

Regards,
Jonathan Rockway

-- 
print just = another = perl = hacker = if $,=$


Begging for money - too tacky?

2008-07-14 Thread Dave Rolsky
A friend recently reminded me of the RRDB author's vast list of donations 
he's received for his work, and I was thinking howzabout me?


I was wondering if anyone had ever put anything in their module POD asking 
for donations, and if it worked. I wrote something up I was thinking of 
adding to mine, and I was wondering if people thought this was too tacky..


Here's what I wrote ...


=head1 DONATIONS

If you'd like to thank me for the work I've done on this module,
please consider making a donation to me via PayPal (send  in thanks. I
spend a lot of free time creating free software, and would
appreciate any support you'd care to offer.

Please note that I am Bnot suggesting that you Bmust do this
in order for to continue working on this module. I will continue
to do so, inasmuch as I have in the past, for as long as it
interests me.

Similarly, a donation made in this way will probably not make me
work on this module much more, unless I get so many donations
that I can consider working on free software full time, which
seems unlikely at best.


/*==
VegGuide.Org
Your guide to all that's veg
==*/