Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Subclassing CGI::Pretty dies instantly in ->new , bug?

Reply
Thread Tools

Subclassing CGI::Pretty dies instantly in ->new , bug?

 
 
Jeremy Henty
Guest
Posts: n/a
 
      02-21-2007
I created a subclass of CGI:retty and it instantly dies:

$ /data/www-jeremy/cgi-bin/cgi-jeremy
Undefined subroutine Jeremy::CGI::delete
at /data/www-jeremy/cgi-bin/cgi-jeremy line 9

Line 9 is:

my $query = Jeremy::CGI->new;

If I modify the class to inherit from CGI then it works.

Is this a bug or a feature?

Is there a workaround?

Are there any other pitfalls if I inherit from CGI instead of
CGI:retty ? (I plan to use object-oriented style exclusively.)


Details:

Perl 5.8.7 on Linux 2.6.17.14 , gcc 3.4.3 .

The CGI subclass (works as given but fails if I replace CGI with
CGI:retty):

use strict;
use warnings;

package Jeremy::CGI;
use CGI;
our @ISA;
@ISA = qw( CGI );

1; # success

The CGI script:

#!/usr/bin/perl

use strict;
use warnings;

use lib qw( /home/jeremy/Personal/Geeky/Perl/Lib );
use Jeremy::CGI;

my $query = Jeremy::CGI->new;

print
$query->header,
$query->start_html("Hi!"),
$query->p("boink"),
$query->ul($query->li("foo"),
$query->li("bar"),);
$query->end_html,
;

Full output of "perl -V":

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:
Platform:
osname=linux, osvers=2.6.9, archname=i686-linux
uname='linux knoppix 2.6.9 #2 smp tue oct 19 23:51:10 cest 2004 i686 athlon-4 i386 gnulinux '
config_args='-ds -e -Dprefix=/usr -Dpager=/bin/less -isR'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-fno-strict-aliasing -pipe -I/usr/local/include'
ccversion='', gccversion='3.4.3', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -ldl -lm -lcrypt -lutil -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
libc=/lib/libc-2.3.4.so, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.3.4'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'


Characteristics of this binary (from libperl):
Compile-time options: USE_LARGE_FILES
Built under linux
Compiled at Dec 5 2005 05:39:47
@INC:
/usr/lib/perl5/5.8.7/i686-linux
/usr/lib/perl5/5.8.7
/usr/lib/perl5/site_perl/5.8.7/i686-linux
/usr/lib/perl5/site_perl/5.8.7
/usr/lib/perl5/site_perl
 
Reply With Quote
 
 
 
 
Uri Guttman
Guest
Posts: n/a
 
      02-21-2007
>>>>> "JH" == Jeremy Henty <> writes:

JH> I created a subclass of CGI:retty and it instantly dies:
JH> $ /data/www-jeremy/cgi-bin/cgi-jeremy
JH> Undefined subroutine Jeremy::CGI::delete
JH> at /data/www-jeremy/cgi-bin/cgi-jeremy line 9

JH> Line 9 is:

JH> my $query = Jeremy::CGI->new;

JH> If I modify the class to inherit from CGI then it works.

you are contradicting yourself. you can't subclass without
inheriting. the namespace of a module HAS NOTHING to do with subclassing
or inheritance. it is an arbitrary namespace and you can call it Foo and
subclass Bar.

JH> Is this a bug or a feature?

JH> Is there a workaround?

you found the fix (not a workaround).

JH> Are there any other pitfalls if I inherit from CGI instead of
JH> CGI:retty ? (I plan to use object-oriented style exclusively.)

JH> use CGI;
JH> our @ISA;
JH> @ISA = qw( CGI );

replace all that with:

use base 'CGI' ;

uri

--
Uri Guttman ------ -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
 
 
 
Jeremy Henty
Guest
Posts: n/a
 
      02-21-2007
On 2007-02-21, Uri Guttman <> wrote:
>>>>>> "JH" == Jeremy Henty <> writes:

>
> JH> I created a subclass of CGI:retty and it instantly dies:
> JH> $ /data/www-jeremy/cgi-bin/cgi-jeremy
> JH> Undefined subroutine Jeremy::CGI::delete
> JH> at /data/www-jeremy/cgi-bin/cgi-jeremy line 9
>
> JH> Line 9 is:
>
> JH> my $query = Jeremy::CGI->new;
>
> JH> If I modify the class to inherit from CGI then it works.
>
> you are contradicting yourself. you can't subclass without
> inheriting.


I don't see how this comment relates to my problem. I'm not claiming
you can subclass without inheriting. What I have is two modules,
identical except that one subclasses CGI and the other subclasses
CGI:retty , and the first works and the second breaks. What is
wrong with trying to subclass CGI:retty ?

> ...the namespace of a module HAS NOTHING to do with subclassing or
> inheritance. it is an arbitrary namespace and you can call it Foo
> and subclass Bar.


I'm aware of that. I've actually written code that does that without
problems. It doesn't explain why my module breaks if I replace "use
CGI;" with "use CGI:retty;" and "@ISA = qw( CGI );" with "@ISA = qw(
CGI:retty );". I've read the CGI and CGI:retty perldocs, Googled
and searched perl.doc and found nothing that explains this.

> JH> use CGI;
> JH> our @ISA;
> JH> @ISA = qw( CGI );
>
> replace all that with:
>
> use base 'CGI' ;


Thanks for the tip but it doesn't help the original problem, "use base
'CGI';" works fine and "use base 'CGI:retty';" dies exactly as
before. So I'm still mystified.

Regards,

Jeremy Henty
 
Reply With Quote
 
Jeremy Henty
Guest
Posts: n/a
 
      02-21-2007
On 2007-02-21, Jeremy Henty <> wrote:

> ... What I have is two modules, identical except that one
> subclasses CGI and the other subclasses CGI:retty , and the first
> works and the second breaks. What is wrong with trying to subclass
> CGI:retty ?


I'm following up to myself to explain further: the reason why this is
so surprising is that CGI:retty is just a subclass of CGI that
modifies a few methods to produce nicer HTML output. If I rewrite my
CGI script to use CGI:retty directly then it works.

So the *real* puzzle is this: why does replacing CGI:retty with a
module that does nothing except inherit from CGI:retty break things?

In fact "perldoc perltoot" says:

Setting up an empty class like this is called the "empty subclass
test"; that is, making a derived class that does nothing but
inherit from a base class. If the original base class has been
designed properly, then the new derived class can be used as a
drop-in replacement for the old one.

which suggests that CGI:retty is actually broken since it fails the
empty subclass test. If that's so then at the very least the docs
should say so.

Hope this clarifies my question.

Regards,

Jeremy Henty
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      02-21-2007
>>>>> "JH" == Jeremy Henty <> writes:

JH> On 2007-02-21, Jeremy Henty <> wrote:
>> ... What I have is two modules, identical except that one
>> subclasses CGI and the other subclasses CGI:retty , and the first
>> works and the second breaks. What is wrong with trying to subclass
>> CGI:retty ?


JH> I'm following up to myself to explain further: the reason why this is
JH> so surprising is that CGI:retty is just a subclass of CGI that
JH> modifies a few methods to produce nicer HTML output. If I rewrite my
JH> CGI script to use CGI:retty directly then it works.

well, for one thing since you don't seem to do anything special in
Jeremy::CGI why do you need that module?

the error you get seems to imply a broken inheritance path as your new
method is calling a delete method up the @ISA tree. when you changed
your module to use CGI:retty did you change all the CGI to
CGI:retty? you didn't show that version.


JH> So the *real* puzzle is this: why does replacing CGI:retty with a
JH> module that does nothing except inherit from CGI:retty break things?

i looked at the code and it seems it should work so i will bet it is
your code that is somehow broken. nothing personal but that is a good
bet when someone complains about modules by certain authors such as
lincoln stein.

try using the use base idea i mentioned. it does exactly what you want
and it means only one place needs to be changed from CGI to
CGI:retty. maybe that will fix it or help isolate the problem.

also to make your life easier for testing you can run this directly and
not under a web server. this is much better for debugging many cgi
scripts in general.

if you think (and can prove) this is a real error in CGI:retty then
you should report it to the author (but not until you can show serious
evidence on your side).

uri

--
Uri Guttman ------ -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
Jeremy Henty
Guest
Posts: n/a
 
      02-21-2007
On 2007-02-21, Uri Guttman <> wrote:
>>>>>> "JH" == Jeremy Henty <> writes:


> JH> I'm following up to myself to explain further: the reason why
> JH> this is so surprising is that CGI:retty is just a subclass
> JH> of CGI that modifies a few methods to produce nicer HTML output.
> JH> If I rewrite my CGI script to use CGI:retty directly then it
> JH> works.
>
> well, for one thing since you don't seem to do anything special in
> Jeremy::CGI why do you need that module?


I wanted to inherit from CGI:retty to refactor some code and when I
did so it promptly broke. I'm giving you a stripped-down example to
spare you the irrelevant details. (That's good practice, right?)

> ... try using the use base idea i mentioned. it does exactly what
> you want and it means only one place needs to be changed from CGI to
> CGI:retty. maybe that will fix it or help isolate the problem.


It did not fix it (though I appreciate you telling me about it)! Here
are the *exact* files I am now using (modulo indentation for clarity)

The CGI script:

#!/usr/bin/perl

use strict;
use warnings;

use lib qw( /home/jeremy/Personal/Geeky/Perl/Lib );
use Jeremy::CGI;

my $query = Jeremy::CGI->new;

print
$query->header,
$query->start_html("Hi!"),
$query->p("boink"),
$query->ul($query->li("foo"),
$query->li("bar"),);
$query->end_html,
;

Jeremy/CGI.pm :

use strict;
use warnings;

package Jeremy::CGI;
use base 'CGI:retty';

1; # success

And the result is:

Undefined subroutine Jeremy::CGI::delete
at /data/www-jeremy/cgi-bin/cgi-jeremy line 9

If I replace "my $query = Jeremy::CGI->new;" with "my $query =
CGI:retty->new;", it works. If I replace "use base 'CGI:retty';"
with "use base 'CGI';", it works. But as it stands, it's broken. It
seems clear that subclassing CGI:retty just doesn't work.

> ... to make your life easier for testing you can run this directly
> and not under a web server.


I am running it directly. (Believe me, I do read the docs and I am
trying not to waste your time or mine.)

> ... if you think (and can prove) this is a real error in CGI:retty
> then you should report it to the author


I was hoping someone could tell me whether subclassing CGI:retty was
supported before I hassled the author.

> ... (but not until you can show serious evidence on your side).


I've given you the exact files and output, and a quote from "perldoc
perltoot" that says a properly written module should not do this. If
that's not serious evidence I don't know what is!

Regards,

Jeremy Henty
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      02-21-2007
>>>>> "JH" == Jeremy Henty <> writes:

JH> On 2007-02-21, Uri Guttman <> wrote:

JH> The CGI script:

JH> use lib qw( /home/jeremy/Personal/Geeky/Perl/Lib );
JH> use Jeremy::CGI;

JH> my $query = Jeremy::CGI->new;

JH> Jeremy/CGI.pm :

JH> use strict;
JH> use warnings;

JH> package Jeremy::CGI;
JH> use base 'CGI:retty';

JH> And the result is:

JH> Undefined subroutine Jeremy::CGI::delete
JH> at /data/www-jeremy/cgi-bin/cgi-jeremy line 9

JH> If I replace "my $query = Jeremy::CGI->new;" with "my $query =
JH> CGI:retty->new;", it works. If I replace "use base 'CGI:retty';"
JH> with "use base 'CGI';", it works. But as it stands, it's broken. It
JH> seems clear that subclassing CGI:retty just doesn't work.

i would call that pretty good evidence. not much you can do but write
the author and send him all of this.

JH> I was hoping someone could tell me whether subclassing CGI:retty was
JH> supported before I hassled the author.

well, no one seems to have tried it before you did (i don't use :retty
and don't do much CGI in general).

>> ... (but not until you can show serious evidence on your side).


JH> I've given you the exact files and output, and a quote from "perldoc
JH> perltoot" that says a properly written module should not do this. If
JH> that's not serious evidence I don't know what is!

like i said, now you have to write to lincoln stein and show him
this. if you were to even find the fix (something in CGI:retty) he
would likely update it quickly. he is know for reasonable response
times. also you can try reporting the bug with rt.cpan.org which may be
more effective. he should get all bug reports from that on his modules.

as i said, i looked at the CGI:retty code and couldn't see anything
obvious as to why it wouldn't work. there is one possible issue i can
think of. CGI is noted for doing dynamic loading of many of its
functions/methods and it does its own wierd way. maybe GGI:retty is
doing something that needs to be done in your module too to force
loading of the delete method? i see this line in CGI:retty and maybe
it will be a clue for you.

$CGI:retty::AutoloadClass = 'CGI';

also look into calling SUPER::new() instead of new() in your
module. CGI:retty does that and it might also help. calling SUPER:: is
common when inheriting constructors.

uri

--
Uri Guttman ------ -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
Jeremy Henty
Guest
Posts: n/a
 
      02-21-2007
> ... you can try reporting the bug with rt.cpan.org which may be more
> effective.


I will. Thanks for the pointer.

> I see this line in CGI:retty and maybe it will be a clue for you.
>
> $CGI:retty::AutoloadClass = 'CGI';
>
> also look into calling SUPER::new() instead of new() in your
> module. CGI:retty does that and it might also help. calling
> SUPER:: is common when inheriting constructors.


I did actually try copying stuff from the CGI:retty constructor into
mine but nothing I tried worked. Eventually I decided to stop
tinkering and ask for help. Maybe the author can tell me the right
combination of magic.

Thanks again for your comments,

Jeremy Henty
 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      02-21-2007
Uri Guttman <> wrote in comp.lang.perl.misc:
> >>>>> "JH" == Jeremy Henty <> writes:

>
> JH> On 2007-02-21, Uri Guttman <> wrote:
>
> JH> The CGI script:
>
> JH> use lib qw( /home/jeremy/Personal/Geeky/Perl/Lib );
> JH> use Jeremy::CGI;
>
> JH> my $query = Jeremy::CGI->new;
>
> JH> Jeremy/CGI.pm :
>
> JH> use strict;
> JH> use warnings;
>
> JH> package Jeremy::CGI;
> JH> use base 'CGI:retty';
>
> JH> And the result is:
>
> JH> Undefined subroutine Jeremy::CGI::delete
> JH> at /data/www-jeremy/cgi-bin/cgi-jeremy line 9
>
> JH> If I replace "my $query = Jeremy::CGI->new;" with "my $query =
> JH> CGI:retty->new;", it works. If I replace "use base 'CGI:retty';"
> JH> with "use base 'CGI';", it works. But as it stands, it's broken. It
> JH> seems clear that subclassing CGI:retty just doesn't work.
>
> i would call that pretty good evidence. not much you can do but write
> the author and send him all of this.
>
> JH> I was hoping someone could tell me whether subclassing CGI:retty was
> JH> supported before I hassled the author.
>
> well, no one seems to have tried it before you did (i don't use :retty
> and don't do much CGI in general).
>
> >> ... (but not until you can show serious evidence on your side).

>
> JH> I've given you the exact files and output, and a quote from "perldoc
> JH> perltoot" that says a properly written module should not do this. If
> JH> that's not serious evidence I don't know what is!
>
> like i said, now you have to write to lincoln stein and show him
> this. if you were to even find the fix (something in CGI:retty) he
> would likely update it quickly. he is know for reasonable response
> times. also you can try reporting the bug with rt.cpan.org which may be
> more effective. he should get all bug reports from that on his modules.
>
> as i said, i looked at the CGI:retty code and couldn't see anything
> obvious as to why it wouldn't work. there is one possible issue i can
> think of. CGI is noted for doing dynamic loading of many of its
> functions/methods and it does its own wierd way. maybe GGI:retty is
> doing something that needs to be done in your module too to force
> loading of the delete method? i see this line in CGI:retty and maybe
> it will be a clue for you.


Your hunch is right about helping a class along to load its methods.
This is a workaround: In .../Jeremy/CLI.pm do

package Jeremy::CGI;
use base 'CGI:retty';

CGI:retty->can( $_) for qw( delete header cache);

1; # success

The ->can query has the effect that later calls to the methods
actually succeed. I don't know what exactly happens, just
noticed the effect while looking into this.

> $CGI:retty::AutoloadClass = 'CGI';


> also look into calling SUPER::new() instead of new() in your
> module. CGI:retty does that and it might also help. calling SUPER:: is
> common when inheriting constructors.


No, it's common when you override the constructor with your own. If
you inherit the constructor, there's no need (and no way) to use
SUPER::.

Anno
 
Reply With Quote
 
Jeremy Henty
Guest
Posts: n/a
 
      02-21-2007
This is another auto-followup to thank everyone who posted
workarounds. I'll still send in a bug report, but first, sleep
beckons.

Jeremy Henty
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Amazing program PAYS YOU INSTANTLY! Mr. Ellis Computer Support 3 11-13-2004 06:44 AM
Instantly disable a server side asp.net button? Dot net work ASP .Net 11 05-09-2004 10:03 PM
Dynamically inserting text into Table Cells so that they are instantly updated individually. Ceri ASP .Net 2 12-17-2003 02:00 PM
Perl 'system' Creates Program That Dies When First C Program Dies Christopher M. Lusardi Perl Misc 3 10-19-2003 11:53 AM
IE Windows closing instantly. S Computer Support 1 10-13-2003 08:59 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57