Re: Properties as hash keys, damn perl is cool!



On Thursday, October 30, 2003, at 10:11 PM, A. Pagaltzis wrote:

* Ross McFarland <rwmcfa1 neces com> [2003-10-30 04:13]:
that and i don't see the value in replacing $obj->set(foo =>
'bar'); with something like $object->foo('bar'); that isn't
more perlish, it's just a different and un-obvious way of doing
something already available.

I would disagree it's not more Perlish. Combined setter/getters
that set the value of a property if given parameters and return
it if not are quite Perlish;

this could be done rather simply with an AUTOLOAD, i believe, and would eliminate the need for about 50% to 70% of the functions in the bindings (gtk has a get_foo/set_foo pair for just about every property). that said, i don't think it's a great idea, because it's a fundamental deviation from the API. but you could do it like this:

<gratuitous example>

use Glib;

package Glib::Object;

sub AUTOLOAD {
        my $object = shift;

        my $method = $AUTOLOAD;
        $method =~ s/^.*:://;

        print "method : $method\n";
        $method =~ y/-/_/;

        my @properties = $object->list_properties;
        foreach my $p (@properties) {
                $p->{name} =~ y/-/_/;
                if ($p->{name} eq $method) {
                        warn "auto-creating $p->{owner_type}::$p->{name}";
                        eval "sub $p->{owner_type}::$p->{name} {
                                my \$ret = \$_[0]->get ('$p->{name}');
                                \$_[0]->set ('$p->{name}', \$_[1])
                                        if \ _ > 1;
                                return \$ret;
                        }; 1;";
                        no strict 'refs';
                        return $object->$method (@_);
                }
        }

        use Carp;
        croak "$method is not a property or valid method";
}


package Mup::Foo;

use Glib::Object::Subclass
        Glib::Object::,
        properties => [
Glib::ParamSpec->boolean ('foo-bar', 'Foo Bar', 'It\'s fubarred', 1, [qw/readable writable/]), Glib::ParamSpec->string ('whammy_bar', 'Whammy Bar', 'A wiggle stick', 'whee', [qw/readable writable/]),
        ]
        ;

sub INIT_INSTANCE {
        $_[0]->{'foo_bar'} = 1;
        $_[0]->{'whammy_bar'} = 'mama';
}

package Mup::Bar;

use Glib::Object::Subclass
        Mup::Foo::,
        properties => [
Glib::ParamSpec->int ('wiz', 'Wiz Wiz', 'wiz wiz wiz', 0, 10, 3, [qw/readable writable/]),
        ]
        ;

sub INIT_INSTANCE {
        $_[0]->{'wiz'} = 42;
}

package main;

use Data::Dumper;

my $mupfoo = Mup::Foo->new (foo_bar => 0);
my $mupbar = Mup::Bar->new;
print Dumper($mupfoo);
print Dumper($mupbar);

print "foo-bar is ".$mupfoo->foo_bar."\n";
print "set :".$mupfoo->foo_bar(1)."\n";
print "foo-bar is ".$mupfoo->foo_bar."\n";
print "whammy_bar is ".$mupfoo->whammy_bar."\n";
$mupfoo->whammy_bar ('wwwwwizzzzzaaaaaah!');
print "whammy_bar is ".$mupfoo->whammy_bar."\n";

print "foo-bar is ".$mupbar->foo_bar."\n";
print "set :".$mupbar->foo_bar(1)."\n";
print "foo-bar is ".$mupbar->foo_bar."\n";
print "whammy_bar is ".$mupbar->whammy_bar."\n";
print "wiz is ".$mupbar->wiz."\n";
$mupbar->wiz (4);
print "wiz is ".$mupbar->wiz."\n";

</gratuitous example>

i'd just like to point out that not only did i make a reference to the reverend horton heat in that example, it's also the first time i've ever actually used perl's transliteration operator.

but, for the record, i find that sort of AUTOLOAD to be rather obnoxious in that it makes the error messages you get when you misspell a method name be non-standard, possibly non-sensical.


for the final touch, they should
return $self as a setter. Then you can do stuff like

$obj
    ->foo(1)
    ->bar('baz')
    ->quux(answer => 42);

oh my --- the potential for a flame war just increased a thousand-fold.
i have always despised this VB-esq way of doing things. i much prefer setters that return the replaced value, so you can restore it later.

$oldfoo = $obj->foo ($newfoo);
...
$obj->foo ($oldfoo);


Lots of modules employ this style, too.

hey, everybody can't be right all the time.

/me ducks



You're right that we have a potential for future collisions here
though.

had we had something like properties as hash keys for the initial release, i don't think it would really be an issue. the problem now is that we'd break existing code. whether that's really a problem is up for discussion, but i'd like not to break people's code, so it's not on by default.


--
"that's it! you're a genius!" "yes. that's what i think. do you think i deserve a raise?"
        - dialogue from 'Godzilla versus Mothra', 1964




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]