This FAQ assumes your Perl version is ActiveState 316 - if you don't have it then get it now.
Q: What is the advantage of PerlScript over CGI programming with Perl?
A: The first issue is speed. Most importantly PerlScript (ASP) is multi-threaded (not that the script writer will ever notice) which means that one instance of PerlScript is started (with the web server) and threads are spawned to process the scripts. This is different to Perl.exe which has to launch in a separate memory space from the web server and be launched for each and every script. PerlIS gets around some of the problems, but it appears that PerlScript is faster (in my examples anyway!).
Secondly PerlScript gives you access to a number of useful things:
Finally PerlScript embeds within the HTML, so you don't have to be a programmer to get a grasp of what's going on. Let me show you two equivalent scripts:
formproc.pl =========== require 'cgi-lib.pl'; &ReadParse(*input); print <<EOF; <HTML> <HEAD> <TITLE>Form Values</TITLE> </HEAD> <BODY> <H1>Form Values</H1> Value of Text1 = $input{'Text1'} </BODY> </HTML> formproc.asp ============ <%@ LANGUAGE = PerlScript %> <% use Win32::ASP; %> <HTML> <HEAD> <TITLE>Form Values</TITLE> </HEAD> <BODY> <H1>Form Values</H1> Value of Text1 = <%= GetFormValue('Text1') %> </BODY> </HTML>
OK, so it's not a great example because of the lack of complexity. But anyone coming to the second script won't have to deal with the <<EOF things found in so many scripts.
Q: There doesn't appear to be any documentation for PerlScript (ASP) - where can I find it?
A: You're reading it :-) Seriously though, ASP is simply an interface to a COM object model. Using ASP in PerlScript is the same as using Win32::OLE. The pre-defined objects are:
VBScript PerlScript -------- ---------- Session $Session Response $Response Request $Request Server $Server Application $Application *
* There appear to be problems with the Application object in PerlScript
To access the members of each object use the "->" arrow. Properties are accessed using $Object->{PropertyName} and functions using $Object->Func().
Example 1:
To get at the QueryString collection
* in the Request object use:
$FormVariableQ = $Request->QueryString("Q")->Item();
* collections act like functions that return RequestDictionaries, get each item in the dictionary with a call to Item($i)
Example 2:
To set a page to expire immediately (no
caching) use:
$Response->{Expires} = 0;
If you get stuck on anything use OLE Viewer and look at the Microsoft Active Server Pages object model, it's an awful lot easier to figure out things that way than using the VB Script oriented documentation.
A: Look at the sample that comes with PerlScript 313.
# get the value associated with 'MyVar' # increment the value then store it back $var = $Session->{'MyVar'}; $var++; $Session->{'MyVar'} = $var;
Simple eh?
You can use the session object for example to store a persistent database connection (This makes your app VERY fast):
In Global.asa
<OBJECT RUNAT=Server SCOPE=Session ID=Conn PROGID="ADODB.Connection"> </OBJECT> <SCRIPT RUNAT=Server LANGUAGE=PerlScript> sub Session_OnStart { $Conn->Open( "DSN=TESTING;UID=dba;PWD=sql" ); } </SCRIPT>
In your ASP file
<% $Conn->Execute(...); ... %>
Note: I couldn't get this to work in ActivePerl (builds 500 and 501).
Top
my $CookieVal = $Request->Cookies('CookieName')->{Item};
# Repeat for different values of SubCookie. # NB: SubCookie MUST be in capitals, even if you set it in lower case. my $CookieVal = $Request->Cookies('CookieName')->Item('SUBCOOKIE');
$Response->Cookies('CookieName')->{Value} = $Value;
# Repeat for different values of SubCookie # DOES NOT WORK UNDER "use strict"; $Response->Cookies('CookieName')->{SubCookie} = $Value;
# DOES NOT WORK UNDER "use strict"; Win32::OLE::with($Response->Cookies('CookieName'), SubCookie1 => $Val1, SubCookie2 => $Val2, SubCookie3 => $Val3);
$Response->Cookies('CookieName')->Item('Expires')->{Value} = "December 31, 2005"; $Response->Cookies('CookieName')->Item('Path')->{Value} = "/"; # Available on whole server $Response->Cookies('CookieName')->Item('Domain')->{Value} = "server.com"; # Only returned on server.com domain $Response->Cookies('CookieName')->Item('Secure')->{Value} = 1; # Boolean - set to 1 for secure cookies
To iterate over all the cookies returned:
foreach my $f (Win32::OLE::in ($Request->Cookies)) { Print "\n<br>", $f, " = ", $Request->Cookies($f)->{Item} ; }
(assumes Win32::ASP is loaded)
To iterate over a single cookie's dictionary:
foreach my $f (Win32::OLE::in ($Request->Cookies('CookieName'))) { Print "\n<br>", $f, " : ", $Request->Cookies('CookieName')->Item($f); }
Cookies do not get set if you specify an undef value.
Cookies do not get set (or return an error which it does in VBScript) if you try and set a cookie after sending any output whatsoever. You can overcome this by setting $Response->{Buffer} = 1;
There are problems under "use strict;" - the collection as hash ref hack doesn't work, so you can't do $Response->Cookies->{Name} = $Value any more (and should avoid doing it anyway), however that hack is the only way to set sub cookies at the moment. To quote Jan Dubois on this (thanks Jan!):
"I'm afraid that this involves "SetProperty with arguments" functionality. This is not yet implemented in Win32::OLE and was undocumented in the old OLE.pm module. Of course you had the special case of "SetProperty with single argument" as a byproduct of the collection/property dualism hack."
Q: Form variables seem to be different depending on whether you use POST or GET, cgi-lib/CGI.pm were never like this. I want to use GET to develop and POST for production, how can I do this easily?
A: OK, so this is just a plug, but you need my Win32::ASP module. It contains a functions called GetFormValue which takes a Form name (the text from NAME="..." on your form) and optionally an index. See the documentation for why the index is there. Get it from:
http://come.to/fastnet/
Top
Q: Why doesn't die or exit stop my script?
A: Because the engine processes the whole of the script, only stopping if it comes across a $Response->End(). To get around this, and make programming easier for perl programmers, use Win32::ASP as mentioned above and you get all the functionality of die and exit back again...
Q: When I try to call a VB Script function from my PerlScript, it says the function doesn't exist.
A: You need to call it as:
$ScriptingNamespace->VBScriptFunctionName();
Top
Q: When I call a PerlScript function from VB Script it corrupts the parameters. Is it something I'm doing wrong?
A: No. This is a bug in PerlScript that is being worked on. For now there is a work around: use a session object to pass the parameter.
A: See the PerlScript security warning I posted, other than that it's secure - probably more so than VBScript.
A: http://www.activestate.com/
Get yourself a copy of ActivePerl, and select PerlScript when installing.
A: This assumes you are using ActivePerl (perl 5.005 and above)
Use the "in" function in Win32::OLE:
foreach $f (Win32::OLE::in ($Request->Form)) { # Do something with $f here }
BinaryWrite is needed if, for example, you want to send a GIF to the browser instead of HTML. The problem is that internally Perl doesn't support unicode (yet), which are strings that are wider than ordinary ASCII (an 8bit string representation). OLE (and thus the ASP object model) expects unicode wherever it goes, and so it converts to unicode whenever you pass a scalar to an OLE function. In order to do this perl (really Win32::OLE) simply pads with nulls. This breaks things like GIFs being sent. The way around it is to use the Win32::OLE::Variant module to explicitly convert to a variant first before outputting:
<%@ ENABLESESSIONSTATE=FALSE LANGUAGE=PerlScript %> <% use Win32::OLE::Variant; $Response->{ContentType} = 'image/gif'; my $filename = $Server->MapPath('aspfdr.gif'); my $buf; open ( FILE, $filename ); read ( FILE, $buf, 10000 ); close FILE; # This converts to a variant unicode value my $variant = Win32::OLE::Variant->new( VT_UI1, $buf ); $Response->BinaryWrite($variant); %>
Or use the latest Win32::ASP module and the Win32::ASP::BinaryWrite function to hide the conversion.
-----------------------------------------------------------
This FAQ is Copyright © Fastnet Software Ltd, 1998 - All rights reserved. For your use it is released under the same licence as Perl itself, and may be distributed under the same terms and conditions.
Mailto:sergeant@geocities.com for praise/flames/criticism or just to drop me a line, or visit my web site at http://come.to/fastnet