Home > Archive > PERL Miscellaneous > March 2004 > Signal handling in objects. Good idea? Best practices?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Signal handling in objects. Good idea? Best practices?
|
|
| Carlton Brown 2004-03-27, 12:01 am |
| Is it "right" to try to define signal handlers in a class, or should
this be handled elsewhere such as the implementation code? How should
I be thinking about this problem?
I am trying to write a class where instances will execute a "cleanup"
method in response to a SIGINT. (At this point the method is just a
single print statement). It won't work regardless of whether I define
the handler as class data or instance data. The signal gets caught as
evidenced by ^C not breaking the execution. However, the cleanup
method never gets executed on the INT... stranglely, it executes once
at startup. (i have it stripped down to a single print statement).
This is confusing, I'd figure it would either work or throw a compile
error about the subroutine not being defined.
The lack of newsgroup activity on this subject suggests that this may
be the Wrong Strategy but I thought I'd check first.
# Implementation code
#!/usr/local/bin/perl
push(@INC,".");
use Booger;
$myBoog = new Booger;
while (true) {
print ".";
sleep 1;
}
# Class module
package Booger;
BEGIN {
use Exporter();
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(new gripe);
}
sub new($) {
my $classname = shift;
my $self = {};
bless($self, $classname);
warn "Created object of type $classname";
$SIG{'INT'} = $self->gripe();
return $self;
}
sub gripe($) {
my $self = shift;
print "What do you want?\n";
}
return 1;
| |
| A. Sinan Unur 2004-03-27, 12:01 am |
| carltonbrown@hotmail.com (Carlton Brown) wrote in
news:aa611a32.0403251545.2c484b80@posting.google.com:
> Is it "right" to try to define signal handlers in a class, or should
> this be handled elsewhere such as the implementation code? How should
> I be thinking about this problem?
....
> method never gets executed on the INT... stranglely, it executes once
> at startup.
See below. It is not that strange.
> # Implementation code
> #!/usr/local/bin/perl
> push(@INC,".");
> use Booger;
> $myBoog = new Booger;
> while (true) {
> print ".";
> sleep 1;
> }
>
> # Class module
> package Booger;
>
> BEGIN {
> use Exporter();
> $VERSION = 1.00;
> @ISA = qw(Exporter);
> @EXPORT = qw(new gripe);
> }
>
> sub new($) {
> my $classname = shift;
> my $self = {};
> bless($self, $classname);
> warn "Created object of type $classname";
> $SIG{'INT'} = $self->gripe();
Here you assign to $SIG{'INT'} the return value of the $self->gripe()
method call. That is why you see the statement printed once at object
creation time.
> return $self;
> }
>
> sub gripe($) {
> my $self = shift;
> print "What do you want?\n";
> }
> return 1;
I am not going to be able to speak to design issues except to note that I
would find it odd to have 10 different signal handlers for the same
signal.
I also do not know the correct syntax for obtaining to references to
methods of on object and too lazy right now to look it up.
However, the following might help:
sub gripe {
my $self = shift;
return sub {
print "What do you want?\n";
}
}
Also, if you want to see those dots, make sure to turn autoflush on for
STDOUT.
$| = 1;
--
A. Sinan Unur
1usa@llenroc.ude (reverse each component for email address)
| |
| A. Sinan Unur 2004-03-27, 12:01 am |
| carltonbrown@hotmail.com (Carlton Brown) wrote in
news:aa611a32.0403251545.2c484b80@posting.google.com:
> # Implementation code
> #!/usr/local/bin/perl
> push(@INC,".");
> use Booger;
> $myBoog = new Booger;
> while (true) {
What is this?
--
A. Sinan Unur
1usa@llenroc.ude (reverse each component for email address)
| |
| Tad McClellan 2004-03-27, 12:01 am |
| A. Sinan Unur <1usa@llenroc.ude> wrote:
> carltonbrown@hotmail.com (Carlton Brown) wrote in
> news:aa611a32.0403251545.2c484b80@posting.google.com:
>
> What is this?
An infinite loop.
What I want to know is why "use strict" doesn't complain about it?
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
| |
| Tad McClellan 2004-03-27, 12:01 am |
| Carlton Brown <carltonbrown@hotmail.com> wrote:
> #!/usr/local/bin/perl
You should ask for all the help you can get:
use strict;
use warnings;
> push(@INC,".");
That happens at runtime.
> use Booger;
That happens at compile-time.
If perl needs the cwd to find Booger.pm, that isn't going to work.
perldoc -q include
How do I add a directory to my include path at runtime?
> while (true) {
Strings should *look like* strings, ie. with quotes.
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
| |
| Martien Verbruggen 2004-03-27, 12:01 am |
| On Thu, 25 Mar 2004 22:20:32 -0600,
Tad McClellan <tadmc@augustmail.com> wrote:
> A. Sinan Unur <1usa@llenroc.ude> wrote:
>
>
>
> An infinite loop.
>
>
>
> What I want to know is why "use strict" doesn't complain about it?
I believe it has something to do with constant folding and
optimisation, and strict checks happening after that. I just vaguely
recall something about that being brought up on p5p at some point in
the past.
This croaks:
use strict;
while($a = true) { }
This doesn't:
use strict;
while(true) { }
Also:
$ perl -MO=Deparse -Mstrict -e 'while ($a = true) {}'
Bareword "true" not allowed while "strict subs" in use at -e line 1.
-e had compilation errors.
while ($a = 'true') {
();
}
and
$ perl -MO=Deparse -Mstrict -e 'while (true) {}'
for (;;) {
();
}
-e syntax OK
As you can see, Perl compiles the two in totally different manners,
having removed the "constant true value" without side effects from the
statement.
Martien
--
|
Martien Verbruggen | +++ Out of Cheese Error +++ Reinstall
Trading Post Australia | Universe and Reboot +++
|
| |
| Anno Siegel 2004-03-27, 12:01 am |
| A. Sinan Unur <1usa@llenroc.ude> wrote in comp.lang.perl.misc:
> carltonbrown@hotmail.com (Carlton Brown) wrote in
> news:aa611a32.0403251545.2c484b80@posting.google.com:
>
[...]
[color=darkred]
>
> Here you assign to $SIG{'INT'} the return value of the $self->gripe()
> method call. That is why you see the statement printed once at object
> creation time.
>
>
> I am not going to be able to speak to design issues except to note that I
> would find it odd to have 10 different signal handlers for the same
> signal.
>
> I also do not know the correct syntax for obtaining to references to
> methods of on object and too lazy right now to look it up.
my $coderef = $self->can( 'gripe');
However, the automatic calls to $SIG{INT} aren't method calls, so putting
that in $SIG{INT} won't work right with "real" methods (as opposed to
ones that ignore their first argument). It also freezes method resolution
to the moment when $SIG{INT} is set, so dynamic changes in inheritance
wouldn't be honored.
The new() method could do this:
$SIG{'INT'} = sub { $self->gripe };
That would call ->gripe correctly and do method dispatch each time.
To OP: The prototypes ($) in method definitions are ignored. They
shouldn't be there.
Anno
| |
| Carlton Brown 2004-03-27, 12:01 am |
| Tad McClellan <tadmc@augustmail.com> wrote in message news:<slrnc67cuq.mh9.tadmc@magna.augustmail.com>...
> Carlton Brown <carltonbrown@hotmail.com> wrote:
>
>
>
> You should ask for all the help you can get:
The minor pecadillos are duly noted, but neither they nor the
stricture messages shed any light on the larger question of if, why,
whether, or how one would design signal handlers into objects. The
toy program was not a debugging request, it was to illustrate how I
attempted to approach the problem (Also to anticipate the question
"What did you try?").
| |
| Carlton Brown 2004-03-27, 12:01 am |
| anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote in message news:<c410do$ad1$1@mamenchi.zrz.TU-Berlin.DE>...
> my $coderef = $self->can( 'gripe');
>
> However, the automatic calls to $SIG{INT} aren't method calls, so putting
> that in $SIG{INT} won't work right with "real" methods (as opposed to
> ones that ignore their first argument). It also freezes method resolution
> to the moment when $SIG{INT} is set, so dynamic changes in inheritance
> wouldn't be honored.
>
> The new() method could do this:
>
> $SIG{'INT'} = sub { $self->gripe };
>
> That would call ->gripe correctly and do method dispatch each time.
Thank you for the clarification. I will try this and see how it works
out.
I am sure it will work programmatically, but what do you think about
this practice in general? Is it a "good idea" to have per-object
signal handlers? From the example you have given, it seems that it
could only be done by an instance method and not a class method, would
you agree with that statement?
| |
| Richard Morse 2004-03-27, 12:01 am |
| In article <aa611a32.0403260658.348c75e7@posting.google.com>,
carltonbrown@hotmail.com (Carlton Brown) wrote:
> anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote in message
> news:<c410do$ad1$1@mamenchi.zrz.TU-Berlin.DE>...
>
> I am sure it will work programmatically, but what do you think about
> this practice in general? Is it a "good idea" to have per-object
> signal handlers? From the example you have given, it seems that it
> could only be done by an instance method and not a class method, would
> you agree with that statement?
Speaking completely without any idea of anything, I'm guessing that if
you wanted to use a class method, you would do something like:
$SIG{'INT'} = sub { MyClass->gripe };
I can't speak to the advisability of this though, as signal handlers are
completely out of my experience.
HTH,
Ricky
| |
| Anno Siegel 2004-03-27, 12:01 am |
| Carlton Brown <carltonbrown@hotmail.com> wrote in comp.lang.perl.misc:
> anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote in message
> news:<c410do$ad1$1@mamenchi.zrz.TU-Berlin.DE>...
>
> Thank you for the clarification. I will try this and see how it works
> out.
>
> I am sure it will work programmatically, but what do you think about
> this practice in general? Is it a "good idea" to have per-object
> signal handlers?
That can't be answered in general. Normally, sig handlers deal with
the program as a whole, but other applications exist. It may make
sense to have a signal change a single object, but only you can tell.
> From the example you have given, it seems that it
> could only be done by an instance method and not a class method, would
> you agree with that statement?
Huh? You can call a class method just as easily:
$SIG{'INT'} = sub { Class->gripe }; # I forget what you called your class
Also, an object method can act like a class method; all it has to do
is ignore the specific object and use its class, if needed.
Anno
| |
| Anno Siegel 2004-03-27, 12:01 am |
| Carlton Brown <carltonbrown@hotmail.com> wrote in comp.lang.perl.misc:
> Tad McClellan <tadmc@augustmail.com> wrote in message
> news:<slrnc67cuq.mh9.tadmc@magna.augustmail.com>...
>
> The minor pecadillos are duly noted, but neither they nor the
> stricture messages shed any light on the larger question of if, why,
> whether, or how one would design signal handlers into objects. The
> toy program was not a debugging request, it was to illustrate how I
> attempted to approach the problem (Also to anticipate the question
> "What did you try?").
The question here isn't so much "What did you try?", but "What are you
up to?".
What your example does can't be described as "design(ing) signal handlers
into objects". What you do is install an object-specific signal handler.
That may make sense (or be a design error) in so many ways, it is
impossible to say anything general.
What is strange is that you do this in the new() method. That means
another object controls the signal handler each time you create one.
I fail to see a scenario where this makes sense, though there may be
one. I wonder why *this* is in the example code.
Anno
|
|
|
|
|