Re: Learning Objects, destroy methods

2004-01-07 Thread Gary Stainburn
On Tuesday 06 January 2004 6:09 pm, Randal L. Schwartz wrote:
> > "Gary" == Gary Stainburn <[EMAIL PROTECTED]> writes:
>
> Gary> My idea is to keep only the %_BLOCKS as a strong ref and weaken
> Gary> all others.  That way, I can guarantee that when I delete that
> Gary> ref the object will be destroyed.
>
> I do believe you want it the other way around.

Hi Randal,

I've read the column you mentioned in a previous post, and I see what you mean 
with the above statement.

However, I believe what I am right for the effects I want.

my %_BLOCKS is the equivelent of your %REGISTRY, and when a block gets created 
I add it to %_BLOCKS.  However, I want that block to remain after the block 
that created it has finished - hence keeping it as a strong ref. (think init 
function which reads track definition from file then exits)

I also want to be confident that when I want to delete the block the object is 
actually deleted, hence weakening ALL other references to it.

However, as I said in a response to Rob, provided I don't do sloppy coding the 
problem should never arise anyway.
-- 
Gary Stainburn
 
This email does not contain private or confidential material as it
may be snooped on by interested government parties for unknown
and undisclosed purposes - Regulation of Investigatory Powers Act, 2000 


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-06 Thread Randal L. Schwartz
> "Gary" == Gary Stainburn <[EMAIL PROTECTED]> writes:

Gary> My idea is to keep only the %_BLOCKS as a strong ref and weaken
Gary> all others.  That way, I can guarantee that when I delete that
Gary> ref the object will be destroyed.

I do believe you want it the other way around.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-06 Thread Gary Stainburn
On Tuesday 06 Jan 2004 2:08 pm, Dan Anderson wrote:
> I don't know if anybody has mentioned it yet, but check out weak
> references on CPAN:
>
> http://search.cpan.org/~lukka/WeakRef-0.01/WeakRef.pm
>
> -Dan

Thanks Dan,

Although, based on experience and responses from this thread I don't think 
that the problem will arrise ($scalars going out of scope, correctly 
structured DESTROY's to remove cyclic references etc), this looks to be a 
very effective safety net so I think I'll be using it.

My idea is to keep only the %_BLOCKS as a strong ref and weaken all others.  
That way, I can guarantee that when I delete that ref the object will be 
destroyed.
-- 
Gary Stainburn
 
This email does not contain private or confidential material as it
may be snooped on by interested government parties for unknown
and undisclosed purposes - Regulation of Investigatory Powers Act, 2000 


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-06 Thread Dan Anderson
I don't know if anybody has mentioned it yet, but check out weak
references on CPAN:

http://search.cpan.org/~lukka/WeakRef-0.01/WeakRef.pm

-Dan


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread R. Joseph Newton
Gary Stainburn wrote:

> On Monday 05 January 2004 2:09 pm, Dan Anderson wrote:
> > > My problem is one of destroying a block (object), making sure that I have
> > > no memory leakage.
> >
> > Out of curiosity, when you say memory leakage do you mean that the
> > memory persists after the Perl process exits, or just while it is
> > running?  And have you verified this?  And, is the program a daemon
> > where the memory leak will build up over time?  (i.e. if the program
> > runs for 10 minutes you may just want to bite the bullet and let the
> > memory leak -- if it gets cleaned up when the process exits)
>
> By memory leak, I meant a redundant object being kept in memory, i.e. refcount
> for the object still being >0 after calling the delete method.
>
> The program, while initially being an academic project for me to learn OOP,
> will eventually be interactive, potentially running for long periods and I
> didn't want it to keep grabbing more memory.
>
> The problem, like the project is really pretty academic.

One key for general durability is to start by limiting the numer of direct
references to any object or its member.  For instance, once a Trainset is created,
you would want to access inidividual Tracks only through the Trainset methods, and
let it find and interact with the appropriate track.  One strategy would be to
return the index of any track created, and have accessor function take an index
argument, rather than handing out direct treferences to the object.  By being
stingy with direct references to contained objects, you can be assured that when
the object is removed from the list or hash within the container, it will die.

If you can be assured of that, then you can free a whole set of objects just by
assigning the container structure to a new empty hash or array:

$self->{'tracks'} = [];

Think "One-way path of reference".

Joseph


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread R. Joseph Newton
"R. Joseph Newton" wrote:

Whoops.  Forgot the most important function.  Inine

> Overall, I would suggest that you steer clear of internal references in your
> objects when possible.  It is much better to make a container class, then delete
> contained objects from the container.  Generally you would want to avoid having
> other references to the contained objects, except through the methods of the
> container [Trainset] object.
>
> package Trainset;
>
> use strict, warnings et. al.;

use Trian;

>
>
> use Exporter;
>
> our @ISA = qw/Eporter/;
>
> sub new {
>
> sub add_track {
>my $self = shift;
>
>my $track = shift;
>push @{$self->{'tracks'}}, $track;

   return @{$self->{'tracks'}} - 1;

> }

sub track {
   my $self = shift;

   my $track = Track-new(@_);
   push @{$self->{'tracks'}}, $track;
   return @{$self->{'tracks'}} - 1;
}

Which should give you a very nice pass-through approach to creating and adding new
train objects on the fly.

Joseph


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread Randal L. Schwartz
> "Gary" == Gary Stainburn <[EMAIL PROTECTED]> writes:

Gary> I create a new track block such:

Gary> my $T1=Trainset->track('T1','Block');

Gary> This also created $Trainset::_BLOCKS{T1} which references the object.

Gary> My problem is how can I destroy the object when I no longer want it?

Yes, you need to weaken the reference in the package hash.  That's
nearly exactly the scenario I covered in
 and in my
book "Learning Perl References Objects and Modules".

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread R. Joseph Newton
Gary Stainburn wrote:

> Hi folks,
>
> My first forrey into Perl objects sees me trying to model a railway.  I've got
> a hash of named blocks of track, which is added to when I create a new block
> object.
>
> My problem is one of destroying a block (object), making sure that I have no
> memory leakage.
>
> I create a new track block such:
>
> my $T1=Trainset->track('T1','Block');
>
> This also created $Trainset::_BLOCKS{T1} which references the object.

Hi Gary,

I really think your problem comes in here.  I would always be leery of situations
where you have to use the namespace prefix explicitly.  It generally  casts too
broad a net for most purposes.  I think you are doing the right thing--sort
of--with Trainset.  This is assumig that you have a Trainset class as well as a
Track class.  I would suggest, though, that you assign new $track to your object
through $train_set, your Trainset object, rather than through the class itself.
This apporoach would give you the flexibility to have mutliple Trainset objects,
thus make your class more robust.

>
>
> My problem is how can I destroy the object when I no longer want it?
>
> If I call
>
> $T1=$T1->delete;
>
> Then the object is destroyed (display in DESTROY shows this).  However, if I
> simply call
>
> $T1->delete;
>
> The object isn't destroyed because even though the ref in %_BLOCKS is deleted,
> the ref in $T1 is still there.  Is there and way to ensure that the object is
> destroyed - i.e. force the refcount to zero?
>
> The only solution I've come up with is to explicitly call DESTROY from within
> the delete function, and within DESTROY empty the hash. Is this sufficient,
> or will this still tie up memory?  Is there a better way?
>
> --
> Gary Stainburn

Overall, I would suggest that you steer clear of internal references in your
objects when possible.  It is much better to make a container class, then delete
contained objects from the container.  Generally you would want to avoid having
other references to the contained objects, except through the methods of the
container [Trainset] object.

package Trainset;

use strict, warnings et. al.;

use Exporter;

our @ISA = qw/Eporter/;

sub new {
   my $class = shift;
   my $self = {};
   bless $self, $class;
   $self->initialize(@_);
}

sub initialize {
   my $self = shift;

   $self->{'set ID'} = shift;
   #... assign other set-level scalar info hard-coded into
   #the parameter list ...then:
   push @{$self->{'tracks'}}, (@_};  # to allow initialization with an existing
list
}

sub add_track {
   my $self = shift;

   my $track = shift;
   push @{$self->{'tracks'}}, $track;
}

...

Let your train set be one object, and your tracks be represented by another
class.  Keep each as simple and straightforward as possible.

Joseph


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread Rob Dixon

Gary Stainburn wrote:
>
> On Monday 05 January 2004 3:12 pm, Rob Dixon wrote:
> > Gary Stainburn wrote:
> [snip]
> > > sufficient, or will this still tie up memory?  Is there a better way?
> >
> > Hi Gary.
> >
> > We really need to see your 'delete' and 'DESTROY' methods. But you can get
> > around the problem by setting $T1 to anything that's not a reference to the
> > object. At present you're setting it to the result of your 'delete' method,
> > but you could equally write
> >
> >   $T1 = 99;
> > or
> >   undef $T1;
> >
> > Alternatively you could let $T1 go out of scope (at the end of a block)
> > and be implcitly deleted itself by Perl. That only works if it's a 'my'
> > variable.
> >
> > HTH,
> >
> > Rob
>
> Hi Rob,
>
> I'm pretty okay with the $T1 going out of scope, and being re-assigned, hence
> the difference between my two examples.

You seemed to think that

  $T1 = $T1->delete;

did something special, whereas it's the same as

  $T1->delete;
  $T1 = $value;

which only works because the return value from 'delete' isn't a reference to
the object (which it could quite well be).

I think you should throw away 'delete' and write just

  undef $T1; # (or let it fall out of scope)

and let the garbage collection take care of deallocating the data.

> The question was more academic, trying to cover my back in the case of bad
> programming, where a ref remained by mistake.  An unlikely event with the way
> Perl scoping works.
>
> I was really looking to see if there was a way of effectively zeroising the
> refcount for the object, this FORCing the garbage collector to free the
> memory.

Not without leaving references to a non-existent object.

> The best I've come up with is to call DESTROY from within the delete method,
> and from within there deleting all the elements in the hash and undefining
> the scalar holding the hashref.

I think you're confused here Gary. Or it may be me. You can't undefine
'the scalar holding the hashref' as you don't necessarily have access to it
from within the method. The reference to the object's data is passed to the
method as its first parameter. If I write

  package Class;

  sub new {
bless { data => 99 };
  }

  sub delete {
my $self = shift;
%$self = ();
  }

  package main;

  my $object = new Class;
  $object->delete;

Then my 'delete' method can empty the hash iteself, but can't access $object
to change its value. The line

  $object->delete;

would be better written

  undef $object;

which would make perl deallocate the hash properly instead of just leaving
a useless object containing no data.

There's nothing special at all about the 'delete' method. It's just another
object method that you can choose to write to do anything you want. Likewise
there's not much special about the DESTROY method except that is called
implicitly by Perl when the object's reference count falls to zero.

So I don't see your point about calling DESTROY from 'delete' as you can't do
anything that way that you can't do by writing extra code right there in
'delete'. DESTROY is just another subroutine in this context.

Neither DESTROY nor 'delete' have to exist; in fact it's quite unusual to see
either of them. As I said, to help you further we really need to see what these
methods are doing.

> The way I see this, the worst that would happen is that a single scalar and
> the BLESS info associated with it would remain.

It's the object data (in this case, the hash) that's blessed, not the scalar
that refers to it. If you could lie to Perl and zero the reference count
of the object then the the hash would promptly get deallocated leaving one or
more scalar references lying around pointing to something that didn't exist.
This is likely to upset Perl quite a lot, if only because when those scalar
references are destroyed (which they must be eventually) Perl will try to
cascade the destruction and delete an already-deleted object. There's no easy
way of going round finding all the references to an object and setting them to
'undef', and it would need some C code to do it at all.

> However, as I said, it's very unlikely to happen, so I don't think it's worth
> worrying about too much.  I'm thinking of mountains and mole-hills now.

Mole hills are worth considering well before they become mountains :)

Cheers,

Rob



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread Gary Stainburn
On Monday 05 January 2004 3:12 pm, Rob Dixon wrote:
> Gary Stainburn wrote:
[snip]
> > sufficient, or will this still tie up memory?  Is there a better way?
>
> Hi Gary.
>
> We really need to see your 'delete' and 'DESTROY' methods. But you can get
> around the problem by setting $T1 to anything that's not a reference to the
> object. At present you're setting it to the result of your 'delete' method,
> but you could equally write
>
>   $T1 = 99;
> or
>   undef $T1;
>
> Alternatively you could let $T1 go out of scope (at the end of a block)
> and be implcitly deleted itself by Perl. That only works if it's a 'my'
> variable.
>
> HTH,
>
> Rob

Hi Rob,

I'm pretty okay with the $T1 going out of scope, and being re-assigned, hence 
the difference between my two examples.

The question was more academic, trying to cover my back in the case of bad 
programming, where a ref remained by mistake.  An unlikely event with the way 
Perl scoping works.

I was really looking to see if there was a way of effectively zeroising the 
refcount for the object, this FORCing the garbage collector to free the 
memory.  

The best I've come up with is to call DESTROY from within the delete method, 
and from within there deleting all the elements in the hash and undefining 
the scalar holding the hashref.

The way I see this, the worst that would happen is that a single scalar and 
the BLESS info associated with it would remain.

However, as I said, it's very unlikely to happen, so I don't think it's worth 
worrying about too much.  I'm thinking of mountains and mole-hills now.
-- 
Gary Stainburn
 
This email does not contain private or confidential material as it
may be snooped on by interested government parties for unknown
and undisclosed purposes - Regulation of Investigatory Powers Act, 2000 


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread Gary Stainburn
On Monday 05 January 2004 2:09 pm, Dan Anderson wrote:
> > My problem is one of destroying a block (object), making sure that I have
> > no memory leakage.
>
> Out of curiosity, when you say memory leakage do you mean that the
> memory persists after the Perl process exits, or just while it is
> running?  And have you verified this?  And, is the program a daemon
> where the memory leak will build up over time?  (i.e. if the program
> runs for 10 minutes you may just want to bite the bullet and let the
> memory leak -- if it gets cleaned up when the process exits)

By memory leak, I meant a redundant object being kept in memory, i.e. refcount 
for the object still being >0 after calling the delete method.

The program, while initially being an academic project for me to learn OOP, 
will eventually be interactive, potentially running for long periods and I 
didn't want it to keep grabbing more memory.

The problem, like the project is really pretty academic.

>
> -Dan

-- 
Gary Stainburn
 
This email does not contain private or confidential material as it
may be snooped on by interested government parties for unknown
and undisclosed purposes - Regulation of Investigatory Powers Act, 2000 


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread Rob Dixon
Gary Stainburn wrote:
>
> My first forrey into Perl objects sees me trying to model a railway.  I've got
> a hash of named blocks of track, which is added to when I create a new block
> object.
>
> My problem is one of destroying a block (object), making sure that I have no
> memory leakage.
>
> I create a new track block such:
>
> my $T1=Trainset->track('T1','Block');
>
> This also created $Trainset::_BLOCKS{T1} which references the object.
>
> My problem is how can I destroy the object when I no longer want it?
>
> If I call
>
> $T1=$T1->delete;
>
> Then the object is destroyed (display in DESTROY shows this).  However, if I
> simply call
>
> $T1->delete;
>
> The object isn't destroyed because even though the ref in %_BLOCKS is deleted,
> the ref in $T1 is still there.  Is there and way to ensure that the object is
> destroyed - i.e. force the refcount to zero?
>
> The only solution I've come up with is to explicitly call DESTROY from within
> the delete function, and within DESTROY empty the hash. Is this sufficient,
> or will this still tie up memory?  Is there a better way?

Hi Gary.

We really need to see your 'delete' and 'DESTROY' methods. But you can get
around the problem by setting $T1 to anything that's not a reference to the
object. At present you're setting it to the result of your 'delete' method,
but you could equally write

  $T1 = 99;
or
  undef $T1;

Alternatively you could let $T1 go out of scope (at the end of a block)
and be implcitly deleted itself by Perl. That only works if it's a 'my'
variable.

HTH,

Rob



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Re: Learning Objects, destroy methods

2004-01-05 Thread Dan Anderson
> My problem is one of destroying a block (object), making sure that I have no 
> memory leakage.

Out of curiosity, when you say memory leakage do you mean that the
memory persists after the Perl process exits, or just while it is
running?  And have you verified this?  And, is the program a daemon
where the memory leak will build up over time?  (i.e. if the program
runs for 10 minutes you may just want to bite the bullet and let the
memory leak -- if it gets cleaned up when the process exits)

-Dan


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
 




Learning Objects, destroy methods

2004-01-05 Thread Gary Stainburn
Hi folks,

My first forrey into Perl objects sees me trying to model a railway.  I've got 
a hash of named blocks of track, which is added to when I create a new block 
object.

My problem is one of destroying a block (object), making sure that I have no 
memory leakage.

I create a new track block such:

my $T1=Trainset->track('T1','Block');

This also created $Trainset::_BLOCKS{T1} which references the object.

My problem is how can I destroy the object when I no longer want it?

If I call

$T1=$T1->delete;

Then the object is destroyed (display in DESTROY shows this).  However, if I 
simply call

$T1->delete;

The object isn't destroyed because even though the ref in %_BLOCKS is deleted, 
the ref in $T1 is still there.  Is there and way to ensure that the object is 
destroyed - i.e. force the refcount to zero?

The only solution I've come up with is to explicitly call DESTROY from within 
the delete function, and within DESTROY empty the hash. Is this sufficient, 
or will this still tie up memory?  Is there a better way?

-- 
Gary Stainburn
 
This email does not contain private or confidential material as it
may be snooped on by interested government parties for unknown
and undisclosed purposes - Regulation of Investigatory Powers Act, 2000 


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]