Glib
view release on metacpan or search on metacpan
$my->signal_handler_block ($id_b);
$my->signal_handler_unblock ($id_b);
ok($my->signal_handler_is_connected ($id_b), 9);
$my->signal_handler_disconnect ($id_b);
$my->something_changed;
# attempting to marshal the wrong number of params should croak.
# this is part of the emission process going wrong, not a handler,
# so it's a bug in the calling code, and thus we shouldn't eat it.
eval { $my->test_marshaler (); };
ok( $@ =~ m/Incorrect number/, 10, "signal_emit barfs on bad input" );
$my->test_marshaler (qw/foo bar 15/, $my);
pass(11);
my $id = $my->signal_connect (test_marshaler => sub {
ok( $_[0] == $my &&
$_[1] eq 'foo' &&
$_[2] && # string bar is true
$_[3] == 15 && # expect an int
$_[4] == $my && # object passes unmolested
$_[5][1] eq 'two' # user-data is an array ref
,
13,
"marshalling"
);
return 77.1;
}, [qw/one two/, 3.1415]);
ok($id, 12);
$my->test_marshaler (qw/foo bar/, 15, $my);
pass(14);
$my->signal_handler_disconnect ($id);
# here's a signal handler that has an exception.
# we should be able to emit the signal all we like without catching
# exceptions here, because we don't care what other people may have
# connected to the signal. the signal's exception can be caught with
# an installed exception handler.
$id = $my->signal_connect (test_marshaler => sub {
# signal handlers are always eval'd, so
# $@ should be empty.
warn "internal problem: \$@ is not empty in "
. "signal handler!!!" if $@;
die "ouch"
});
my $tag;
$tag = Glib->install_exception_handler (sub {
ok( $tag, 16, "exception_handler" );
0 # returning FALSE uninstalls
}, [qw/foo bar/, 0]);
ok($tag, 15, "installed exception handler");
# the exception in the signal handler should not affect the value of
# $@ at this code layer.
$@ = 'neener neener neener';
print "# before invocation: \$@ $@\n";
$my->test_marshaler (qw/foo bar/, 4154, $my);
print "# after invocation: \$@ $@\n";
pass(17, "still alive after an exception in a callback");
ok($@ eq 'neener neener neener', 18, "$@ is preserved across signals") ||
diag "# expected 'neener neener neener'\n",
" # got '$@'";
$tag = 0;
# that was a single-shot -- the exception handler shouldn't run again.
{
local $SIG{__WARN__} = sub {
if ($_[0] =~ m/unhandled/m) {
pass(20, "unhandled exception just warns");
} elsif ($_[0] =~ m/isn't numeric/m) {
pass(19, "string value isn't numeric");
} else {
fail("got something unexpected in __WARN__: $_[0]\n");
}
};
$my->test_marshaler (qw/foo bar baz/, $my);
pass(21);
}
use Data::Dumper;
$my->signal_connect (returner => sub { pass(23); 0.5 });
# the class closure should be called in between these two
$my->signal_connect_after (returner => sub { pass(25); 42.0 });
pass(22);
my $ret = $my->returner;
# we should have the return value from the last handler
ok( $ret == 42.0, 26 ) || diag("expected 42.0, got $ret");
# now with our special accumulator
$my->signal_connect (list_returner => sub { pass(28); 10 });
$my->signal_connect (list_returner => sub { pass(29); '15' });
$my->signal_connect (list_returner => sub { pass(30); [20] });
$my->signal_connect (list_returner => sub { pass(31); {thing => 25} });
# class closure should before the "connect_after" ones,
# and this one will stop everything by returning the magic value.
$my->signal_connect_after (list_returner => sub { pass(33, "stopper"); 42 });
# if this one is called, the accumulator isn't working right
$my->signal_connect_after (list_returner => sub { fail("shouldn't get here"); 0 });
pass(27);
print Dumper( $my->list_returner );
# Check that a signal_connect() of a non-existant signal name doesn't
# leak the subr passed to it, ie. doesn't keep it alive forever.
#
# Note $subr has to use $x or similar in its containing environment to be
# a closure. If not then it's treated as part of the mainline code and
# won't be gc'ed immediately -- or something like that.
{
my $x = 123;
my $subr = sub { return $x };
# handler to suppress the warning message from nosuchsignal
my $logid = Glib::Log->set_handler ('GLib-GObject', ['warning'], sub { });
my $sigid = $my->signal_connect ('nosuchsignal' => $subr);
Glib::Log->remove_handler ('GLib-GObject', $logid);
ok(! $sigid, 34, "'nosuchsignal' not connected");
require Scalar::Util;
Scalar::Util::weaken ($subr);
ok(! defined $subr, 35, "subr gc'ed after bad signal name");
}
}
pass(36);
__END__
Copyright (C) 2003, 2009 by the gtk2-perl team (see the file AUTHORS for the
full list)
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Library General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option) any
later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Library General Public License for more
details.
You should have received a copy of the GNU Library General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
( run in 1.782 second using v1.01-cache-2.11-cpan-39bf76dae61 )