Subclass(3pm) User Contributed Perl Documentation Subclass(3pm)
NAME
Glib::Object::Subclass - register a perl class as a GObject class
SYNOPSIS
use Glib::Object::Subclass
Some::Base::Class::, # parent class, derived from Glib::Object
signals => {
something_changed => {
class_closure => sub { do_something_fun () },
flags => [qw(run-first)],
return_type => undef,
param_types => [],
},
some_existing_signal => \&class_closure_override,
},
properties => [
Glib::ParamSpec->string (
'some_string',
'Some String Property',
'This property is a string that is used as an example',
'default value',
[qw/readable writable/]
),
];
DESCRIPTION
This module allows you to create your own GObject classes, which is useful to e.g.
implement your own Gtk2 widgets.
It doesn't "export" anything into your namespace, but acts more like a pragmatic module
that modifies your class to make it work as a GObject class.
You may be wondering why you can't just bless a Glib::Object into a different package and
add some subs. Well, if you aren't interested in object parameters, signals, or having
your new class interoperate transparently with other GObject-based modules (e.g., Gtk2 and
friends), then you can just re-bless.
However, a GObject's signals, properties, virtual functions, and GInterface
implementations are specific to its GObjectClass. If you want to create a new GObject
which was a derivative of GtkDrawingArea, but adds a new signal, you must create a new
GObjectClass to which to add the new signal. If you don't, then all of the
GtkDrawingAreas in your application will get that new signal!
Thus, the only way to create a new signal or object property in the Perl bindings for Glib
is to register a new subclass with the GLib type system via Glib::Type::register_object().
The Glib::Object::Subclass module is a Perl-developer-friendly interface to this bit of
paradigm mismatch.
USAGE
This module works similar to the "use base" pragma in that it registers the current
package as a subclass of some other class (which must be a GObjectClass implemented either
in C or some other language).
The pragma requires at least one argument, the parent class name. The remaining arguments
are key/value pairs, in any order, all optional:
- properties => []
Add object properties; see "PROPERTIES".
- signals => {}
Add or override signals; see "SIGNALS" and "OVERRIDING BASE METHODS".
- interfaces => []
Add GInterfaces to your class; see "INTERFACES".
(Actually, these parameters are all passed straight through to
Glib::Type::register_object(), adding __PACKAGE__ (the current package name) as the name
of the new child class.)
OBJECT METHODS AND FUNCTIONS
The following methods are either added to your class on request (not yet implemented), or
by default unless your own class implements them itself. This means that all these methods
and functions will get sensible default implementations unless explicitly overwritten by
you (by defining your own version).
Except for "new", all of the following are functions and no methods. That means that you
should not call the superclass method. Instead, the GObject system will call these
functions per class as required, emulating normal inheritance.
$class->new (attr => value, ...)
The default constructor just calls "Glib::Object::new", which allows you to set
properties on the newly created object. This is done because many "new" methods
inherited by Gtk2 or other libraries don't have "new" methods suitable for
subclassing.
INIT_INSTANCE $self [not a method]
"INIT_INSTANCE" is called on each class in the hierarchy as the object is being
created (i.e., from "Glib::Object::new" or our default "new"). Use this function to
initialize any member data. The default implementation will leave the object
untouched.
GET_PROPERTY $self, $pspec [not a method]
SET_PROPERTY $self, $pspec, $newval [not a method]
"GET_PROPERTY" and "SET_PROPERTY" are called whenever somebody does "$object->get
($propname)" or "$object->set ($propname => $newval)" (from other languages, too).
The default implementations hold property values in the object hash, equivalent to
sub GET_PROPERTY {
my ($self, $pspec) = @_;
my $pname = $pspec->get_name;
return (exists $self->{$pname} ? $self->{$pname}
: $pspec->get_default_value); # until set
}
sub SET_PROPERTY {
my ($self, $pspec, $newval) = @_;
$self->{$pspec->get_name} = $newval;
}
Because "$pspec->get_name" converts hyphens to underscores, a property "line-style" is
in the hash as "line_style".
These methods let you store/fetch properties in any way you need to. They don't have
to be in the hash, you can calculate something, read a file, whatever.
Most often you'll write your own "SET_PROPERTY" so you can take action when a property
changes, like redraw or resize a widget. Eg.
sub SET_PROPERTY {
my ($self, $pspec, $newval) = @_;
my $pname = $pspec->get_name
$self->{$pname} = $newval; # ready for default GET_PROPERTY
if ($pname eq 'line_style') {
$self->queue_draw; # redraw with new lines
}
}
"GET_PROPERTY" is different from a C get_property method in that the perl method
returns the retrieved value. For symmetry, the $newval and $pspec args on
"SET_PROPERTY" are swapped from the C usage.
FINALIZE_INSTANCE $self [not a method]
"FINALIZE_INSTANCE" is called as the GObject is being finalized, that is, as it is
being really destroyed. This is independent of the more common DESTROY on the perl
object; in fact, you must NOT override "DESTROY" (it's not useful to you, in any case,
as it is being called multiple times!).
Use this hook to release anything you have to clean up manually. FINALIZE_INSTANCE
will be called for each perl instance, in reverse order of construction.
The default finalizer does nothing.
$object->DESTROY [DO NOT OVERWRITE]
Don't ever overwrite "DESTROY", use "FINALIZE_INSTANCE" instead.
The DESTROY method of all perl classes derived from GTypes is implemented in the Glib
module and (ab-)used for its own internal purposes. Overwriting it is not useful as it
will be called multiple times, and often long before the object actually gets
destroyed. Overwriting might be very harmful to your program, so never do that.
Especially watch out for other classes in your ISA tree.
PROPERTIES
To create gobject properties, supply a list of Glib::ParamSpec objects as the value for
the key 'properties'. There are lots of different paramspec constructors, documented in
the C API reference's Parameters and Values page, as well as Glib::ParamSpec.
As of Glib 1.060, you can also specify explicit getters and setters for your properties at
creation time. The default values in your properties are also honored if you don't set
anything else. See Glib::Type::register_object in Glib::Type for an example.
SIGNALS
Creating new signals for your new object is easy. Just provide a hash of signal names and
signal descriptions under the key 'signals'. Each signal description is also a hash, with
a few expected keys. All the keys are allowed to default.
flags => GSignalFlags
If not present, assumed to be 'run-first'.
param_types => reference to a list of package names
If not present, assumed to be empty (no parameters).
class_closure => reference to a subroutine to call as the class closure.
may also be a string interpreted as the name of a subroutine to call, but you should
be very very very careful about that.
If not present, the library will attempt to call the method named "do_signal_name" for
the signal "signal_name" (uses underscores).
You'll want to be careful not to let this handler method be a publically callable
method, or one that has the name name as something that emits the signal. Due to the
funky ways in which Glib is different from Perl, the class closures should not inherit
through normal perl inheritance.
return_type => package name for return value.
If undefined or not present, the signal expects no return value. if defined, the
signal is expected to return a value; flags must be set such that the signal does not
run only first (at least use 'run-last').
accumulator => signal return value accumulator
quoting the Glib manual: "The signal accumulator is a special callback function that
can be used to collect return values of the various callbacks that are called during a
signal emission."
If not specified, the default accumulator is used, and you just get the return value
of the last handler to run.
Accumulators are not really documented very much in the C reference, and the perl
interface here is slightly different, so here's an inordinate amount of detail for
this arcane feature:
The accumulator function is called for every handler. It is given three arguments:
the signal invocation hint as an anonymous hash (containing the signal name, notably);
the current accumulated return value; and the value returned by the most recent
handler. The accumulator must return two values: a boolean value determining whether
signal emission should continue (false stops the emission), and the new value for the
accumulated return value. (This is different from the C version, which writes through
the return_accu.)
OVERRIDING BASE METHODS
GLib pulls some fancy tricks with function pointers to implement methods in C. This is
not very language-binding-friendly, as you might guess.
However, as described above, every signal allows a "class closure"; you may override thie
class closure with your own function, and you can chain from the overridden method to the
original. This serves to implement virtual overrides for language bindings.
So, to override a method, you supply a subroutine reference instead of a signal
description hash as the value for the name of the existing signal in the "signals" hash
described in "SIGNALS".
# override some important widget methods:
use Glib::Object::Subclass
Gtk2::Widget::,
signals => {
expose_event => \&expose_event,
configure_event => \&configure_event,
button_press_event => \&button_press_event,
button_release_event => \&button_release_event,
motion_notify_event => \&motion_notify_event,
# note the choice of names here... see the discussion.
size_request => \&do_size_request,
}
It's important to note that the handlers you supply for these are class-specific, and that
normal perl method inheritance rules are not followed to invoke them from within the
library. However, perl code can still find them! Therefore it's rather important that
you choose your handlers' names carefully, avoiding any public interfaces that you might
call from perl. Case in point, since size_request is a widget method, i chose
do_size_request as the override handler.
INTERFACES
GObject supports only single inheritance; in place of multiple inheritance, GObject uses
GInterfaces. In the Perl bindings we have mostly masqueraded this with multiple
inheritance (that is, simply adding the GInterface class to the @ISA of the implementing
class), but in deriving new objects the facade breaks and the magic leaks out.
In order to derive an object that implements a GInterface, you have to tell the GLib type
system you want your class to include a GInterface. To do this, simply pass a list of
package names through the "interfaces" key; this will add these packages to your @ISA, and
cause perl to invoke methods that you must provide.
package Mup::MultilineEntry;
use Glib::Object::Subclass
'Gtk2::TextView',
interfaces => [ 'Gtk2::CellEditable' ],
;
# perl will now invoke these methods, which are part of the
# GtkCellEditable GInterface, when somebody invokes the
# corresponding lower-case methods on your objects.
sub START_EDITING { warn "start editing\n"; }
sub EDITING_DONE { warn "editing done\n"; }
sub REMOVE_WIDGET { warn "remove widget\n"; }
SEE ALSO
GObject - http://developer.gnome.org/doc/API/2.0/gobject/
AUTHORS
Marc Lehmann <schmorp AT schmorp.de>, muppet <scott at asofyet dot org>
COPYRIGHT AND LICENSE
Copyright 2003-2004 by muppet and the gtk2-perl team
This library is free software; you can redistribute it and/or modify it under the terms of
the Lesser General Public License (LGPL). For more information, see
http://www.fsf.org/licenses/lgpl.txt
perl v5.10.0 2008-05-04 Subclass(3pm)
Generated by $Id: phpMan.php,v 4.49 2006/02/26 13:18:18 chedong Exp $ Author: Che Dong
On Apache
Under GNU General Public License
2012-05-24 08:15 @38.107.179.239 Crawled by CCBot/1.0 (+http://www.commoncrawl.org/bot.html)