Subject: | delete_observer() stringifies observer references |
This is an issue with Class-Observable-1.04
When delete_observer() is called any observer references in $O are
converted to strings. This means that coderefs and object refs get
interpreted as package names - you'll get an error like:
"Failed to send observation from '$OBSERVABLE_OBJECT' to
'CODE(0x89a1ea8)': Can't locate object method "update" via package
"CODE(0x89a1ea8)"
Attached is a patch against v1.04 which fixes the problem. Includes a
test file (t/delete.t)
Subject: | class-observable.diff |
diff -ruN Class-Observable-1.04/lib/Class/Observable.pm Class-Observable-1.04-patched/lib/Class/Observable.pm
--- Class-Observable-1.04/lib/Class/Observable.pm 2004-10-16 18:46:32.000000000 +0200
+++ Class-Observable-1.04-patched/lib/Class/Observable.pm 2006-05-26 15:52:15.000000000 +0200
@@ -40,7 +40,7 @@
unless ( ref $O{ $item } eq 'ARRAY' ) {
return 0;
}
- my %ok_observers = map { $_ => 1 } @{ $O{ $item } };
+ my %ok_observers = map { $_ => $_ } @{ $O{ $item } };
foreach my $observer_to_remove ( @observers_to_remove ) {
$item->observer_log( "Removing observer '$observer_to_remove' from ",
"'", _describe_item( $item ), "'" );
@@ -50,7 +50,7 @@
"removing..." );
}
}
- $O{ $item } = [ keys %ok_observers ];
+ $O{ $item } = [ values %ok_observers ];
return scalar keys %ok_observers;
}
diff -ruN Class-Observable-1.04/MANIFEST Class-Observable-1.04-patched/MANIFEST
--- Class-Observable-1.04/MANIFEST 2004-10-16 18:46:49.000000000 +0200
+++ Class-Observable-1.04-patched/MANIFEST 2006-05-26 15:54:32.000000000 +0200
@@ -7,5 +7,5 @@
t/inherited.t
t/DeeJay.pm
t/Song.pm
-
+t/delete.t
META.yml Module meta-data (added by MakeMaker)
diff -ruN Class-Observable-1.04/t/delete.t Class-Observable-1.04-patched/t/delete.t
--- Class-Observable-1.04/t/delete.t 1970-01-01 01:00:00.000000000 +0100
+++ Class-Observable-1.04-patched/t/delete.t 2006-05-26 16:01:00.000000000 +0200
@@ -0,0 +1,53 @@
+#!/usr/local/bin/perl -w
+
+use strict;
+use Test::More tests => 6;
+
+package Something;
+use base 'Class::Observable';
+
+sub new {
+ return bless {},$_[0];
+}
+
+sub test {
+ my $self = shift;
+ $self->notify_observers("test!");
+}
+
+package main;
+
+my $test = Something->new;
+
+sub update1 {
+ ok("update1 called");
+}
+
+sub update2 {
+ ok("update2 called");
+}
+
+sub update3 {
+ ok("update3 called");
+}
+
+sub update4 {
+ ok("update4 called");
+}
+
+
+$test->add_observer(\&update1);
+$test->add_observer(\&update2);
+
+Something->add_observer(\&update3);
+Something->add_observer(\&update4);
+
+$test->test();
+
+$test->delete_observer(\&update1);
+
+Something->delete_observer(\&update3);
+
+$test->test();
+
+