Gunther Birznieks <[EMAIL PROTECTED]> writes:
> However, I think it is reasonable to make the interface to support a
> data source for the widgets flexible and object based to make it easy
> for someone to write a DBI source, a DBM source, an LDAP source, an
> Apache::Session source or whatever anyone wants really. I happen to
> think DBI and Session sources are cool.
I agree; unfortunately writing classes to interface to all of these
would be difficult, and it would be difficult to be futureproof. When
you hit LDAP and DBI you must then worry about databases, tables,
servers, usernames, passwords, etc. It can become cumbersome to do
the simple things.
> By default, it could be GPC chaining like PHP (Get, Post,
> Cookie).... But with enough widget data sources to choose from you
> could do
>
> GPCSD (Get, Post, Cookie, Session, Database) type of thing.
This can be done quite well from a closure:
my $dbh = DBI->connect(...);
my $sth = $dbh->prepare('SELECT foo FROM persistant_data WHERE id = ?');
my $cgi = new CGI;
my $data_closre =
sub {
my $key = shift;
my $return = $cgi->param($key);
$return = $cgi->cookie($key)
unless defined $return;
if (not defined $return) {
$sth->execute($key);
($return) = $sth->fetchrow;
$sth->finish;
}
return $return;
};
Now the closre, though slightly more complicated, doesn't need to know
anything about the world around it, and neatly cinches off the
interface from Widget into DBI, CGI, cookies, etc etc. Using classes
for this would work, but it could be cumbersome; a closure allows for
near infinite flexibility... but at the price of complexity.
> I think but am not sure that closures likely also have better
> performance than method lookups. If this is the case, it could make
> sense to support a few data sources that need high performance because
> of their common use: CGI.pm and Apache::Request. Yet provide the
> extensibility for other developers to inject their own data sources
> into the chain using an Object-based API.
Closures are indeed faster than both instance method calls and package
method calls. However, this is a very basic thing; if performance is
critical enough to optimize this portion of a program then likely
someone wouldn't be using Widgets anyway :)
> Maybe someone else could comment on the technical merit of closure vs
> objects as well as the way in which they have been expecting the
> widgets to get populated? Is what I am saying make sense?
Below is a script to benchark the various invocations. The baseline
is for a function (method, closure, package method) to take one data
parameter and return something based on it.
The results I get on a dual P3 500 are:
[cturner@magneto cturner]$ perl bench.pl
Benchmark: timing 4000000 iterations of closure, method, pkgmethod...
closure: 10 wallclock secs ( 9.88 usr + 0.00 sys = 9.88 CPU) @ 404858.30/s
(n=4000000)
method: 22 wallclock secs (20.98 usr + 0.00 sys = 20.98 CPU) @ 190657.77/s
(n=4000000)
pkgmethod: 35 wallclock secs (35.59 usr + 0.00 sys = 35.59 CPU) @ 112391.12/s
(n=4000000)
bench.pl:
#!/usr/bin/perl -w
use strict;
use Benchmark;
my $meth = new Foo;
my $cref = sub { my $data = shift; return 1 };
timethese(4000000, { 'method' => sub { return $meth->bar },
'closure' => sub { return $cref->() },
'pkgmethod' => sub { return Foo->bar }});
package Foo;
sub new {
return bless {}, shift;
}
sub bar {
my $self = shift;
my $data = shift;
return 1;
}
--
Chip Turner [EMAIL PROTECTED]
RHN Web Engineer