in reply to Inherit from IO::Handle derived class

In this case, the "blah blah" in your code is used to configure the actual socket, whose handle is eventually returned.

Instead of adding your metadata into the socket, I suggest your $self be a CONTAINER class, and :

$self->{SOCKET} = $class->SUPER::new( blah blah ); $self->{OTHER_ATT} = "Whatever";
Of course, this may require manually redirecting methods you expect to inherit.
I'm not suggesting this is a 'perfect' solution - it will get you past your immediate problem.
I have not used inside-out objects, but that may be an option ....

             All great truths begin as blasphemies.
                   ― George Bernard Shaw, writer, Nobel laureate (1856-1950)

Replies are listed 'Best First'.
Re^2: Inherit from IO::Handle derived class
by halfcountplus (Hermit) on Apr 08, 2012 at 16:38 UTC
    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.
      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.

      On behalf of the many people who have worked on refining the idea of inside-out classes, we're extremely glad you're so pleased. And, yes, we actually did get a prize: the ability to do clean encapsulated OO in Perl. ;-)

      BTW, if you like the idea of inside-out objects, you're going to love the framework we've build to make them easier to use: Object::InsideOut. Using that framework, your above solution could be written like this:

      { package test; use Object::InsideOut; use IO::Socket::INET; my @socket :Field Handles(IO::Socket::INET) :Default( _make_socket() ); my @field :Field Arg(field) Get(getField); sub _make_socket :Private { return IO::Socket::INET->new( PeerAddr => '127.0.0.1:80', Proto => 'tcp', Blocking => 0 ); } sub _cleanup :Destroy { my $self = shift; print STDERR "Bye from $field[$$self]!\n"; } } my $obj = test->new(field => "okay"); print $obj->getField."\n"; print $obj->sockhost."\n"; my $two = test->new(field => "two"); print $two->getField."\n";

      I would encourage you to take a look at the module. It may quite literally turn your world inside-out.

      Damian

      FWIW, I don't think you're supposed to inherit from IO::Socket anymore, just dispatch , see "Redispatching Methods in AUTOLOAD()" in the free Modern Perl book), a loose description of how experienced and effective Perl 5 programmers work....You can learn this too.