Wow, thanks for that tip about inside out objects, I had not heard of that before but love the idea! My first attempt did not quite solve the problem:
#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);
{ package test;
use IO::Socket::INET;
our @ISA = ('IO::Socket::INET');
my %field;
sub new {
my $class = shift;
my $self = bless \do {
new IO::Socket::INET(
PeerAddr => '127.0.0.1:80',
Proto => 'tcp',
Blocking => 0
);
}, $class;
$field{$self} = shift;
return $self;
}
sub getField {
my $self = shift;
return $field{$self};
}
sub DESTROY {
my $self = shift;
delete $field{$self};
$self->SUPER::DESTROY();
print STDERR "Bye!\n";
}
1; }
my $obj = test->new('okay');
print $obj->getField."\n";
print $obj->sockhost."\n";
Result:
root~/perl»./test1.pl
okay
Not a GLOB reference at /usr/lib64/perl5/5.14.2/x86_64-linux-thread-mu
+lti/IO/Socket.pm line 246.
Bye!
Note that changing the last line to $$obj->sockhost will make it work, but I'd prefer this be a normal subclass. So tweaking the inside-out constructor a bit, since IO::Socket::new() returns a glob ref to start with:
#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);
{ package test;
use IO::Socket::INET;
our @ISA = ('IO::Socket::INET');
my %field;
sub new {
my $class = shift;
my $self = $class->SUPER::new (
PeerAddr => '127.0.0.1:80',
Proto => 'tcp',
Blocking => 0
);
$field{$self} = pop;
return $self;
}
sub getField {
my $self = shift;
return $field{$self};
}
sub DESTROY {
my $self = shift;
delete $field{$self};
$self->SUPER::DESTROY();
print STDERR "Bye!\n";
}
1; }
my $obj = test->new("okay");
print $obj->getField."\n";
print $obj->sockhost."\n";
my $two = test->new("two");
print $two->getField."\n";
Bingo:
root~/perl»./test2.pl
okay
127.0.0.1
two
Bye!
Bye!
Thanks much. Besides making this possible (and guaranteeing I won't get into namespace entanglements with superclass members), I really like the idea of genuine encapsulation in perl. Etc.
"Inside out". That is freaking brilliant. Somebody deserves a prize for that one.
|