From: Ben Morrow on

Quoth =?utf-8?B?RnLDqWTDqXJpYw==?= Perrin <fred(a)resel.fr>:
> Ben Morrow <ben(a)morrow.me.uk> writes:
>
> Unfortunately, I have to run of RHEL5 with perl 5.8.8. I'm not using
> threads, but I don't want to close that door in the future.

I'm not yet convinced there's *ever* any point using ithreads on a
system with a real fork(2).

> If I
> understand correctly [1], the problem with threads is the refaddr; if
> I use an other index that I know is unique between my objects (in my
> example, it could be the hostname of the remote server), that will
> work, right?

Yes, provided you are *certain* there will never be an overlap.

You will also need a DESTROY method to remove dead entries, which I
forgot to mention before. HUF and OIO both handle this for you.

Ben

From: Mumia W. on
On 04/22/2010 04:04 AM, Fr�d�ric Perrin wrote:
> "Mumia W." <paduille.4061.mumia.w+nospam(a)earthlink.net> writes:
>> On 04/21/2010 03:24 AM, Fr�d�ric Perrin wrote:
>>> I want to subclass Net::SSH::Expect, by adding a couple of fields to
>>> it. Using "perldoc fields" as a guide, I did the following:
>>>
>>> ---------------- 8< ----------------
>>> #!/usr/bin/perl
>>> [...]
>> Ben Morrow gave you good advice; however, if inside-out objects are
>> not your thing, Class::Struct makes it easy to create accessor methods
>> which can be inherited into other classes, e.g.:
>
> IIUC [1], I can't use that to extend Net::SSH::Expect if I don't want
> to touch its code. Do I understand correctly ?
> [...]

That's not a problem in practice. The example I posted shows how to do
it. You first create a new base class using Class::Struct, and then
inherit into a new class that you will instantiate objects with. In my
example, NewFileBase was created by Class::Struct, and NewFile was my
intended final class. NewFile inherited from both NewFileBase and
IO::File. I used IO::File in my example because I don't have
Net::SSH::Expect installed.

> [1] <http://search.cpan.org/~jesse/perl-5.12.0/lib/Class/Struct.pm#The_struct()_function>:
>> The class created by struct must not be a subclass of another class
>> other than UNIVERSAL.
>>
>> It can, however, be used as a superclass for other classes. To
>> facilitate this, the generated constructor method uses a two-argument
>> blessing. Furthermore, if the class is hash-based, the key of each
>> element is prefixed with the class name (see Perl Cookbook, Recipe
>> 13.12).
>

See ;-)

From: Frédéric Perrin on
Ben Morrow <ben(a)morrow.me.uk> writes:
> Quoth Frédéric Perrin <fred(a)resel.fr>:
> Use
> an inside-out object instead:
>
> use Scalar::Util qw/refaddr/;
>
> my %new_field;
>
> sub new {
> my $class = shift;
> my $self = $class->SUPER::new(...);
> $new_field{refaddr $self} = "something";
> }
>
> Be aware that this will fail if your program uses threads. If you can
> depend on 5.10, you can use the core Hash::Util::Fieldhash to fix this
> (and also avoid the 'refaddr'). You can also use Object::InsideOut,
> which works on older perls but is a little heavy for my taste.

Unfortunately, I have to run of RHEL5 with perl 5.8.8. I'm not using
threads, but I don't want to close that door in the future. If I
understand correctly [1], the problem with threads is the refaddr; if
I use an other index that I know is unique between my objects (in my
example, it could be the hostname of the remote server), that will
work, right?

[1] <http://www.perlfoundation.org/perl5/index.cgi?inside_out_object> writes:
> Inside-out objects based on hashes that use the memory address of the
> object as the index are not normally thread safe. In a new thread, an
> object's memory address will be different and thus all old data
> associated with that object will be lost (which also causes a memory
> leak).

Otherwise, I'll be using Object::InsideOut, which does pull in a
number of external dependencies.

>> sub new {
>> my $class = shift;
>> my $self = fields::new($class);
>> $self->SUPER::new(host => "server.invalid",
>> password => "password");
>
> This is wrong. Net::SSH::Expect->new is a class method, not an object
> method, so you should be calling it on the class.
>
> my $self = $class->SUPER::new(...);
>
> I believe (though I haven't tested it) that this will fix your original
> problem, as well, since N::S::E->new will now call fields::new with your
> classname.

Corrected. However, $self is still empty according to Dumper $self. I
haven't investigated more than that.

Thanks for your time.

--
Fred
From: PERRIN Frederic on
Frédéric Perrin <fred(a)resel.fr> writes:
> Ben Morrow <ben(a)morrow.me.uk> writes:
>> Quoth Frédéric Perrin <fred(a)resel.fr>:
>>> sub new {
>>> my $class = shift;
>>> my $self = fields::new($class);
>>> $self->SUPER::new(host => "server.invalid",
>>> password => "password");
>>
>> This is wrong. Net::SSH::Expect->new is a class method, not an
>> object method, so you should be calling it on the class.
>>
>> my $self = $class->SUPER::new(...);
>>
>> I believe (though I haven't tested it) that this will fix your
>> original problem, as well, since N::S::E->new will now call
>> fields::new with your classname.
>
> Corrected. However, $self is still empty according to Dumper $self.
> I haven't investigated more than that.

Stupid me. I had simply replaced "$self->SUPER::new" with
"$class->SUPER::new", without saving the results to $self. Of *course*
$self wasn't going to be modified by some class method... But there is
still the possibility you pointed out earlier, with names clashes.

--
Fred
From: Frédéric Perrin on
"Mumia W." <paduille.4061.mumia.w+nospam(a)earthlink.net> writes:
> On 04/21/2010 03:24 AM, Frédéric Perrin wrote:
>> I want to subclass Net::SSH::Expect, by adding a couple of fields to
>> it. Using "perldoc fields" as a guide, I did the following:
>>
>> ---------------- 8< ----------------
>> #!/usr/bin/perl
>> [...]
>
> Ben Morrow gave you good advice; however, if inside-out objects are
> not your thing, Class::Struct makes it easy to create accessor methods
> which can be inherited into other classes, e.g.:

IIUC [1], I can't use that to extend Net::SSH::Expect if I don't want
to touch its code. Do I understand correctly ?

[1] <http://search.cpan.org/~jesse/perl-5.12.0/lib/Class/Struct.pm#The_struct()_function>:
> The class created by struct must not be a subclass of another class
> other than UNIVERSAL.
>
> It can, however, be used as a superclass for other classes. To
> facilitate this, the generated constructor method uses a two-argument
> blessing. Furthermore, if the class is hash-based, the key of each
> element is prefixed with the class name (see Perl Cookbook, Recipe
> 13.12).

--
Fred