This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
|
Active Scripting with PerlScript
Tobias Martinsson |
Download the code (7KB)
Scripting in ASP isn't limited to VBScript and JScript. PerlScript is an offshoot of Perl, and finds itself at home in Active Server Pages, thanks to Active Scripting.
For the majority of ASP programmers, VBScript, the default language of ASP, has been the scripting language of choice. Few people know that PerlScript is also supported in Active Server Pages. And there's little documentation on how to use scripting languages other than VBScript or JScript® with ASP. This article will introduce you to how PerlScript can be used to build powerful Web applications. It will also show you how PerlScript works together with ASP.
It's no surprise that there are syntactic differences between VBScript and other scripting languages. This is a good reason to carefully select the language you feel most comfortable with when you start using ASP. In my case, I thought it would be a very good idea to have both the features of a full-fledged version of Perl and access to ActiveX® Data Objects (ADO) and ASP objects on my Web server. Apparently someone else thought so too, because the ActiveState Corporation (http://www.activestate.com) has released the PerlScript product. If this is your first PerlScript lesson, congratulations! You're teaching yourself what is, in my opinion, the most powerful language that exists for Web applications. Perl, with a bit of effort, gives you the potential to write scripts that can work with server software that does not necessarily support ASP technology. To walk you through some PerlScript basics, I'll show you how to write a site that works like a database application,
but which resides in the form of a Web page on your server, fully administrated from your browser. Realistically, building a full-blown application of this kind is very time-
consuming, so it'll be up to you to finish the work started here. To design this miniature database, I'll demonstrate ADO, session variables, and the handling of form data through the Request object. You don't need to know Perl; all you need to understand the program is a basic knowledge of HTML and ASP. Obtaining and Using PerlScript
To obtain and use PerlScript for your Web server with ASP-support, you need to do the following:
|
|
within your ASP document or .inc file. The PerlScript code goes inside the <% and %> tags, just like VBScript or JScript code would. If you want to permanently set your default language to PerlScript in Microsoft® Internet Information Server (IIS) 3.0 or earlier, you can update the following registry key to the value "PerlScript". |
|
This setting was moved to the IIS metabase in version 4.0, so it no longer works in the newest releases.
There are no known problems you should encounter when installing and running PerlScript on either Personal Web Server (PWS) for Windows® 98 or IIS (part of Windows NT® 4.0 and Windows 2000). Active Server Pages Technology Active Server Pages technology supports the access of ADO and ASP objects from your scripting language of choice. The ASP objects consist of six built-in objects: Application, ObjectContext, Response, Request, Session, and Server. The ASP objects are, in short, the basis for data communication between client and server. Each one of these objects has individual properties and methods that you can employ. Moreover, all objects but the ObjectContext and Server have individual collections, which I'll describe in a moment. ADO is a collection of external objects whose sole purpose is making your life easier when you are working with databases. The primary ADO objects are Connection, Recordset, and Command. If you're already familiar with ASP programming from your experiences with VBScript or JScript, you'll be pleased to find that the migration from VBScript to PerlScript is easy. In VBScript, you can invoke the method of an object with the syntax object.method. PerlScript works the same way, but with a Perl-specific syntax: |
|
This is not a very drastic change for an experienced programmer, and it's well worth the three extra characters considering the enormous collection of packages and functions that come with PerlScript.
You will need to know two more things inside out: properties and collections. The property of an object is a value available by calling |
|
If you want to get the current session ID, for example, you can call: |
|
For properties that are settable by the programmer, you can use a syntax like this: |
|
This call sets the Session to time out after 60 minutes without activity. This setting can be put in either the Global.asa file that exists in your application's root directory or inside your ASP document.
The second property type you should pay attention to is the collection, which is really a variable holder. You are required to specify which collection you want to request from the object. Furthermore, you must specify which variable within the collection to return. The two most common approaches for returning a collection variable are |
|
and |
|
For a QueryString or Form collection, you normally use |
|
or |
|
or |
|
Beware this syntax, because the second example above can randomly return nothing but a memory reference to the variable. For example, say that the form element "Personal Information" was filled out at your Web site and passed to your script through the QueryString. With PerlScript, you could grab the variable "FirstName" syntactically by calling |
|
or |
|
Consequently, in order to get the fully unencoded QueryString collection, you must issue the command |
|
To create a variable in a collection, you use the SetProperty method. If you want to set a property in the $Session->Contents collection, the syntax is: |
|
To display a variable that is in the same Contents collection, you would issue the following command |
|
Before beginning to use ADO, you need to understand a couple of basic concepts. In ADO, the Connection object takes a string representing a Data Source Name (DSN) and returns a SQL session, from which you can execute SQL commands. According to the ASP documentation, every object should be automatically destroyed when a page is finished rendering.
In some versions of PerlScript, problems exist with this object destruction process. If you've downloaded a version prior to release 510 (where this bug has been fixed), you can bypass the bug by calling the method Win32::OLE->Initialize before creating your objects. The Recordset and Command objects are also key ADO concepts. Recordsets have methods for navigating and manipulating a set of records returned from a SQL query. The Command object is used to explicitly execute commands, SQL queries, or stored procedures with the Connection. While using the Command object is faster and more reliable than executing commands directly from the Connection object, I personally don't have to use it often from my applications. Any SQL-related command executed at the Connection object returns a Recordset, and a Connection object can execute SQL commands perfectly well on its own. The code in Figure 1 shows a PerlScript-based ASP page. It has several variables declared and initialized (with the "my" syntax, which I'll describe shortly). The variable $SQL represents the SQL that the Connection will execute. The Connection object (named $Connection) is instantiated by calling the CreateObject method of the Server object. Next, the Connection's Execute method is called with the $SQL variable passed in as a parameter. The results from this call (a Recordset) are stored in $Result. The code next loops through all the field values of the ID column in $Result until it hits the end of file. After the loop exits, the Recordset and Connection objects are closed. Figure 2 shows the Connection scheme. |
Figure 2: Connection Scheme |
Perl/PerlScript Variables
In the previous example, some of the syntax might have looked like it belongs on another planet, especially if you come from a VBScript background. Let's look at how PerlScript handles variables. Perl and PerlScript's primary variable is the scalar datatype. It is declared and initialized as: |
|
A scalar works the same way as a variantit can store numerals as well as strings, and you never declare one as a specific datatype. Although it's not required, it's good practice to declare the range of the variable upon creation using either the keyword my or local, like this: |
|
Variables of the type my have a scope limited to the block of code in which they're declared, while local variables can be used both within the declaring block and inside any blocks of code called from within that block. (Blocks of code are considered any code within a while loop or subroutine.)
A second datatype is the array, which is a list of elements containing scalar data. An array is declared and initialized in one of these three ways: |
|
You must specify my; omitting it causes ASP to set the default scripting language to the name you used for your array because of the similar @ syntax. PerlScript arrays are indexed by integer value, and always have a starting index of zero. To get the total number of indexed elements in an array, PerlScript supports a special variable called $#nameofarray. There are different ways to display one or more variables of an array; the following statements are valid for single elements: |
|
To display the very first element, you can set the index to $# or zero; an entire array can be referred to with an @ prefix. These techniques come in handy when you want to loop through an array and print all its elements: |
|
PerlScript supports several functions that help you manipulate arrays. For example, you can sort the elements of your array alphabetically, numerically, or simply reverse the order. An alphabetical sorting function is |
|
The numerical equivalent is |
|
To reverse the order of your elements, use |
|
You can use functions like this as the statement of a control structure, like so: |
|
Every classical programming language has functions for adding and removing elements from an array. In PerlScript, these functions treat the array like a stack. Pop will remove and return the last element of an array, while push adds array elements to the end of the array. The shift function removes and returns the first element of the array, and unshift is used to add elements to the beginning of the array. To remove the last element from the array aname, you can say |
|
while |
|
adds three values to the end of the same array. For an illustrated view of an array stack, see Figure 3. |
Figure 3: Array Stack |
Associative arrays (also known as hashes) index their elements with strings, not integers. The keys and values of an associative array are declared and initialized with the following syntax: |
|
If you want to declare and initialize an associative array, then loop through all keys of the hash and print the value for each corresponding key. You can do something like this: |
|
Within ASP pages, associative arrays can be used in numerous ways. Whether you want to store input data, regular data, or collections, they're handy when you want to retrieve values by key item. Keep in mind that all types of arrays are used to store associated data as a group, and for single data items you are best off using scalar variables. The Database Application The information you've seen so far has explored important basics of PerlScriptthe variables of the language. You've seen how to declare and initialize variables, but you also need to know how to match the variables with other data. The sample application will implement open, add, modify, delete, and view commands. Every action will be presented within an HTML form, so they'll need to be launched with submit buttons. One submit button will be set for each action; because only one action can be performed at a time, these buttons will have the same name but different values represented by their captions (Add, Delete, and Modify). The code can then request the form elements based on the name of the action element, match up the value, and figure out what the user wants the program to do. Consider this example: |
|
The code produces three buttons on the screen. But since they have the same name, only one value will be passed in the QueryString to the program. To get the value of the clicked button from the QueryString, you can say the following: |
|
When the value has been retrieved, you can use a case statement to match the value of the string and run the proper block of code. In the PerlScript case statement, the special variable $_ is used as a data holder. PerlScript assumes that this is the value to use when no other variable is specified (see Figure 4). Iterating the Collection of an Object Since the program will deal with quite a few form elements, let's look at how to iterate through an object's collections. As with most ASP pages, the most important collection is QueryString. Since PerlScript collections are based on OLE, you can use the Win32::OLE module to look at them. This module has a method named in, which allows you to browse through collections. Naturally, the most convenient approach is to store the values in an associative array and later refer to them by name, so you can do that as well. Whenever a QueryString is passed to you, it's good programming practice to grab it like this: |
|
This example iterates through the QueryString collection and sets the appropriate keys and values in the associative array. From there on you only need to call it by its key name (the name of the form element) to get the value (the value of the form element).
In the previous piece of code, I've covered most of the basics of PerlScript for ASP. You've seen what the program's interface should look like, how to use database connections, and how to grab QueryString data. The next step is to write an intuitive program that digs just a little bit deeper into the database you want to manipulate and issues SQL commands to the database. The Intuitive Database Application To build a truly intuitive database application, several aspects of the database need to be taken into consideration. Let's simplify by giving the user the option of typing in which System DSN to open and what table to work inside. All that work can be taken care of from a simple login page. While this solves many problems, you won't have a useful application unless you retrieve the field names of the open table and present them to the user. Moreover, you need to allow the user to create new entries and new tables in an easy yet practical way. To use the object model efficiently, you can store information such as the DSN and table name in the Session object. This eliminates the chore of passing numerous values between the documents as hidden form fields. The field names (or columns) of a database table are stored in the Fields collection, which is part of the returned Recordset. You can reuse the technique of iterating through the QueryString collection and storing names and values, but this time you'll be working with a regular array. You need to be able to create a program that writes SQL statements without having to tell it what field to put where. There's already a Recordset equivalent with a Fields collection, containing the records returned from a call to |
|
Consider the example in Figure 5.
What's left is a little SQL, a script that creates new tables, and a modular programming structure. For each action in the case statement to work properly, and to keep the code clean and neat-looking, code should not be executed by default inside of subroutines. A subroutine's structure looks like this: |
|
The code within curly brackets is executed when you call
the subroutine by &sname;. You may specify parameters and return values when you call the subroutine. Your parameters are collected in the special variable $_ or @_ within the
subroutine. In this database program, the database mani-pulation routines are reusable and will fit in subroutines, while the case statement is run only once to call the appropriate subroutine. The Source Code The source code for the ASP database consists of five files: the login screen (see Figure 6), the table manager (see Figure 7), files that let you specify and create tables (see Figure 8 and Figure 9), and a PerlScript include file (see Figure 10). The database-specific information, such as DSN, table name, and field names, are stored as Session variables and are available in the Contents collection; this is done at login. Information that relates to the user's action, like adding or modifying an existing entry in the database table, is dynamically editable from within the form elements and are passed in through the QueryString collection. The current entries in the database table are displayed in a dropdown menu, from which the user can select the entry to put on display or delete. The value of each element in the dropdown menu corresponds to the ID value returned by the database software, and is presented in the menu with the values of the first two fields. This is the most effective way of locating the selected data in the database. When the user wants to create a new table, they must enter the name of the table and the number of fields it contains. This information is passed via the QueryString to the script that generates tables. This script then outputs the same number of text fields within the form as the number of columns the program was told to produce. The user enters the name for each field, and whether the field holds text or integers. To simplify matters, the code presets the number of characters for each text field to 80. However, with a minor modification you can add a text field that lets the user specify the number of characters. Since the code handles both text and integers, there's one important thing to remember. PerlScript stores everything as a scalar, and scalars can hold both text and integers. This means that you can make only text columns when creating database tables and get away with it. In fact, you can even store floating-point values in a text field. Since PerlScript doesn't strongly type variables, you can save them as text and manipulate them easily. To close the connection and clean up the session, give the user a logout option that closes the session, then calls its abandon method. Conclusion
PerlScript makes development on Windows-based Web servers easier, and it offers the advantage of inline Perl embedded in HTML. If portability is an issue, standard Perl may be a better choice for you. Still, if you use PWS or IIS, PerlScript is a good solution. For further information about PerlScript, ADO, ASP, and SQL, please visit http://www.perlscripters.com. The site also provides information on the setup of system and file DSNs. Happy coding! |
http://support.microsoft.com/support/kb/articles/Q150/6/29.asp |
From the August 1999 issue of Microsoft Internet Developer.