Glib-Ex-ObjectBits

 view release on metacpan or  search on metacpan

lib/Glib/Ex/FreezeNotify.pm  view on Meta::CPAN

Even in simple code an error can be thrown for a bad property name in a
C<set()>, or while calculating a value.  (Though as of Glib-Perl 1.222 an
invalid argument type to C<set()> generally only provokes warnings.)

=head2 Operation

FreezeNotify works by having C<thaw_notify()> in the destroy code of the
FreezeNotify object.

FreezeNotify only holds weak references to its objects, so the mere fact
they're due for later thawing doesn't keep them alive if nothing else cares
whether they live or die.  The effect is that frozen objects can be garbage
collected within a freeze block at the same point they would be without any
freezing, instead of extending their life to the end of the block.

It works to have multiple freeze/thaws, done either with FreezeNotify or
with other C<freeze_notify()> calls.  C<Glib::Object> simply counts
outstanding freezes, which means they don't have to nest, so multiple
freezes can overlap in any fashion.  If you're freezing for an extended time
then a FreezeNotify object is a good way not to lose track of the thaws,
although anything except a short freeze for a handful of C<set_property()>

lib/Glib/Ex/TieProperties.pm  view on Meta::CPAN

things, but you can control it with the C<field> parameter,

    Glib::Ex::TieProperties->in_object ($object,
                                        field => 'xyzzy')
    print $object->{'xyzzy'}->{'border-width'};

=back

The C<weak> parameter described above is always set on a tied hash
established by C<in_object()> so that it's not a circular reference which
would keep C<$object> alive forever.

=back

=head1 TIED OBJECT FUNCTIONS

The tie object associated with the hash, which is returned by the C<tie> or
obtained later with C<tied()>, has the following methods.

=over 4

t/FreezeNotify.t  view on Meta::CPAN

{
  my $obj = Foo->new;
  my $notified = 0;
  $obj->signal_connect (notify => sub { $notified = 1; });

  {
    my $freezer = Glib::Ex::FreezeNotify->new ($obj);
    ok (! $notified);
    $obj->set (myprop_one => 1);
    $obj->set (myprop_two => 1);
    ok (! $notified, 'freezer alive, no notify yet');
  }
  ok ($notified, 'notify goes out after freezer dies');
}

# notify goes out on two objects when $freezer dies
{
  my $obj1 = Foo->new;
  my $obj2 = Foo->new;
  my $notified1 = 0;
  my $notified2 = 0;
  $obj1->signal_connect (notify => sub { $notified1 = 1; });
  $obj2->signal_connect (notify => sub { $notified2 = 1; });

  {
    my $freezer = Glib::Ex::FreezeNotify->new ($obj1, $obj2);
    $obj1->set (myprop_one => 1);
    $obj2->set (myprop_two => 1);
    ok (! $notified1, 'freezer alive, no notify obj1 yet');
    ok (! $notified2, 'freezer alive, no notify obj2 yet');
  }
  ok ($notified1, 'notify obj1 goes out after freezer dies');
  ok ($notified2, 'notify obj2 goes out after freezer dies');
}

{
  my $obj = Foo->new;
  my $notified = 0;
  $obj->signal_connect (notify => sub { $notified = 1; });

t/FreezeNotify.t  view on Meta::CPAN

  };

  eval {
    my $freezer = Glib::Ex::FreezeNotify->new ($obj);
    $obj->set (myprop_one => 1);
    ok (! $notified, "notify hasn't gone before the die");
    die "an error";
  };
  ok ($notified, 'notify has gone out after the die');
  is ($die_notified, 0,
     'SIG{__DIE__} runs inside the eval, so the freezer object is still alive and not yet done its thaw');
}

{
  my $obj = Foo->new;
  my $freezer = Glib::Ex::FreezeNotify->new ($obj);
  Scalar::Util::weaken ($obj);
  ok (! defined $obj, "doesn't keep a hard reference to its object");
}

# doesn't keep a hard reference to either of two objects



( run in 1.524 second using v1.01-cache-2.11-cpan-39bf76dae61 )