Give signal handlers within an object access to $self by defining them with an anonymous subroutine. Updated: to reflect additional comments below about establishing per-object signal handlers.
sub set_signal_handlers { my $self=shift; $SIG{USR1}=sub { $self->handler_USR1() } ... } sub handler_USR1 { my $self=shift; # Now I can access the object through $self }
And call $object->set_signal_handlers() after creating the object (or $self->set_signal_handlers() from within the object itself).
As pointed out below, the above technique has the problem that signal handlers in Unix are per-process, so if more than one object sets a signal handler for the same signal using the technique above, only one of them will be executed. The following code solves this problem (slightly modified from code below, and combining my code with chromatic's) by using a single per-class signal handler, and a hash in which the specific per-object handlers are stored as code references. When the per-class handler is called, it calls all the per-object handlers in sequence. I wonder if this could be declared a belonging to class UNIVERSAL and then have every object in your program use it :-)
package Obj; # Class variable $handlers={}; sub new { my $class = shift; my $self = { @_ }; bless $self, $class; $self->set_signal_handlers; $self; } sub name { shift->{'name'}; } sub set_signal_handlers { my $self = shift; # Set handlers for USR1 if (!$handlers{USR1}) { # Class signal handler, only set the first time $SIG{USR1} = sub { class_handle_signal('USR1'); }; } # You could index by $self->name, or by any other identifier $handlers->{USR1}->{$self} = $self->handle_USR1(); # Set handlers for USR1 if (!$handlers{USR2}) { $SIG{USR2} = sub { class_handle_signal('USR2'); } } $handlers->{USR2}->{$self} = $self->handle_USR2(); } sub handle_USR1 { my $self = shift; return sub { print "handling USR1 for ", $self->name, "\n"; } } sub handle_USR2 { my $self = shift; return sub { print "handling USR2 for ", $self->name, "\n"; } } sub class_handle_signal { my $sig=shift; foreach (keys %{$handlers->{$sig}}) { &{$handlers->{$sig}->{$_}}(); } } package main; my $obj1 = new Obj(name => 'obj1'); my $obj2 = new Obj(name => 'obj2'); while (1) { }