http://www.perlmonks.org?node_id=639251


in reply to Re^2: AJAX popup windows - an example
in thread AJAX popup windows - an example

More actually. On my machine:
qwurx [shmem] ~ > perl -le 'use CGI::Ajax; print "$_ => $INC{$_}" for +sort keys %INC' CGI/Ajax.pm => /usr/lib/perl5/site_perl/5.8.8/CGI/Ajax.pm Carp.pm => /usr/lib/perl5/5.8.8/Carp.pm Class/Accessor.pm => /usr/lib/perl5/site_perl/5.8.8/Class/Accessor.pm Data/Dumper.pm => /usr/lib/perl5/5.8.8/i386-linux-thread-multi/Data/Du +mper.pm Exporter.pm => /usr/lib/perl5/5.8.8/Exporter.pm XSLoader.pm => /usr/lib/perl5/5.8.8/i386-linux-thread-multi/XSLoader.p +m base.pm => /usr/lib/perl5/5.8.8/base.pm bytes.pm => /usr/lib/perl5/5.8.8/bytes.pm overload.pm => /usr/lib/perl5/5.8.8/overload.pm strict.pm => /usr/lib/perl5/5.8.8/strict.pm vars.pm => /usr/lib/perl5/5.8.8/vars.pm warnings.pm => /usr/lib/perl5/5.8.8/warnings.pm warnings/register.pm => /usr/lib/perl5/5.8.8/warnings/register.pm

Class::Accessor is included out of laziness - not having to code setters/getters for objects.

As we all know, laziness is one of the virtues of a perl programmer, so that seems OK. But it isn't, because it conflicts with hubris, which beats laziness for Module authors. You don't want anybody to ever say something bad about your module, do you?

Data::Dumper is a leftover from development. It isn't used anywhere in that module. And that one pulls in:

qwurx [shmem] ~ > perl -le 'use Data::Dumper; print "$_ => $INC{$_}" f +or sort keys %INC' Carp.pm => /usr/lib/perl5/5.8.8/Carp.pm Data/Dumper.pm => /usr/lib/perl5/5.8.8/i386-linux-thread-multi/Data/Du +mper.pm Exporter.pm => /usr/lib/perl5/5.8.8/Exporter.pm XSLoader.pm => /usr/lib/perl5/5.8.8/i386-linux-thread-multi/XSLoader.p +m bytes.pm => /usr/lib/perl5/5.8.8/bytes.pm overload.pm => /usr/lib/perl5/5.8.8/overload.pm warnings.pm => /usr/lib/perl5/5.8.8/warnings.pm warnings/register.pm => /usr/lib/perl5/5.8.8/warnings/register.pm

Then there's the ubiquitous 'vars' module, which does

qwurx [shmem] ~ > perl -le 'use vars qw($foo); print "$_ => $INC{$_}" +for sort keys %INC' Carp.pm => /usr/lib/perl5/5.8.8/Carp.pm Exporter.pm => /usr/lib/perl5/5.8.8/Exporter.pm strict.pm => /usr/lib/perl5/5.8.8/strict.pm vars.pm => /usr/lib/perl5/5.8.8/vars.pm warnings.pm => /usr/lib/perl5/5.8.8/warnings.pm warnings/register.pm => /usr/lib/perl5/5.8.8/warnings/register.pm

A little bit of (crude *) cleanup to the header of CGI::Ajax

--- /usr/lib/perl5/site_perl/5.8.8/CGI/Ajax.pm 2007-02-01 00:35:44.00 +0000000 +0100 +++ CGI/Ajax.pm 2007-09-16 16:18:47.000000000 +0200 @@ -1,17 +1,32 @@ package CGI::Ajax; -use strict; -use Data::Dumper; -use base qw(Class::Accessor); -use overload '""' => 'show_javascript'; # for building web pages, +so - # you can just say: print +$pjx BEGIN { - use vars qw ($VERSION @ISA @METHODS); + our ($VERSION, @ISA, @METHODS); @METHODS = qw(url_list coderef_list DEBUG JSDEBUG html js_encode_function cgi_header_extra); - CGI::Ajax->mk_accessors(@METHODS); - + for my $field (@METHODS) { + *{'CGI::Ajax::'.$field} = sub { + my $self = shift @_; + if (@_) { + return $self->set($field, @_); + } else { + return $self->get($field); + } + }; + }; + for (qw(set get)) { + *{'CGI::Ajax::'.$_} = sub { + my $self = shift @_; + if (@_ == 1) { + return $$self{$_[0]}; + } elsif (@_ > 1) { + return $self->{$_[0]} = $_[1]; + } else { + $self->_croak('Wrong number of arguments received'); + } + }; + } $VERSION = .701; }
and all dependencies are eliminated
qwurx [shmem] ~ > perl -I. -le 'use CGI::Ajax(); print "$_ => $INC{$_} +" for sort keys %INC' CGI/Ajax.pm => CGI/Ajax.pm

at the expense of not being able to just print $pjx but having to say print $pjx->show_javascript.

qwurx [shmem] ~ > perl -le 'use overload "+" => \&add; print "$_ => $ +INC{$_}" for sort keys %INC' Carp.pm => /usr/lib/perl5/5.8.8/Carp.pm Exporter.pm => /usr/lib/perl5/5.8.8/Exporter.pm overload.pm => /usr/lib/perl5/5.8.8/overload.pm warnings.pm => /usr/lib/perl5/5.8.8/warnings.pm warnings/register.pm => /usr/lib/perl5/5.8.8/warnings/register.pm

Of course the code using CGI::Ajax might pull in Exporter, scrict, warnings, vars et al anyways - but it is not CGI::Ajax's business to do so if it can do without.

update:

OTOH, if the code that uses CGI::Ajax uses all those modules anyways, it is better to have them imported once instead of compiling duplicated code. So the cleanest thing would be adding a conditional in a BEGIN block, and pulling in Class::Accessor et cetera only if those namespaces are already present, because the cost of linking in already loaded modules is close to nil.

But then, this would depend on module loading order... not doing so for this particular module would just add 15 lines of code (which doesn't say much about perl's internal waste thereof... :-)

*)I just dumped the methods mk_accessors() generates and stuck them into the BEGIN block. Works.

update: corrected bug in set/get constructor

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}