Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

the CGI.pm in Perl 6

238 views
Skip to first unread message

Darren Duncan

unread,
Sep 9, 2006, 2:36:34 PM9/9/06
to perl6...@perl.org
P.S. I originally sent this to just Mark Stosberg yesterday, and he
suggested I sent it to perl6-users for more exposure, so here it is,
slightly edited.
----------------

To those of you working on (or wanting to use) the Perl 6 native CGI.pm,

Concerning the work you've been doing lately in getting the Perl 6
version of CGI.pm to function, I would like to strongly suggest that
you don't simply clone CGI.pm for Perl 5, but rather introduce some
(possibly but not necessarily backwards-incompatible) improvements in
the process, in particular to correct some stupid design issues.

Note that I will make these changes myself if someone else doesn't.
But since you're extensively working on CGI.pm now, I'm giving you
these strong suggestions early on so that you can incorporate them
using other design decisions of your own choosing (eg, different
function names).

To summarize:

1. ALWAYS gather all GET/query-string variables that exist,
regardless of whether this is a POST or GET query. The Perl 5
version currently discards any GET vars that are included in a POST
request and doesn't provide any workaround save to uncomment a code
line in CGI.pm itself.

Eg, say you want to submit a POST form to this url:

http://foo.com/bar/?screen=baz

Stuff like that should just work, but for CGI.pm in Perl 5 it
doesn't. I have to parse the query string myself if I get a POST
request, to make that work, and its inane that Perl 5's CGI.pm
doesn't just work with it.

2. Keep 2 distinct sets of query parameters, one each for GET (query
string) and POST (HTTP body) variables, that are both initialized and
can be appropriately read from and updated. They must be separate
because it is legitimate to have variables with the same names in
both places that must be kept distinct.

Combining these is like combining cookie or session variable with
either; all 4 are distinct things. I suggest that all accessors for
these contain the words "http get var(s)" or "http post var(s)" in
them respectively. For backwards compatability, you could also keep
"param" named functions which accesses a union of the above and the
post ones take precedence in a name conflict. But the key thing is
it must be possible+easy to use them separately.

Practically every other web invironment's basic built-ins, including
ASP and PHP, correctly keep these separate, and its time for Perl's
basics to join them.

3. ALWAYS retain any multiple values for get and post vars. For
ease of use, your accessors could look like "http_post_var()" and
"http_post_var_multi()" etc, which fetch either just the first item
as a scalar or an array ref having all the items (even if just one)
respectively.

4. Make UTF-8 the default HTTP response character encoding, and the
default declared charset for text/* MIME types, and explicitly
declare that this is what the charset is. The only time that output
should be anything else, even Latin-1, is if the programmer specifies
such.

5. Similarly, default to trying to treat the HTTP request as UTF-8
if it doesn't specify a character encoding; fallback to Latin-1 only
if the text parts of the HTTP request don't look like valid UTF-8.

So CGI.pm for Perl 6 can resemble the Perl 5 version, but in no way
should we retain backwards designs just because that's they way they
were before. So keep all input information and standardize on
Unicode.

Thank you in advance.

-- Darren Duncan

Mark Stosberg

unread,
Sep 9, 2006, 4:11:42 PM9/9/06
to perl6...@perl.org
Darren Duncan wrote:
> P.S. I originally sent this to just Mark Stosberg yesterday, and he
> suggested I sent it to perl6-users for more exposure, so here it is,
> slightly edited.

And here is my reply to Darren, slightly edited.

I'm only interested in CGI.pm so much as it holds up my work on
CGI::Application. As far as I'm aware, adding cookie support is all
that's left to do that to meet my needs.

So for the most part, I don't intend to be making design decisions for
or against your arguments.

I do share your sentiment that CGI.pm shouldn't be a clone of how P5
works. I'd like the HTML building methods to stay out, which wasn't even
one of the differences you cared about yourself. On the other hand,
there is a real benefit to in being similar enough so that porting from
Perl 5 is easy. Radical differences can forked into Web.pm or something.

I'll provide some comments on your suggestions below.

> > Note that I will make these changes myself if someone else doesn't.

Great!

> > 1. ALWAYS gather all GET/query-string variables that exist, regardless
> > of whether this is a POST or GET query. The Perl 5 version currently
> > discards any GET vars that are included in a POST request and doesn't
> > provide any workaround save to uncomment a code line in CGI.pm itself.
> >
> > Eg, say you want to submit a POST form to this url:
> >
> > http://foo.com/bar/?screen=baz
> >
> > Stuff like that should just work, but for CGI.pm in Perl 5 it doesn't.
> > I have to parse the query string myself if I get a POST request, to make
> > that work, and its inane that Perl 5's CGI.pm doesn't just work with it.

I see both sides to this and don't feel strongly about it.

> > 2. Keep 2 distinct sets of query parameters, one each for GET (query
> > string) and POST (HTTP body) variables, that are both initialized and
> > can be appropriately read from and updated. They must be separate
> > because it is legitimate to have variables with the same names in both
> > places that must be kept distinct.
> >
> > Combining these is like combining cookie or session variable with
> > either; all 4 are distinct things. I suggest that all accessors for
> > these contain the words "http get var(s)" or "http post var(s)" in them

> > respectively. For backwards computability, you could also keep "param"


> > named functions which accesses a union of the above and the post ones
> > take precedence in a name conflict. But the key thing is it must be
> > possible+easy to use them separately.
> >

> > Practically every other web environment's basic built-ins, including ASP


> > and PHP, correctly keep these separate, and its time for Perl's basics
> > to join them.

I agree here.

> > 3. ALWAYS retain any multiple values for get and post vars. For ease
> > of use, your accessors could look like "http_post_var()" and
> > "http_post_var_multi()" etc, which fetch either just the first item as a
> > scalar or an array ref having all the items (even if just one)
> > respectively.

I think this is already working. We always store values as arrays
internally, and I think because of how Perl 6 works, it does the right
thing if you expect a single value or an array returned.

> > 4. Make UTF-8 the default HTTP response character encoding, and the
> > default declared charset for text/* MIME types, and explicitly declare
> > that this is what the charset is. The only time that output should be
> > anything else, even Latin-1, is if the programmer specifies such.
> >
> > 5. Similarly, default to trying to treat the HTTP request as UTF-8 if

> > it doesn't specify a character encoding; fall back to Latin-1 only


if the
> > text parts of the HTTP request don't look like valid UTF-8.

I am not knowledgeable enough about this to haven an opinion. Currently
CGI.pm-p6 defaults to Latin-1, apparently as a port for Perl 5. Since
the related function was broken as recently as a few days ago, I know no
one is depending on that default now, including me.

> > 6. I suggest ditching the functional globals-storing CGI.pm interface
> > and using the OO version only; much simpler.

I made that change myself. It's OO-only now.

I look forward to your commits! Once you start making changes, I'll let
you know if you break anything CGI::Application depends on. It sounds
like you probably won't.

Mark

--
http://mark.stosberg.com/

Darren Duncan

unread,
Sep 9, 2006, 5:24:01 PM9/9/06
to perl6...@perl.org
At 3:11 PM -0500 9/9/06, Mark Stosberg wrote:
>I do share your sentiment that CGI.pm shouldn't be a clone of how P5
>works. I'd like the HTML building methods to stay out, which wasn't even
> one of the differences you cared about yourself. On the other hand,
>there is a real benefit to in being similar enough so that porting from
>Perl 5 is easy. Radical differences can forked into Web.pm or something.

If you want to see something more radical, have a look at my first
major CPAN modules from 2001ish.

Mainly HTML::FormTemplate and CGI::Portable. Between those and their
dependencies (HTML::EasyTags, Class::ParamParser,
Data::MultiValuedHash, CGI::MultiValuedHash), was an entire and
cleaner and more modular re-implementation of CGI.pm plus a few
extras (and minus a few bits; I never implemented file upload
handling). It is also more or less backwards compatible with CGI.pm
where it makes sense.

The combination is a bit large to be a CGI.pm replacement, but I
think that a lot can be learned from this if one wants to make more
significant CGI.pm improvements.

Note that I am still using those modules of mine for my own personal
web sites, but I'm not aware that they ever took off with other
people in a big way.

I also don't plan to straight-port them to Perl 6 since in large I
don't know if they really offer anything people want that other web
frameworks don't. I also don't have a big stake in them like I do
with my current database-centric modules (where I'm more certain they
can have a big impact). However, I'm sure the web modules can
influence improvements to CGI.pm in Perl 6, and I will do so at an
appropriate time.

-- Darren Duncan

Trey Harris

unread,
Sep 10, 2006, 5:47:17 PM9/10/06
to perl6...@perl.org, Mark Stosberg
In a message dated Sat, 9 Sep 2006, Mark Stosberg writes:
> I do share your sentiment that CGI.pm shouldn't be a clone of how P5
> works. I'd like the HTML building methods to stay out, which wasn't even
> one of the differences you cared about yourself.

I agree with the sentiment, but as a practical matter, not having HTML methods
in CGI.pm could drastically limit Perl 6 adoption.

If Perl 5 programmers get used to how they can mechanistically port their
programs to Perl 6, they will do so with the same sort of "ah-hah" moments
you've posted about on the Pugs blog, and it will be a good experience.

In other words, if they can port at a very low level (more like paraphrasing a
complicated text for a child than like translating from Chinese to English)
they won't feel that *everything* has changed under their feet, and over time
they'll start to nibble at more advanced features, and before long they'll be
translating automatically rather than paraphrasing mechanically.

But the HTML methods are used everywhere. And the more novitiate the
programmer, the more likely they are to be using them spaghetti-like
throughtout their code. If they discover that every time they see a
C<start_form> it's going to entail new coding, they're going to rapidly get
discouraged about porting to Perl 6.

I'd suggest that perhaps a more workable solution is to just buck up and accept
that the HTML methods have to get ported along with the rest of CGI.pm, but put
them into a separate distribution and have documentation in Differences and its
successors that say something like:

was: use CGI ':standard';

now: use CGI;
use CGI::HTMLgenerators; # Available separately, deprecated

perhaps with some scary-sounding warnings about how you should only use the
latter if you have lots of preexisting code needing the generators, that it's
better to use these other good solutions, you may shoot your eye out, etc. etc.

I know I seem to veer from wanting everything to change to wanting nothing
change, but it really comes down to whether the changes will not just be good
for us in an eat-your-spinach kind of way, but will lead to a more pleasant
programming experience as well. Adoption of Perl 6 will depend on whether
programmers like it, regardless of how stable or beautifully-architected its
systems are.

Trey

Trey Harris

unread,
Sep 10, 2006, 5:43:21 PM9/10/06
to Mark Stosberg, perl6...@perl.org
In a message dated Sat, 9 Sep 2006, Mark Stosberg writes:
> I do share your sentiment that CGI.pm shouldn't be a clone of how P5
> works. I'd like the HTML building methods to stay out, which wasn't even
> one of the differences you cared about yourself.

I agree with the sentiment, but as a practical matter, not having HTML

Thomas Wittek

unread,
Sep 11, 2006, 4:13:24 PM9/11/06
to perl6...@perl.org
Trey Harris schrieb:

> I agree with the sentiment, but as a practical matter, not having HTML
> methods in CGI.pm could drastically limit Perl 6 adoption.

Oh well. I thought it was common sense that it's a bad idea to mix code
and markup. Who really wants to do itself this pain should use a
separate module for that imho (or better a templating system like
Template Toolkit).

> If Perl 5 programmers get used to how they can mechanistically port
> their programs to Perl 6, they will do so with the same sort of "ah-hah"
> moments you've posted about on the Pugs blog, and it will be a good
> experience.

They can do:

use perl5:CGI;

if they want that legacy support.

If Perl6 CGI.pm is intended to be the successor of the P5 CGI.pm (the
quasi-standard for Perl web programming) is should really get a modern
design.

An other acceptable solution would be to create a backwards compatible
P6 CGI.pm and create a new Web.pm with an all new interface, like Mark
suggested. But then this new module cannot profit of the popularity of
the name "CGI.pm" and many people will say "Ah, Perl6 web development is
stuck at the 10 years old Perl5 CGI.pm interface. I'll use (python|ruby(
on rails)?|.+)". That would be sad.

> now: use CGI;
> use CGI::HTMLgenerators; # Available separately, deprecated

That'd be ok.

Just my 2ct.
-Thomas

Steffen Schwigon

unread,
Sep 12, 2006, 3:58:38 AM9/12/06
to perl6...@perl.org
Thomas Wittek <ma...@gedankenkonstrukt.de> writes:
> An other acceptable solution would be to create a backwards
> compatible P6 CGI.pm and create a new Web.pm with an all new
> interface, like Mark suggested. But then this new module cannot
> profit of the popularity of the name "CGI.pm" and many people will
> say "Ah, Perl6 web development is stuck at the 10 years old Perl5
> CGI.pm interface. I'll use (python|ruby( on rails)?|.+)". That would
> be sad.

IMHO even Perl people like me will think "Ah, Perl6 web development is
stuck at the 10 years old Perl5 CGI.pm interface" just *because* of
the name, regardless of a changed internal api.

I would strongly expect the CGI module to do the same as it did for
the last 200 years and create another name for any new school web
development. Catalyst, Jifty, Acme, Acyou, SillyIdol, WhatEver.

The name "CGI" smells like, erm, yes, C...G...I. If RoR would have
sold itself with "CGI" in its name, it hadn't been that successful. In
mankind's history, everything *not* named CGI had a chance to success,
even PHP. It will be impossible to resurrect a hype around the word
"CGI". Because of the word. Not the api.

IMHO. Of course. :-)

GreetinX
Steffen
--
Steffen Schwigon <schw...@webit.de>
Dresden Perl Mongers <http://dresden-pm.org/>

Thomas Wittek

unread,
Sep 12, 2006, 9:21:41 AM9/12/06
to perl6...@perl.org
Steffen Schwigon schrieb:

> Thomas Wittek <ma...@gedankenkonstrukt.de> writes:
>> An other acceptable solution would be to create a backwards
>> compatible P6 CGI.pm and create a new Web.pm with an all new
>> interface, like Mark suggested.

> I would strongly expect the CGI module to do the same as it did for


> the last 200 years and create another name for any new school web
> development. Catalyst, Jifty, Acme, Acyou, SillyIdol, WhatEver.

So we might agree ;) Catalysy, Jifty [..] are all "higher level"
complete frameworks. I used CGI.pm for rather lower level tasks
(POST/GET-parsing, HTTP redirects, ...) than as a foundation to build
complete applications (where the higher level framework come in).

So I think that there should be a (well designed) module for those lower
level (donkeywork) tasks and only for those (so definitely no
HTML-generation...).

Other frameworks (or simple CGI-scripts or even a backwards compatible
CGI.pm) could be built upon this foundation.

-Thomas

Amir E. Aharoni

unread,
Sep 12, 2006, 10:18:19 AM9/12/06
to perl6-users
> > Thomas Wittek <ma...@gedankenkonstrukt.de> writes:
> >> An other acceptable solution would be to create a backwards
> >> compatible P6 CGI.pm and create a new Web.pm with an all new
> >> interface, like Mark suggested.

My 0.02 ₪: CGI.pm will be better off redesigned and cleaned up, and
for those wanting compatibility a module called CGI5.pm can be
written.

It will probably be very popular, like p5 regexes ...

Darren Duncan

unread,
Sep 12, 2006, 6:08:03 PM9/12/06
to perl6...@perl.org
At 3:21 PM +0200 9/12/06, Thomas Wittek wrote:
>So I think that there should be a (well designed) module for those lower
>level (donkeywork) tasks and only for those (so definitely no
>HTML-generation...).

I strongly suggest that if we're going to do things this way, which
sounds like a good idea, then the new and well designed lower level
module should NOT be named "CGI.pm" ... if nothing else, it is
because that name sends the wrong message in today's age.

The word "CGI" generally speaks to an old, weak, and relatively
inefficient technology ... modern proper stuff does not spin off a
separate process for each server request; it reuses an existing
server ala mod_perl.

But this module in question should provide a low level layer that one
can use without changes regardless of whether the script is running
in CGI mode, or under mod_perl or ISAPI or as a pure-Perl server or
on the command-line.

As for "Web.pm", that may work better, but are there any reasonably
conceivable uses outside HTTP/HTTPS stuff that may invalidate the
name?

Either way, I agree; no HTML generation in this core module. Just
management of our server-side view of web client input and output.

In fact, it may borrow a few pages of design from LWP if applicable?

-- Darren Duncan

David Cantrell

unread,
Sep 13, 2006, 11:15:50 AM9/13/06
to Amir E. Aharoni, perl6-users
On Tue, Sep 12, 2006 at 05:18:19PM +0300, Amir E. Aharoni wrote:

> My 0.02 ???: CGI.pm will be better off redesigned and cleaned up, and


> for those wanting compatibility a module called CGI5.pm can be
> written.
>
> It will probably be very popular, like p5 regexes ...

Hear hear!

I wonder how many people really use the HTML-generating bits of CGI.pm?
I know I never have, nor have they been used that I can remember
anywhere that I've worked, or in any of the non-work projects I've
collaborated in. It's always been 'print "<HTML>"' or more recently
using a templating language like TT.

--
David Cantrell | top google result for "internet beard fetish club"

Computer Science is about lofty design goals and careful algorithmic
optimisation. Sysadminning is about cleaning up the resulting mess.

Andy Dougherty

unread,
Sep 13, 2006, 11:54:41 AM9/13/06
to perl6-users
On Wed, 13 Sep 2006, David Cantrell wrote:

> I wonder how many people really use the HTML-generating bits of CGI.pm?

I'd guess a lot, since they are prominently documented in the CGI.pm
documentation and are used extensively throughout many of the examples
there. It would be quite natural for anyone who learned to use
CGI.pm by reading its documentation to use those bits. Also, a simple
Google search for them turns up lots and lots of hits.

> I know I never have, nor have they been used that I can remember
> anywhere that I've worked, or in any of the non-work projects I've
> collaborated in. It's always been 'print "<HTML>"' or more recently
> using a templating language like TT.

Yep, I'm sure there's a lot of that too.

--
Andy Dougherty doug...@lafayette.edu

David Cantrell

unread,
Sep 13, 2006, 12:00:52 PM9/13/06
to perl6...@perl.org
On Tue, Sep 12, 2006 at 03:08:03PM -0700, Darren Duncan wrote:

> The word "CGI" generally speaks to an old, weak, and relatively
> inefficient technology ... modern proper stuff does not spin off a
> separate process for each server request; it reuses an existing
> server ala mod_perl.

To me the Commong Gateway Interface means a standard method for dealing
with data supplied by the user, nothing more. It certainly doesn't
specify how you should implement it. Indeed, every mod_perl application
I've seen uses CGI.

--
David Cantrell | A machine for turning tea into grumpiness

Just because it is possible to do this sort of thing
in the English language doesn't mean it should be done

Darren Duncan

unread,
Sep 13, 2006, 6:12:19 PM9/13/06
to perl6...@perl.org
At 5:00 PM +0100 9/13/06, David Cantrell wrote:
>On Tue, Sep 12, 2006 at 03:08:03PM -0700, Darren Duncan wrote:
> > The word "CGI" generally speaks to an old, weak, and relatively
>> inefficient technology ... modern proper stuff does not spin off a
>> separate process for each server request; it reuses an existing
>> server ala mod_perl.
>
>To me the Commong Gateway Interface means a standard method for dealing
>with data supplied by the user, nothing more. It certainly doesn't
>specify how you should implement it. Indeed, every mod_perl application
>I've seen uses CGI.

I beg to differ. "CGI" is very much an implementation detail. It is
a gateway protocol for how 2 different processes communicate.

See: http://www.w3.org/CGI/

An HTTP server is often used as a gateway to a legacy
information system; for example, an existing body of documents or an
existing database application. The Common Gateway Interface is an
agreement between HTTP server implementors about how to integrate
such gateway scripts and programs.

And: http://en.wikipedia.org/wiki/Common_Gateway_Interface

The Common Gateway Interface (CGI) is a standard protocol for
interfacing external application software with an information server,
commonly a web server. This allows the server to pass requests from a
client web browser to the external application. The web server can
then return the output from the application to the web browser.

Because this technology generally requires a fresh copy of
the program to be executed for every CGI request, the workload could
quickly overwhelm web servers, inspiring more efficient technologies
such as mod_perl or ASP that allow script interpreters to be
integrated directly into web servers as modules, thus avoiding the
overhead of repeatedly loading and initializing language interpreters.

So "CGI" is absolutely not a good name for a new and modern module's
design where the module's functionality isn't CGI-specific.

-- Darren Duncan

Leon Timmermans

unread,
Sep 13, 2006, 6:21:11 PM9/13/06
to perl6-users
Actually, I used them a few times. I agree the model used for html
generation is inadequate for most any serious usage. However, if you
need to dynamicaly generate forms CGI.pm is unmatched. A modernized
equavalent for them would still be very usefull IMHO. Though I agree
it might be better put in it's own module.

On the other HTML outputting functions: They never really belonged in
CGI in the first place I guess. There is no reason they cannot be
generalized to XML outputting and be put in an appropriate library. In
my experience, it is a very decent method of outputting XML content,
specially when your program has a procedural or functional design.

gr.

Leon

Aankhen

unread,
Sep 14, 2006, 8:00:13 PM9/14/06
to perl6...@perl.org
On 9/13/06, Leon Timmermans <faw...@gmail.com> wrote:
> On the other HTML outputting functions: They never really belonged in
> CGI in the first place I guess. There is no reason they cannot be
> generalized to XML outputting and be put in an appropriate library.

There is, actually. HTML ne XML. HTML is an SGML application. XHTML
is an XML application. The HTML generation functions definitely don't
fit in CGI.pm, but neither should they be pushed out into an XML
generation module, if only for the sake of conceptual clarity.

Regarding the general "CGI.pm in Perl 6" topic... I was working on
porting HTTP::* from LWP to Perl 6 a long time ago, but I was unable
to complete that. That was probably a year or so ago; if someone
would like to take over and bring it up to date with the latest syntax
and tricks, be my guest.

There were a few discussions with Juerd and others in #perl6 about
CGI.pm in Perl 6... if anyone's interested, I'll look for the logs.
The major feeling was that there should be no CGI.pm (if someone was
hellbent on using it, they could use the Perl 5 module). Rather,
there needs to be proper seperation of concerns. Maybe instead of
just importing CGI, you'd now import HTTP::Request::CGI and
HTML::Generator (I'm throwing names out at random, although I did
write HTTP::Request::CGI as a subclass of HTTP::Request whose members
are populated in a manner similar to CGI.pm's parsing of %ENV).

Aankhen
--
"I meant *our* species."
"You said *your* species."
"Evidently I am insane. May I go now?"

Darren Duncan

unread,
Sep 14, 2006, 9:00:35 PM9/14/06
to perl6...@perl.org
At 5:00 PM -0700 9/14/06, Aankhen wrote:
>There were a few discussions with Juerd and others in #perl6 about
>CGI.pm in Perl 6... if anyone's interested, I'll look for the logs.
>The major feeling was that there should be no CGI.pm (if someone was
>hellbent on using it, they could use the Perl 5 module). Rather,
>there needs to be proper seperation of concerns. Maybe instead of
>just importing CGI, you'd now import HTTP::Request::CGI and
>HTML::Generator (I'm throwing names out at random, although I did
>write HTTP::Request::CGI as a subclass of HTTP::Request whose members
>are populated in a manner similar to CGI.pm's parsing of %ENV).

While I wasn't involved in that discussion, I agree with the
sentiment you have expressed here, wherein there should be no
"CGI.pm" in Perl 6.

(Moreover, we should probably make an effort that no Perl 6 module
will have just a top-level namespace as its name unless it is a core
module or it is a framework.)

Having had some prior experience in tackling this problem (eg,
CGI::Portable), I will endeavour to work on / help with the Perl 6
analogy to HTTP::Request/Response, so to replace the use of
corresponding aspects of CGI.pm.

Note that the design strategy I had used in CGI::Portable was to have
a pure container object representing a request and/or response, which
was used sort of like this:

1. At start of handling an HTTP request, the main server runloop
creates a new Request Container and has it populated by invoking a
module function that knows about a particular environment, such as
IO::Socket vs mod_perl vs CGI or whatever.

2. The main runloop calls the application's main per-request handling
function; that function reads its HTTP input details from Request
Container and writes its HTTP output details to Response Container.

3. At end of handling an HTTP request, the main server runloop
invokes a module function that knows about a particular environment,
and that function outputs whatever the Response Container represents.

Note that, in the general case, the Request/Response containers would
not have any ties to outside environment, though in specific cases
where input and output are too large to easily fit in RAM at once,
there can be enhancements.

-- Darren Duncan

Juerd

unread,
Sep 14, 2006, 10:18:12 PM9/14/06
to perl6...@perl.org
Aankhen skribis 2006-09-14 17:00 (-0700):

> There were a few discussions with Juerd and others in #perl6 about
> CGI.pm in Perl 6...

I've been following the discussion with great interest, and will
summarize my thoughts here soon.
--
korajn salutojn,

juerd waalboer: perl hacker <ju...@juerd.nl> <http://juerd.nl/sig>
convolution: ict solutions and consultancy <sa...@convolution.nl>

Michael Snoyman

unread,
Sep 15, 2006, 10:27:32 AM9/15/06
to Darren Duncan, perl6...@perl.org
On 9/14/06, Darren Duncan <dar...@darrenduncan.net> wrote:
>
> Having had some prior experience in tackling this problem (eg,
> CGI::Portable), I will endeavour to work on / help with the Perl 6
> analogy to HTTP::Request/Response, so to replace the use of
> corresponding aspects of CGI.pm.
>

I really like this idea. I was actually working on a threaded HTTP server
in Perl that used that exact approach. The idea was that you could write a
HTTP::Server::Threaded::Handler implementation; this could easily work for
CGI as well. I can't test my code, since my Pugs installation is currently
broken (I've been working on it from work, and I'm trying to get everything
working in Cygwin right now). However, I've posted my code at this URL:

http://oss.snoyman.com/HTTP-Server-Threaded.tar.gz

As a note to Audrey: This is what I was asking about threads for; I added
the async statement, but haven't tested it.

Michael

Randal L. Schwartz

unread,
Sep 15, 2006, 12:15:03 PM9/15/06
to perl6...@perl.org
>>>>> "Andy" == Andy Dougherty <doug...@lafayette.edu> writes:

Andy> On Wed, 13 Sep 2006, David Cantrell wrote:
>> I wonder how many people really use the HTML-generating bits of CGI.pm?

Andy> I'd guess a lot, since they are prominently documented in the CGI.pm
Andy> documentation and are used extensively throughout many of the examples
Andy> there. It would be quite natural for anyone who learned to use
Andy> CGI.pm by reading its documentation to use those bits. Also, a simple
Andy> Google search for them turns up lots and lots of hits.

>> I know I never have, nor have they been used that I can remember
>> anywhere that I've worked, or in any of the non-work projects I've
>> collaborated in. It's always been 'print "<HTML>"' or more recently
>> using a templating language like TT.

Andy> Yep, I'm sure there's a lot of that too.

The thing that CGI.pm does is put in one place everything you need for a
simple web form. And there's an amazing number of applications for
this... putting a "contact us" page on an otherwise static site comes to mind
immediately.

Sure, if you're building a complex shopping cart application, you're gonna
reach for Jifty or Catalyst, or at least roll your own with Template Toolkit
or Mason, and you'd be silly to use either CGI.pm's parsing or HTML generation
in those cases.

But don't throw out the simplicity of CGI.pm's basic task handling: parsing
the incoming parameters (including file upload), and generating sticky forms
and other common HTML elements.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<mer...@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Juerd

unread,
Sep 15, 2006, 5:26:56 PM9/15/06
to perl6...@perl.org
Randal L. Schwartz skribis 2006-09-15 9:15 (-0700):

> The thing that CGI.pm does is put in one place everything you need for a
> simple web form. And there's an amazing number of applications for
> this... putting a "contact us" page on an otherwise static site comes to mind
> immediately.

Yes, it's great to have a standard toolkit. It's also totally acceptable
that a single thing exports several task related things at once.

use Web;

my $web = Web::Request.new does HTML::Generator;

HTML::Generator can be smart enough to realise that when it's used as a
role to extend Web::Request, it can provide stickiness for form
elements.

In fact, if you want to build a newbie friendly thing, just export a
pre-built $web, much like LWP::Simple can export a $ua:

use Web::Simple :html :cookies :sessions;

> But don't throw out the simplicity of CGI.pm's basic task handling: parsing
> the incoming parameters (including file upload), and generating sticky forms
> and other common HTML elements.

Don't thow out the simplicity, but do severely re-model things!

Juerd

unread,
Sep 15, 2006, 5:35:32 PM9/15/06
to perl6...@perl.org
Juerd skribis 2006-09-15 23:26 (+0200):

> Randal L. Schwartz skribis 2006-09-15 9:15 (-0700):
> > The thing that CGI.pm does is put in one place everything you need for a
> > simple web form. And there's an amazing number of applications for
> > this... putting a "contact us" page on an otherwise static site comes to mind
> > immediately.
> Yes, it's great to have a standard toolkit. It's also totally acceptable
> that a single thing exports several task related things at once.

Hm, removed two paragraphs that I wanted to keep:

But this thing should not be called CGI. It's not CGI-specific. Also,
this should not internally put everything on one big pile. We have roles
now, and roles make it easy to compose an object of the things that we
like, leaving out the things that we don't like.

Personally, I am *against* HTML generating for elements that are not
form fields. And for form fields, I think the solution should be in the
templating thing, not elsewhere. Stickiness makes sense on invalid data
only anyway, and we need to put the error message and a pointer
somewhere, and those are also templating things. Even the simple
"contact page" is much better off with a nice templating tool, than with
HTML generating methods.

A. Pagaltzis

unread,
Sep 16, 2006, 1:38:36 PM9/16/06
to perl6...@perl.org
* Darren Duncan <dar...@DarrenDuncan.net> [2006-09-09 20:40]:

> 4. Make UTF-8 the default HTTP response character encoding,
> and the default declared charset for text/* MIME types, and
> explicitly declare that this is what the charset is. The only
> time that output should be anything else, even Latin-1, is if
> the programmer specifies such.

No, please don’t. For unknown MIME types, the charset should be
undeclared. In particular, `application/octet-stream` should
never have a charset forced on it if one is not assigned by the
client code explicitly. Likewise, for `application/xml` and
`application/*+xml`, a charset should NEVER be explicitly
declared, as XML documents are self-describing, whereas declaring
a charset forces using the charset declared in the HTTP header.
This is very unwise (cf. Ruby’s Postulate).

> 5. Similarly, default to trying to treat the HTTP request as
> UTF-8 if it doesn't specify a character encoding; fallback to
> Latin-1 only if the text parts of the HTTP request don't look
> like valid UTF-8.

This is not just unwise, it is actually wrong. Latin-1 is the
default for `text/*` MIME types if no charset is declared. Using
a different charset in violation of the HTTP RFCs is __BROKEN__.

In fact, now that I’m writing all this out, I am starting to
think that maybe CGI.pm6 should simply punt on charsets as CGI.pm
does. Otherwise, the code and API would have to have able to deal
with the full complexity of charsets in HTTP, and the docs would
have to explain it, which is no picnic at all.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

A. Pagaltzis

unread,
Sep 16, 2006, 1:47:46 PM9/16/06
to perl6...@perl.org
* Trey Harris <tr...@lopsa.org> [2006-09-10 23:50]:

> But the HTML methods are used everywhere. And the more
> novitiate the programmer, the more likely they are to be using
> them spaghetti-like throughtout their code. If they discover
> that every time they see a C<start_form> it's going to entail
> new coding, they're going to rapidly get discouraged about
> porting to Perl 6.

I see that argument. So build a lean, well-designed CGI module,
but also offer a CGI5 module that aggregates the CGI stuff along
with HTML::Gen and whatnot into a CGI.pm5-compatible API melange
for easy porting.

No need to drag old mistakes along for all eternity just for the
sake of their familiarity.

Juerd

unread,
Sep 16, 2006, 2:58:24 PM9/16/06
to perl6...@perl.org
A. Pagaltzis skribis 2006-09-16 19:38 (+0200):

> * Darren Duncan <dar...@DarrenDuncan.net> [2006-09-09 20:40]:
> > 4. Make UTF-8 the default HTTP response character encoding, and the
> > default declared charset for text/* MIME types, and explicitly
> > declare that this is what the charset is. The only time that output
> > should be anything else, even Latin-1, is if the programmer
> > specifies such.
> No, please don???t. For unknown MIME types, the charset should be

> undeclared. In particular, `application/octet-stream` should never
> have a charset forced on it if one is not assigned by the client code
> explicitly. Likewise, for `application/xml` and `application/*+xml`, a
> charset should NEVER be explicitly declared, as XML documents are
> self-describing, whereas declaring a charset forces using the charset
> declared in the HTTP header. This is very unwise (cf. Ruby???s
> Postulate).

Darren discussed the *default* encoding. Like how text/html is a nice
default for the MIME-type, UTF-8 is a nice encoding. Both should be
overridable.

My thoughts:

* Default Content-Type header of "text/html; charset=UTF-8".
* Default output encoding of UTF-8.
* When a new Content-Type is set, but no new encoding
* Keep the default output encoding of UTF-8
* Warn if it's text/* without /charset=/
* Use the specified charset as the output encoding
* Change the output encoding to raw bytes if it's not text/*
* When a new Content-Type is set, and a new encoding is given
* Use the supplied encoding
* Warn if it's text/* without /charset=/
* Warn if supplied encoding and charset aren't equal enough

I think it's important to realise that only text/* have charset, and
that Content-Type is MIME-type plus charset in one value. We shouldn't
be "clever" and separate these: they're one string.

For XML, you'd have to explicitly mention Content-Type and encoding,
because the encoding can no longer be taken from the Content-Type, and
the default for non-text/* is raw bytes.

> > 5. Similarly, default to trying to treat the HTTP request as
> > UTF-8 if it doesn't specify a character encoding; fallback to
> > Latin-1 only if the text parts of the HTTP request don't look
> > like valid UTF-8.
> This is not just unwise, it is actually wrong. Latin-1 is the
> default for `text/*` MIME types if no charset is declared. Using
> a different charset in violation of the HTTP RFCs is __BROKEN__.

Agreed.

> In fact, now that I???m writing all this out, I am starting to


> think that maybe CGI.pm6 should simply punt on charsets as CGI.pm
> does. Otherwise, the code and API would have to have able to deal
> with the full complexity of charsets in HTTP, and the docs would
> have to explain it, which is no picnic at all.

Simple schemes can always be documented equally simply.

A first attempt:

The default value for the C<Content-Type> header is C<text/html;
charset=UTF-8>

The encoding that $module uses for output data is taken from the
C<charset> attribute in the C<Content-Type> header. If there is no
charset in the C<Content-Type> header, UTF-8 is used for all text/*
types, and raw for everything else.

It is possible to explicitly force an output encoding. When you're
not sending a text/* document, you need to do this if the document
does contain text. This is the case with most XML formats.

$response1.type = 'text/html; charset=iso-8859-1';
# implies: $response1.encoding = 'iso-8859-1;

$response2.type = 'application/xml';
$response2.encoding = 'UTF-8';

my $response3 = Web::Response.new :type('text/html; charset=iso-8859-1');
my $response4 = Web::Response.new :type<application/xml>, :encoding<UTF-8>;

A. Pagaltzis

unread,
Sep 16, 2006, 6:20:14 PM9/16/06
to perl6...@perl.org
* Juerd <ju...@convolution.nl> [2006-09-16 22:15]:

> My thoughts:
>
> * Default Content-Type header of "text/html; charset=UTF-8".
> * Default output encoding of UTF-8.
> * When a new Content-Type is set, but no new encoding
> * Keep the default output encoding of UTF-8
> * Warn if it's text/* without /charset=/
> * Use the specified charset as the output encoding
> * Change the output encoding to raw bytes if it's not text/*
> * When a new Content-Type is set, and a new encoding is given
> * Use the supplied encoding
> * Warn if it's text/* without /charset=/
> * Warn if supplied encoding and charset aren't equal enough

I had to read your mail twice to get what you really meant here,
but now that I have, this sounds reasonable.

> I think it's important to realise that only text/* have
> charset, and that Content-Type is MIME-type plus charset in one
> value. We shouldn't be "clever" and separate these: they're one
> string.

Sounds good to me.

Darren Duncan

unread,
Sep 16, 2006, 6:19:16 PM9/16/06
to perl6...@perl.org
At 7:38 PM +0200 9/16/06, A. Pagaltzis wrote:
>* Darren Duncan <dar...@DarrenDuncan.net> [2006-09-09 20:40]:
>> 4. Make UTF-8 the default HTTP response character encoding,
>> and the default declared charset for text/* MIME types, and
>> explicitly declare that this is what the charset is. The only
>> time that output should be anything else, even Latin-1, is if
>> the programmer specifies such.
>
>No, please don't. For unknown MIME types, the charset should be
>undeclared. In particular, `application/octet-stream` should
>never have a charset forced on it if one is not assigned by the
>client code explicitly. Likewise, for `application/xml` and
>`application/*+xml`, a charset should NEVER be explicitly
>declared, as XML documents are self-describing, whereas declaring
>a charset forces using the charset declared in the HTTP header.
>This is very unwise (cf. Ruby's Postulate).

Look again; I was only specifying that a default charset is used for
text/* MIME types, not non-text/* MIME types; the latter would
typically have no charset as you say.

> > 5. Similarly, default to trying to treat the HTTP request as
>> UTF-8 if it doesn't specify a character encoding; fallback to
>> Latin-1 only if the text parts of the HTTP request don't look
>> like valid UTF-8.
>
>This is not just unwise, it is actually wrong. Latin-1 is the
>default for `text/*` MIME types if no charset is declared. Using
>a different charset in violation of the HTTP RFCs is __BROKEN__.

Okay, I retract that suggestion. Because the official HTTP spec says
no-explicit-charset-means-Latin1.

>In fact, now that I'm writing all this out, I am starting to
>think that maybe CGI.pm6 should simply punt on charsets as CGI.pm
>does. Otherwise, the code and API would have to have able to deal
>with the full complexity of charsets in HTTP, and the docs would
>have to explain it, which is no picnic at all.

I disagree. Regardless of the details, a Perl 6 replacement for
CGI.pm *should* handle character set issues. Its users should simply
be able to pull out correctly interpreted ready-to-use Str values
when the HTTP request content type is text, and not have to know
about what character set was used in the request. Analagously, if
the user takes their Str values and supplies them to an HTTP response
whose content type is text, they should not have to specify an output
encoding if they don't want to, and UTF-8 is the best default because
it can handle all possible characters that the Str repetoire can
represent.

The CGI.pm replacement by no means has to do the dirty work of
processing encodings itself, such as mapping bytes to chars etc.
Those details would be handled by something else, such as either Perl
6 itself or a Perl 6 analogy to Encode.pm.

-- Darren Duncan

Mark Stosberg

unread,
Sep 16, 2006, 10:38:39 PM9/16/06
to perl6...@perl.org
Juerd wrote:
>
> Personally, I am *against* HTML generating for elements that are not
> form fields. And for form fields, I think the solution should be in the
> templating thing, not elsewhere. Stickiness makes sense on invalid data
> only anyway, and we need to put the error message and a pointer
> somewhere, and those are also templating things. Even the simple
> "contact page" is much better off with a nice templating tool, than with
> HTML generating methods.

I think HTML::FillInForm is a much better way to handle form stickiness.
It allows you to keep the form generation in HTML /and/ still support
stickiness.

So, it's fine with me if the sticky feature of CGI.pm doesn't re-appear.

Mark

Mark Stosberg

unread,
Sep 16, 2006, 10:30:43 PM9/16/06
to perl6...@perl.org, Aankhen, perl6...@perl.org
Aankhen wrote:
>
> The major feeling was that there should be no CGI.pm (if someone was
> hellbent on using it, they could use the Perl 5 module).

In theory, "use perl5:CGI" could be a fine solution. In practice, it
hasn't worked out well for me. Even something that seems simple like
passing a hashref to Perl 5 is not documented now. In summary, I found
it easier to update CGI.pm p6 to meet my needs than to 'use perl5:CGI'
to meet my needs. I think the reality it is yet to been seen now well
calls to Perl 5 modules can work for the general case.

Mark

Mark Stosberg

unread,
Sep 16, 2006, 10:23:49 PM9/16/06
to perl6...@perl.org
David Cantrell wrote:
>
> I wonder how many people really use the HTML-generating bits of CGI.pm?
> I know I never have, nor have they been used that I can remember
> anywhere that I've worked, or in any of the non-work projects I've
> collaborated in. It's always been 'print "<HTML>"' or more recently
> using a templating language like TT.

I find a few of the form generation methods really handy, especially
popup_menu(). Form elements aren't managed much by designers anyway.
The rest of the HTML stuff I actively ignore.

Mark

Juerd

unread,
Sep 17, 2006, 5:27:47 AM9/17/06
to perl6...@perl.org
Mark Stosberg skribis 2006-09-16 21:30 (-0500):

Please note that eventually, perl5:CGI is supposed to work as expected.

Mark Stosberg

unread,
Sep 17, 2006, 9:10:19 AM9/17/06
to perl6...@perl.org
Juerd wrote:
>
> Please note that eventually, perl5:CGI is supposed to work as expected.

For that to happen, there will first have be some documentation telling
me what expectations to have.

When Perl 5 has references and Perl 6 doesn't, I don't know what to
expect to when I need to pass a hash reference to a Perl 5 routine.

Such details make no appearance currently in the Perl 6 spec, but I'm
trying to gather them on the wiki if you have anything to add:

http://rakudo.org/perl6/index.cgi?using_perl_5_embedding

Mark

Juerd

unread,
Sep 17, 2006, 6:16:45 AM9/17/06
to perl6...@perl.org
Mark Stosberg skribis 2006-09-17 8:10 (-0500):

> > Please note that eventually, perl5:CGI is supposed to work as expected.
> For that to happen, there will first have be some documentation telling
> me what expectations to have.

Good point, but I think your expectations are natural and logical.

> When Perl 5 has references and Perl 6 doesn't, I don't know what to
> expect to when I need to pass a hash reference to a Perl 5 routine.

That's mostly terminology. I expect that the syntax will still be the
same. That is:

perl5sub( { ... } ); # Anonymous hash
perl5sub( \%hash ); # Capture of a real hash

> Such details make no appearance currently in the Perl 6 spec, but I'm
> trying to gather them on the wiki if you have anything to add:
> http://rakudo.org/perl6/index.cgi?using_perl_5_embedding

Great work!

Unfortunately, it still takes up to a minute for rakudo.org pages to
load on my home machine.

David Cantrell

unread,
Sep 18, 2006, 5:42:25 PM9/18/06
to perl6...@perl.org
Randal L. Schwartz wrote:

> The thing that CGI.pm does is put in one place everything you need for a
> simple web form. And there's an amazing number of applications for
> this... putting a "contact us" page on an otherwise static site comes to mind
> immediately.
>
> Sure, if you're building a complex shopping cart application, you're gonna
> reach for Jifty or Catalyst, or at least roll your own with Template Toolkit
> or Mason, and you'd be silly to use either CGI.pm's parsing or HTML generation
> in those cases.

You seem to be forgetting the case in the middle - a small dynamic site.
My weapons of choice for that are CGI.pm to parse requests and
Template Toolkit to stuff the relevant content into templates. Frankly,
to use something heavier when I don't have to (and TT is already
somewhat heavy for my tastes) would be silly. And to have a plethora of
little scripts each using CGI.pm to parse requests and to then generate
the appropriate HTML, instead of having *one* script which uses TT would
be, frankly, insane.

> But don't throw out the simplicity of CGI.pm's basic task handling: parsing
> the incoming parameters (including file upload), and generating sticky forms
> and other common HTML elements.

That's two tasks. It should be two modules.

I suppose you could argue that generating <FORM> tags specifically and
all their baggage like <INPUT>s might fall under its remit (they are,
after all, what generates the fancy requests that are CGI's bread and
butter), but generating <H1> tags is most definitely not anything to do
with CGI.

--
David Cantrell | Enforcer, South London Linguistic Massive

All praise the Sun God
For He is a Fun God
Ra Ra Ra!

Fagyal Csongor

unread,
Sep 18, 2006, 7:22:08 PM9/18/06
to perl6...@perl.org

> Randal L. Schwartz wrote:
>
>> The thing that CGI.pm does is put in one place everything you need for
>> a simple web form. And there's an amazing number of applications for
>> this... putting a "contact us" page on an otherwise static site comes
>> to mind immediately.
>>
>> Sure, if you're building a complex shopping cart application, you're
>> gonna reach for Jifty or Catalyst, or at least roll your own with
>> Template Toolkit or Mason, and you'd be silly to use either CGI.pm's
>> parsing or HTML generation in those cases.
>
> You seem to be forgetting the case in the middle - a small dynamic site.
IMHO that is: "most sites".

> My weapons of choice for that are CGI.pm to parse requests and
> Template Toolkit to stuff the relevant content into templates.

That's why I use CGI::Lite - no fancy HTML, only a lightweight module with
themost important features. (Gee, I am emitting WML sometimes!)

And let me add this as a side note:
http://www.w3.org/CGI/
IMHO a module should do what its name stands for.

Surely, when I do something with CGI, I also do HTML generation in 99% of
the time. But as the matter of fact, I also use DBI in 99% of the time, so
why not put DBI into CGI.pm, too? ;)

[...]

>> But don't throw out the simplicity of CGI.pm's basic task handling:
>> parsing the incoming parameters (including file upload), and
>> generating sticky forms and other common HTML elements.
>
> That's two tasks. It should be two modules.

Absolutely.

> I suppose you could argue that generating <FORM> tags specifically and
> all their baggage like <INPUT>s might fall under its remit (they are,
> after all, what generates the fancy requests that are CGI's bread and
> butter), but generating <H1> tags is most definitely not anything to do
> with CGI.

Also consider that handling the "input part" of CGI is very
straightforward. No matter what system/language you use, you basically do
the same thing (parse/access GET/POST, the ENV variables, etc.) On the
other hand, handling the output is much more dubious - besides setting the
content type on some other headers, there are dozens of ways to
handle/mangle the content you output. Perl5's CGI.pm provides a way, but
that is IMHO just a legacy API Perl6 has nothing to do with. Basically
everyone who use CGI.pm use ->param() - but only a few use ->h1(), for
example. (IMHO if something beyond CGI input handling must go into CGI.pm,
then that is cookie handling - but that's another story.)

Just my two cents.
- Fagzal


Mark Stosberg

unread,
Sep 16, 2006, 10:32:07 PM9/16/06
to perl6...@perl.org, Aankhen, perl6...@perl.org
Aankhen wrote:
>
> The major feeling was that there should be no CGI.pm (if someone was
> hellbent on using it, they could use the Perl 5 module).

In theory, "use perl5:CGI" could be a fine solution. In practice, it


hasn't worked out well for me. Even something that seems simple like
passing a hashref to Perl 5 is not documented now. In summary, I found
it easier to update CGI.pm p6 to meet my needs than to 'use perl5:CGI'
to meet my needs. I think the reality it is yet to been seen now well
calls to Perl 5 modules can work for the general case.

Mark

Randal L. Schwartz

unread,
Sep 19, 2006, 11:16:26 AM9/19/06
to perl6...@perl.org
>>>>> "David" == David Cantrell <da...@cantrell.org.uk> writes:

>> But don't throw out the simplicity of CGI.pm's basic task handling: parsing
>> the incoming parameters (including file upload), and generating sticky forms
>> and other common HTML elements.

David> That's two tasks. It should be two modules.

No, it's an *integrated* task. The form-generation stuff needs tight coupling
with the getting (and setting) of the incoming param values. You couldn't
just use two random modules for that... they'd have to specifically know about
each other and work together.

That's why it's great that it's all in CGI.pm. If I just want param handling,
I import/compile only that part. If I also want sticky forms, I just ask it
for a bit more. And as long as I'm there, I import "header" or "redirect" or
"cookie" to do that "last bit" of my application. CGI.pm has the *right*
mix for small tasks. It *does* make sense.

Thomas Wittek

unread,
Sep 19, 2006, 3:44:30 PM9/19/06
to perl6...@perl.org
(Randal L. Schwartz) schrieb:

> >>>>> "David" == David Cantrell <da...@cantrell.org.uk> writes:
> David> That's two tasks. It should be two modules.
>
> No, it's an *integrated* task. The form-generation stuff needs tight
> coupling
> with the getting (and setting) of the incoming param values.

A separate module, say HTML::Formgenerator, could easily use CGI.pm (or
Web.pm,...) to get and set parameters:

$value = $query->param('foo');

$query->param('foo','an','array','of','values');

I see no need to integrate those modules.

Regards
--
Thomas Wittek
http://gedankenkonstrukt.de/
Jabber: strea...@jabber.i-pobox.net

Juerd

unread,
Sep 19, 2006, 4:44:13 PM9/19/06
to perl6...@perl.org
Randal L. Schwartz skribis 2006-09-19 8:16 (-0700):

> No, it's an *integrated* task. The form-generation stuff needs tight coupling
> with the getting (and setting) of the incoming param values.

Integrated task? Tight coupling? If I didn't know you, I'd immediately
say you have no idea what you're talking about. But you do, so I'm a bit
puzzled as to why you would say this. Could you explain your point of
view a bit further?

The only coupling needed is the getting of "param"s. This can be done
perfectly by passing the CGI object, or (uglier) by using a subclass of
CGI.pm. In Perl 6, it can be done by adding HTML generation as a role to
the existing object.

In fact, CGI.pm itself only uses ->param and utility functions that are
specific to HTML generation, in methods like _textfield.

> You couldn't just use two random modules for that... they'd have to
> specifically know about each other and work together.

There's a tradition of treating CGI.pm's param method as an known
protocol, and often you can pass a CGI object, or any other object witha
similar param method, to certain modules. One of them is
HTML::FillInForm, which proves rather directly that no tight coupling or
integration is needed, at all. A simple method with a strict definition
is enough, and CGI.pm has provided just that.

It's okay to have two modules that were designed to work together, as it
is okay to have one module depend on and use another.

Otherwise, why would you still want to factor things into separate
modules anyway? Maintenance and usability are important issues, but
being able to use only what you need is quite attractive too. CGI.pm
uses elaborate autoloading techniques, that would not be needed, or
could be much simpler, if there was clear separation of tasks from the
beginning.

> That's why it's great that it's all in CGI.pm. If I just want param
> handling, I import/compile only that part. If I also want sticky
> forms, I just ask it for a bit more. And as long as I'm there, I
> import "header" or "redirect" or "cookie" to do that "last bit" of my
> application. CGI.pm has the *right* mix for small tasks. It *does*
> make sense.

It does make sense to have a single toolkit that does all this. It does
not make sense to have a single .pm that does all this. There's
absolutely no need for having all these different tasks in one module.
There's not even any benefit. You can just as well use a couple of
nicely named, grouped, and reasonably standalone roles or classes, and
then a single module to combine them all for the ease of use that you
like.

Steve Pitchford

unread,
Sep 19, 2006, 4:42:10 PM9/19/06
to perl6...@perl.org
Randal L. Schwartz wrote:

>>>>>>"David" == David Cantrell <da...@cantrell.org.uk> writes:
>>>>>>
>>>>>>
>
>
>
>>>But don't throw out the simplicity of CGI.pm's basic task handling: parsing
>>>the incoming parameters (including file upload), and generating sticky forms
>>>and other common HTML elements.
>>>
>>>
>
>David> That's two tasks. It should be two modules.
>
>No, it's an *integrated* task. The form-generation stuff needs tight coupling
>with the getting (and setting) of the incoming param values. You couldn't
>just use two random modules for that... they'd have to specifically know about
>each other and work together.
>
>That's why it's great that it's all in CGI.pm. If I just want param handling,
>I import/compile only that part. If I also want sticky forms, I just ask it
>for a bit more. And as long as I'm there, I import "header" or "redirect" or
>"cookie" to do that "last bit" of my application. CGI.pm has the *right*
>mix for small tasks. It *does* make sense.
>
>
>

To be honest I'm not sure I follow your argument. Why does populating a
form from incoming form data require "closer integration"
than, say, pulling it out of a database and populating a form for
further editing?. Surely its just a question of a consistant interface?

Forgive me if I have misunderstood your point.

Steve

Mark Stosberg

unread,
Sep 19, 2006, 10:05:29 PM9/19/06
to perl6...@perl.org
Juerd wrote:
>
> It does make sense to have a single toolkit that does all this. It does
> not make sense to have a single .pm that does all this. There's
> absolutely no need for having all these different tasks in one module.
> There's not even any benefit. You can just as well use a couple of
> nicely named, grouped, and reasonably standalone roles or classes, and
> then a single module to combine them all for the ease of use that you
> like.

I suggest that those who have concrete ideas sketch out the API through
a new page on the wiki. That could make it easier for someone else to
pick up, if they have programming skill, but less API design experience.
The result might be even multiple API designs (A more compatible CGI.pm
and cleaner/newer/different Web.pm solution).

http://rakudo.org/perl6/index.cgi

Mark

A. Pagaltzis

unread,
Sep 19, 2006, 10:06:15 PM9/19/06
to perl6...@perl.org
* Randal L. Schwartz <mer...@stonehenge.com> [2006-09-19 21:25]:

> The form-generation stuff needs tight coupling with the getting
> (and setting) of the incoming param values. You couldn't just
> use two random modules for that... they'd have to specifically
> know about each other and work together.

Err, no. They just need a known protocol, and the semantics of
CGI.pm’s `param` method have spread pretty widely and are now
used by many other modules as well. In general, you can pass
instances from any of these modules to anything that expects
something that speaks that protocol and they work just fine.
F.ex., you can pass CGI::Simple objects into HTML::Template for
variable prepopuluation and it Just Works because they talk to
each other using the CGI.pm `param` protocol.

Form handling clearly requires no coupling.

Randal L. Schwartz

unread,
Sep 20, 2006, 11:15:10 AM9/20/06
to perl6...@perl.org
>>>>> "Steve" == Steve Pitchford <ste...@metalogicplc.com> writes:

Steve> To be honest I'm not sure I follow your argument. Why does populating a form
Steve> from incoming form data require "closer integration"
Steve> than, say, pulling it out of a database and populating a form for further
Steve> editing?.

It's the stickiness, which is a handy feature of error-page generation.

Using the existing CGI.pm, I can say:

print textfied('first_name', 'default value');

and the first_name field will have 'default value' *unless* there's also a
param('first_name'), in which case it'll come from there. Of course, I can
specify override => 1, or even delete the param as needed, if I don't want the
sticky behavior.

To get this to work right, whatever I use for HTML generation needs to know
how to get incoming params. Admittedly, the interface is simple, but it would
have to know if I'm using a functional form with a hidden object (use CGI
qw/param/) or an explicit object (my $q = CGI->new). And if it's an
explicit object, how will the HTML generation find it? This works
even for select-multiple forms, which is very nice.

That's why the *tight* integration of incoming parameters and HTML
form generation is a Good Thing. 90% of the time, it just Works.

A. Pagaltzis

unread,
Sep 20, 2006, 4:01:30 PM9/20/06
to perl6...@perl.org
* Randal L. Schwartz <mer...@stonehenge.com> [2006-09-20 19:30]:

> To get this to work right, whatever I use for HTML generation
> needs to know how to get incoming params. Admittedly, the
> interface is simple, but it would have to know if I'm using a
> functional form with a hidden object (use CGI qw/param/)

Which is seriously awful anyway. Have you read the
`self_or_default` sub in CGI.pm? I’d never put such a thing in my
own code.

CGI::Simple does this correctly – the default interface is OO
only, and if you want exports then you use CGI::Simple::Standard.

> or an explicit object (my $q = CGI->new). And if it's an
> explicit object, how will the HTML generation find it? This
> works even for select-multiple forms, which is very nice.

Uuuuhhhh… maybe you’d just pass the query object to the form
generator constructor? You’ve seen HTML::FillInForm and
HTML::Template, haven’t you?

With roles in P6, you can even make this even simpler. You could
make the HTML generator a role which can be composed onto any
object that `does ParamQuery`.

> That's why the *tight* integration of incoming parameters and
> HTML form generation is a Good Thing. 90% of the time, it just
> Works.

You keep stating this as if it were true despite conclusive
evidence to the opposite. I don’t know what you are trying to
achieve.

Juerd

unread,
Sep 20, 2006, 4:18:47 PM9/20/06
to perl6...@perl.org
A. Pagaltzis skribis 2006-09-20 22:01 (+0200):

> With roles in P6, you can even make this even simpler. You could
> make the HTML generator a role which can be composed onto any
> object that `does ParamQuery`.

I think it's time we moved away from the param method, and started using
a hash. In fact, two hashes, get and post.

use Web <$web>;

$web.get<foo>;
$web.post<foo>;

$web<foo>; # shorthand form for $web.post<foo> // $web.get<foo>

A. Pagaltzis

unread,
Sep 20, 2006, 4:39:35 PM9/20/06
to perl6...@perl.org
* Juerd <ju...@convolution.nl> [2006-09-20 22:25]:

> I think it's time we moved away from the param method, and
> started using a hash.

I don’t know about that. The `param` method has the nice property
that it allows you to pretend everything’s a single value or to
use multi-valued params, at your own discretion, at any time,
with no change of syntax.

my $foo = $q->param( 'foo' );
my @bar = $q->param( 'bar' );

If you tried to do this with a hash, you’d get

my $foo = $q->param->{ 'foo' }[0];
# my ( $foo ) = @{ $q->param->{ 'foo' } };
my @bar = @{ $q->param->{ 'bar' } };

You could try making the type of the value depend on arity and be
either a scalar or an arrayref, but then you get V*E*R*Y U*G*L*Y
client code that needs to constantly check whether it’s dealing
with one or the other.

Does Perl 6 offer any help in making access to a HoL look like
the first example? If not, then no, let’s please stick with the
`param` protocol.

Juerd

unread,
Sep 20, 2006, 6:43:41 PM9/20/06
to perl6...@perl.org
A. Pagaltzis skribis 2006-09-20 22:39 (+0200):

> * Juerd <ju...@convolution.nl> [2006-09-20 22:25]:
> > I think it's time we moved away from the param method, and
> > started using a hash.
> I don???t know about that. The `param` method has the nice property
> that it allows you to pretend everything???s a single value or to

> use multi-valued params, at your own discretion, at any time,
> with no change of syntax.

Thinking that one variable has only one interface is *so* Perl 5 :)

> my $foo = $q->param( 'foo' );
> my @bar = $q->param( 'bar' );

> If you tried to do this with a hash, you???d get


> my $foo = $q->param->{ 'foo' }[0];
> # my ( $foo ) = @{ $q->param->{ 'foo' } };
> my @bar = @{ $q->param->{ 'bar' } };

In Perl 5, yes.

But in Perl 6:

my $foo = $web<foo>;
say $foo;
say $foo[1]; # heck, why not.

my @foo = $web<foo>;
say @foo[1];

All we need is a very simple type that does both Str and Array. We can
handle this, *easily*.

And I wouldn't want the nullbyte mistake again. Let's just stick to the
last given value instead.

Also, I want parameters to be able to do a certain Upload role, which
adds terribly useful methods for file uploads. Let's escape the
primitive world and add some REAL dwimmery, the kind that doesn't
confuse people all the time :)

> Does Perl 6 offer any help in making access to a HoL look like
> the first example?

No, but it does offer help to make it look a whole lot nicer than that.
:)
--
korajn salutojn,

juerd waalboer: perl hacker <ju...@juerd.nl> <http://juerd.nl/sig>
convolution: ict solutions and consultancy <sa...@convolution.nl>

PS

Note that your code, if literally translated to Perl 6, is already
nicer:

> my $foo = $q->param->{ 'foo' }[0];

my $foo = $q.param<foo>[0];

> my @bar = @{ $q->param->{ 'bar' } };

my @bar = $q.param<bar>.'@';
my @bar = @ $q.param<bar>;

A. Pagaltzis

unread,
Sep 20, 2006, 7:43:08 PM9/20/06
to perl6...@perl.org
* Juerd <ju...@convolution.nl> [2006-09-21 00:45]:

> And I wouldn't want the nullbyte mistake again. Let's just
> stick to the last given value instead.

Nobrainer. The nullbyte thing was a Perl-4-ism.

> Also, I want parameters to be able to do a certain Upload role,
> which adds terribly useful methods for file uploads. Let's
> escape the primitive world and add some REAL dwimmery, the kind
> that doesn't confuse people all the time :)

But let’s also be careful not to go *too* overboard with the new
stuff. Last time someone was all gung-ho to use new features to
make things more automagical, we got `@ISA = qw( Exporter );`.

Larry Wall

unread,
Sep 20, 2006, 7:34:05 PM9/20/06
to perl6...@perl.org
On Thu, Sep 21, 2006 at 12:43:41AM +0200, Juerd wrote:
: > my @bar = @{ $q->param->{ 'bar' } };

:
: my @bar = $q.param<bar>.'@';
: my @bar = @ $q.param<bar>;

That should work but my preference is just

my @bar = $q.param<bar>[];

That is, empty .[] has the same arrayifying semantics as @. (This is
currently b0rken in pugs though.) Likewise .{} is equivalen to %.

Larry

Juerd

unread,
Sep 21, 2006, 4:10:04 AM9/21/06
to perl6...@perl.org
Larry Wall skribis 2006-09-20 16:34 (-0700):

> That should work but my preference is just
> my @bar = $q.param<bar>[];
> That is, empty .[] has the same arrayifying semantics as @. (This is
> currently b0rken in pugs though.) Likewise .{} is equivalen to %.

Nice, but what's the syntax for an empty slice then?

Juerd

unread,
Sep 21, 2006, 4:13:55 AM9/21/06
to perl6...@perl.org
Mark Stosberg skribis 2006-09-16 21:32 (-0500):

> In theory, "use perl5:CGI" could be a fine solution. In practice, it
> hasn't worked out well for me.Even something that seems simple like

> passing a hashref to Perl 5 is not documented now.

I base my thoughts on Perl 6, not Pugs specifically. It's known that
Pugs doesn't implement all of Perl 6 perfectly yet, and Perl 5
compatibility is one of the many things that needs improvement. Give it
some time, and don't draw conclusions already.

David Cantrell

unread,
Sep 21, 2006, 7:31:36 AM9/21/06
to perl6...@perl.org
On Tue, Sep 19, 2006 at 08:16:26AM -0700, Randal L. Schwartz wrote:
> >>>>> "David" == David Cantrell <da...@cantrell.org.uk> writes:
> >> But don't throw out the simplicity of CGI.pm's basic task handling: parsing
> >> the incoming parameters (including file upload), and generating sticky forms
> >> and other common HTML elements.
> David> That's two tasks. It should be two modules.
> No, it's an *integrated* task. The form-generation stuff needs tight coupling
> with the getting (and setting) of the incoming param values.

Gosh, maybe that's why my next paragraph was:

" I suppose you could argue that generating <FORM> tags specifically and
all their baggage like <INPUT>s might fall under its remit (they are,
after all, what generates the fancy requests that are CGI's bread and
butter), but generating <H1> tags is most definitely not anything to do
with CGI. "

--
David Cantrell | Nth greatest programmer in the world

comparative and superlative explained:

<Huhn> worse, worser, worsest, worsted, wasted

Larry Wall

unread,
Sep 21, 2006, 6:24:38 PM9/21/06
to perl6...@perl.org
On Thu, Sep 21, 2006 at 10:10:04AM +0200, Juerd wrote:
: Larry Wall skribis 2006-09-20 16:34 (-0700):

: > That should work but my preference is just
: > my @bar = $q.param<bar>[];
: > That is, empty .[] has the same arrayifying semantics as @. (This is
: > currently b0rken in pugs though.) Likewise .{} is equivalen to %.
:
: Nice, but what's the syntax for an empty slice then?

Oh, I expect .[()] would work for that. Why you'd want one beats me.
Certainly it would work as a degenerate case of .[@empty] as well.

Larry

Juerd

unread,
Sep 21, 2006, 6:34:47 PM9/21/06
to perl6...@perl.org
Larry Wall skribis 2006-09-21 15:24 (-0700):

> : > That is, empty .[] has the same arrayifying semantics as @. (This is
> : > currently b0rken in pugs though.) Likewise .{} is equivalen to %.
> : Nice, but what's the syntax for an empty slice then?
> Oh, I expect .[()] would work for that. Why you'd want one beats me.

Generated code. It's nice that Perl usually isn't picky about such
things, because it saves you a lot of special cases when you're
generating code.

Larry Wall

unread,
Sep 21, 2006, 6:44:50 PM9/21/06
to perl6...@perl.org
On Fri, Sep 22, 2006 at 12:34:47AM +0200, Juerd wrote:
: Larry Wall skribis 2006-09-21 15:24 (-0700):

: > : > That is, empty .[] has the same arrayifying semantics as @. (This is
: > : > currently b0rken in pugs though.) Likewise .{} is equivalen to %.
: > : Nice, but what's the syntax for an empty slice then?
: > Oh, I expect .[()] would work for that. Why you'd want one beats me.
:
: Generated code. It's nice that Perl usually isn't picky about such
: things, because it saves you a lot of special cases when you're
: generating code.

Well, sure, and for related reasons 1..0 is an empty list rather than
a reversed list. On the other hand, we do use negative subscripts assuming
the user intended them. For the empty slice I expect the usual solution
would end up looking like .[,] unless the code generator outsmarts itself
by using join to suppress the trailing comma.

Larry

Mark Stosberg

unread,
Sep 27, 2006, 8:39:36 PM9/27/06
to perl6...@perl.org
Mark Stosberg wrote:
>
> When Perl 5 has references and Perl 6 doesn't, I don't know what to
> expect to when I need to pass a hash reference to a Perl 5 routine.
>
> Such details make no appearance currently in the Perl 6 spec, but I'm
> trying to gather them on the wiki if you have anything to add:
>
> http://rakudo.org/perl6/index.cgi?using_perl_5_embedding

I saw there have been some commits lately to Perl5 embedding, so I tried
some experiments with pugs to figure out if I could determine reliable
ways pass hashes and arrays to Perl5, so that they are received as
hashes, hashrefs, arrays, or arrayrefs, as appropriate.

I came up with the following test. As you can see, with arrays I was
able to pass them as a reference or not. However, when attempting to
pass a hash, it always came through as a hash, never flattened. Have I
missed something?

my $p5_dumper =
eval('sub {use Data::Dumper; print Dumper(@_); }', :lang<perl5>);

my @a = <b c d>;
$p5_dumper.(@a); # received as array
$p5_dumper.(\@a); # received as arrayref
$p5_dumper.(VAR @a); # received as arrayref

my %h = ( a => 1 );
$p5_dumper.(@%h); # received as hashref
$p5_dumper.([,] %h); # received as hashref
$p5_dumper.(|%h); # received as hashref
$p5_dumper.(%h); # received as hashref
$p5_dumper.(\%h); # received as hashref
$p5_dumper.(VAR %h); # received as hashref

A. Pagaltzis

unread,
Sep 29, 2006, 2:47:23 PM9/29/06
to perl6...@perl.org
* Mark Stosberg <ma...@summersault.com> [2006-09-29 14:18]:

> my $p5_dumper =
> eval('sub {use Data::Dumper; print Dumper(@_); }', :lang<perl5>);
>
> my @a = <b c d>;
> $p5_dumper.(@a); # received as array
> $p5_dumper.(\@a); # received as arrayref
> $p5_dumper.(VAR @a); # received as arrayref
>
> my %h = ( a => 1 );
> $p5_dumper.(@%h); # received as hashref
> $p5_dumper.([,] %h); # received as hashref
> $p5_dumper.(|%h); # received as hashref
> $p5_dumper.(%h); # received as hashref
> $p5_dumper.(\%h); # received as hashref
> $p5_dumper.(VAR %h); # received as hashref

I think you want

$p5_dumper.(%h.kv);

0 new messages