Re: Proposal: Test::Refcount

2008-07-16 Thread Aristotle Pagaltzis
* Paul LeoNerd Evans [EMAIL PROTECTED] [2008-07-14 23:20]:
 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.

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

?

Regards,
-- 
Aristotle Pagaltzis // http://plasmasturm.org/


Re: Proposal: Test::Refcount

2008-07-16 Thread Paul LeoNerd Evans
On Tue, 15 Jul 2008 19:16:08 -0700
Joshua ben Jore [EMAIL PROTECTED] wrote:

   *Devel::RefCount::refcount = \Devel::Peek::SvREFCNT;

No it isn't.

Devel::Peek::SvREFCNT counts the refcount of the SV itself that is passed
to it. Mine counts the refcount of the RV contained in a reference value.

As is even printed in the docs:

 This differs from Devel::Peek::SvREFCNT in that SvREFCNT() gives the
 reference count of the SV object itself that it is passed, whereas
 refcount() gives  the count of the object being pointed to. This allows
 it to give the count of any referent (i.e. ARRAY, HASH, CODE, GLOB and
 Regex types) as well.

Consider:

 my $array = [];
 my $otherref = $array;

 Devel::Peek::SvREFCNT($array) = 1
 Devel::Refcount::refcount($array) = 2


-- 
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-15 Thread Ovid
--- On Mon, 14/7/08, Ivan Wills [EMAIL PROTECTED] wrote:

  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.

++

The B modules are incredibly powerful, poorly documented pieces of crap.  They 
may be great, but without documentation on how to use that speedboat, it's so 
much scrap metal.

Cheers,
Ovid
--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Tech blog- http://use.perl.org/~Ovid/journal/
Twitter  - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6



Re: Proposal: Test::Refcount

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

GLOB   = \*SomeNewName,

Also, this one isn't a fair test. Any real object code in a module would
probably just pass out a new IO handle (as from socket(), socketpair(),
pipe(), etc...) or else generate one using Symbol::gensym(). If I use
gensym() in this test, that becomes happy too.

Still no idea on the CODE though.

-- 
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-15 Thread Paul LeoNerd Evans
On Tue, 15 Jul 2008 00:11:10 -0700 (PDT)
Ovid [EMAIL PROTECTED] wrote:

 The B modules are incredibly powerful, poorly documented pieces of crap.
 They may be great, but without documentation on how to use that speedboat,
 it's so much scrap metal.

So... is this a vote in favour of better docs, or a wrapper module to
hide the magicness?

-- 
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-15 Thread Sawyer X
Both! :)

On Tue, Jul 15, 2008 at 10:20 AM, Paul LeoNerd Evans
[EMAIL PROTECTED] wrote:
 On Tue, 15 Jul 2008 00:11:10 -0700 (PDT)
 Ovid [EMAIL PROTECTED] wrote:

 The B modules are incredibly powerful, poorly documented pieces of crap.
 They may be great, but without documentation on how to use that speedboat,
 it's so much scrap metal.

 So... is this a vote in favour of better docs, or a wrapper module to
 hide the magicness?

 --
 Paul LeoNerd Evans

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



Re: Proposal: Test::Refcount

2008-07-15 Thread Ovid
--- On Tue, 15/7/08, Paul LeoNerd Evans [EMAIL PROTECTED] wrote:

  The B modules are incredibly powerful, poorly
 documented pieces of crap.
  They may be great, but without documentation on how to
 use that speedboat,
  it's so much scrap metal.
 
 So... is this a vote in favour of better docs, or a wrapper
 module to hide the magicness?

People who have the ability to document the B:: modules (not me) don't seem to 
have the inclination and I doubt this will change any time soon.  (This 
frustrating, but hey, it's free software and I'm grateful there's at least 
*something* there).  So I'd vote for the wrapper.

Cheers,
Ovid
--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Tech blog- http://use.perl.org/~Ovid/journal/
Twitter  - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6



Re: Proposal: Test::Refcount

2008-07-15 Thread Joshua ben Jore
On Tue, Jul 15, 2008 at 6:08 AM, Paul LeoNerd Evans
[EMAIL PROTECTED] wrote:
 I've relented now, and written a Devel::Refcount; see

  http://search.cpan.org/~pevans/Devel-Refcount-0.01/lib/Devel/Refcount.pm

Your function is already core.

  *Devel::RefCount::refcount = \Devel::Peek::SvREFCNT;

Josh


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: 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 $,=$