Hello All,
I have created new, optimized, version of my previsous patch.
It keeps the semantics (except getters and setters can't be overriden by
inheritance -- well, that's what globs are for) of the previous patch.
That is default GET_PROPERTY/SET_PROPERTY will call GET_$propname resp.
SET_$propname, if they are defined. However, it is now optimized.
The basic idea is, that when we set GET_PROPERTY/SET_PROPERTY in
check-block generated by import, we can do the same with the individual
getters/settters.
The getters and setters are closures, so they don't need to call
->get_name second time. The GET/SET_PROPERTY are closures too, so they
know the right package (it can't be easily found from $self).
-------------------------------------------------------------------------------
Jan 'Bulb' Hudec <bulb ucw cz>
--- orig/Subclass.pm 2004-04-12 01:03:07.000000000 +0200
+++ mod/Subclass.pm 2004-05-11 22:55:38.000000000 +0200
@@ -143,10 +143,24 @@
Get a property value, see C<SET_PROPERTY>.
-The default implementation looks like this:
+The default implementation calls function C<&{"GET_".$pspec->get_name}>.
- my ($self, $pspec) = @_;
- return $self->{$pspec->get_name};
+=item GET_$propname $self, $pspec [not a method]
+
+This will be called by default C<GET_PROPERTY> for property $propname. It
+should return the property value. $propname is exactly as given in the property
+declaration, including possible non-word characters. These functions are not
+used if you define C<GET_PROPERTY>.
+
+The default implementation just retrns:
+
+ $self->{$propname}
+
+Note, that $propname is not passed as argument.
+
+Also note, that perl can handle symbols with funny names (eg. containing C<->).
+Just you can only access them with symbolic references. The C<GET/SET_PROPERTY>
+do exactly that.
=item SET_PROPERTY $self, $pspec, $newval [not a method]
@@ -162,10 +176,22 @@
default get and set methods store property data in the object as hash
values named for the parameter name.
-The default C<SET_PROPERTY> looks like this:
+The default implementation calls function C<&{"SET_".$pspec->get_name}>.
+
+=item SET_$propname $self, $newval, $pspec [not a method]
+
+This will be called by default C<SET_PROPERTY> for property $propname. It
+should set new value of the property. $propname is exactly as given in the
+property declaration, including possible non-word characters. These functions
+are not used if you define C<SET_PROPERTY>.
- my ($self, $pspec, $newval) = @_;
- $self->{$pspec->get_name} = $newval;
+Default implementation does just:
+
+ $self->{$propname} = $newval
+
+Again, note that $propname is not passed as argument. Also note, that the order
+of arguments is reversed from C<SET_PROPERTY>, so you can simply ignore the
+$pspec.
=item FINALIZE_INSTANCE $self [not a method]
@@ -198,26 +224,37 @@
*new = \&Glib::Object::new;
-sub GET_PROPERTY {
- my ($self, $pspec) = @_;
- $self->{$pspec->get_name};
-}
-
-sub SET_PROPERTY {
- my ($self, $pspec, $newval) = @_;
- $self->{$pspec->get_name} = $newval;
-}
-
sub import {
my ($self, $superclass, %arg) = @_;
my $class = caller;
+ my @props = map { $_->get_name(); } @{$arg{properties}};
# the CHECK callback will be executed after the module is compiled
my $check = sub {
# "optionally" supply defaults
- for (qw(new GET_PROPERTY SET_PROPERTY)) {
- defined &{"$class\::$_"}
- or *{"$class\::$_"} = \&$_;
+ # default for new...
+ *{"$class\::new"} = \&new unless(defined &{"$class\::new"});
+ # default for GET_PROPERTY ...
+ unless(defined &{"$class\::GET_PROPERTY"}) {
+ *{"$class\::GET_PROPERTY"} = sub { # (0:self, 1:pspec)
+ &{"$class\::GET_".$_[1]->get_name}(@_);
+ };
+ # default GET_PROPERTY requires getters...
+ for my $p (@props) {
+ defined &{"$class\::GET_$p"}
+ or *{"$class\::GET_$p"} = sub { $_[0]->{$p}; };
+ }
+ }
+ # default for SET_PROPERTY ...
+ unless(defined &{"$class\::SET_PROPERTY"}) {
+ *{"$class\::SET_PROPERTY"} = sub { # (0:self, 1:pspec, 2:newval)
+ &{"$class\::SET_".$_[1]->get_name}($_[0], $_[2], $_[1]);
+ };
+ # default SET_PROPERTY requires setters...
+ for my $p (@props) {
+ defined &{"$class\::SET_$p"}
+ or *{"$class\::SET_$p"} = sub { $_[0]->{$p} = $_[1]; };
+ }
}
};
eval "package $class; CHECK { &\$check }";
Attachment:
signature.asc
Description: Digital signature