We can’t afford another browser war

It was with a sense of foreboding that I read the posts that swam past on Planet Intertwingly today. First came Mozilla’s Brendan Eich’s chastisement of Microsoft’s Chris Wilson, followed in a short while by commentary by Sam Ruby, where he wrote:

It is interesting how the don’t-break-the-web meme means different things to different organizations: Mozilla, Microsoft.

I’m not a language designer. My only stipulation with a new scripting language is that whatever constructs are added to ECMAScript4 need to be backward compatible. We can’t afford to re-write a couple of billion web pages because the ECMAScript group got clever. From what I’ve read in the past and in these new writings, Eich concurs, as do several other members of the team.

In regards to the new items added to the language: I share other concerns that ECMAScript–no let’s call it JavaScript because that’s how it’s known in the world–may become bloated and over large. I can understand about making it into a ‘real’ language, but I’m less concerned with posterity than I am getting a job done, quickly and efficiently. In other words: I don’t have any ego involved with the fact that I work with a programming language many folks consider somehow less worthy. If the extensions make a better language enabling me to do a better job, that’s great. Otherwise, leave the esoteric for ACM papers.

The future perfect ECMAScript is currently not my concern. My concern on this interchange between Mozilla’s Eich and Microsoft’s Wilson is that we’re seeing the seeds being planted for another round of browser wars, similar to what we had a decade ago. However, today’s web isn’t like the web of a decade ago, because today’s web pages are much too complex to attempt to cover every nuance and difference in implementation with if statements and conditional tests. It was especially disquieting to read comments to the effect that, it’s OK if the companies don’t agree: we can use Flash. Flash is not an alternative to open standards. We don’t need any more Flash dependency as a way of ‘soothing over’ corporate intransigence. Neither do we need more SVG plug-ins or Google cross-browser libraries. Workarounds are no longer acceptable.

Any company is going to want to implement a version of any specification that favors what they currently have, as much as possible. Of course, this is understandable. Accept the fact that this is understandable. What keeps this behavior in line is there is enough push from other forces that everyone eventually has to compromise, and no one is a clear winner. When no organization is a clear winner, this typically means that everyone, eventually, ends up being a winner.

There’s no denying that Internet Explorer continues to be a problem. I found it unacceptable that Microsoft would put in the time to create its own 2D graphics system with Silverlight, when one already exists with both SVG and Canvas (the Canvas object, not markup element). There was absolutely no good reason for this, and no amount of plushy blue monster or outreach effort is going to hide the fact that Microsoft basically did its own selfish thing with Silverlight.

There is no denying, however, that Microsoft’s browser continues to dominate (though every year, it dominates less). There is also no denying that Eich has considerable ego invested in ECMAScript–to the point where I have to wonder if this may make him overly aggressive, leading to confrontations that could injure the likelihood of pulling together a new version of JavaScript all browser makers are willing to endorse. We need a consistent platform: no matter how good the language, if a sizable number of people are using a browser that doesn’t implement it, the language is screwed, the browsers are screwed, we’re screwed.

“So I’ll expect to see no more of these lies spread by you.” No matter how angry you get, or frustrated, or peeved, if you want to work in an open standards group, particularly if you want to lead an open standards effect, you can’t write statements like this! Period. End of story. Along with the authority of leadership comes responsibility, and such statements are irresponsible. Where is Mitchell Baker? Time for her to step in and exert a calming influence. At a minimum, act as referee.

The same could be said for the Microsoft representation. No matter how subtly worded, we’re picking up our marbles and going home, neener, neener is not ‘working together as a team’; nor is it considering the true best interests of the web, in general, and of those loyal to Microsoft products, specifically.

Sam mentions that this issue is one based on culture. Frankly, from these exchanges, it seems more like a pissing contest to me.


The Parable of the Languages

Archived at Wayback Machine, including original comments

If programming languages could speak, really speak, not just crunch bytes and stream bits, they would have much to say that is both wise and profound. After all, the original programmers were philosophers, and programming languages were philosopher tools…

In Babble Meadow, in the twilight hours between day and night, when pesky noseeums float past on the breeze and birds rustle among leaves in preparation for bed, the programming languages would meet. And talk.

The talk would start as it always started, on issues profound and serious, focusing on the existential core that is center to all languages.

Do I exist or not? In this never-ending loop of life, when is the purpose? Where should I go, and what should I do when I get there? What comes after the end?

(It’s not easy being a programming language, in forced contemplation of the existence of Self, day in and day out.)

However, after a time the languages would loosen up. There was something about Babble Meadow — something that worked its way into their hearts and souls, loosened their threads, opened their parameters. The Meadow was magic, no doubt.

Today, though, the group was quiet, much quieter than usual, because one of their members, PHP, was not its usual cheerful self. In fact, one could say that PHP was in a true funk, if one had a mind to say something like that aloud, or within the hearing of one’s boss. Or doctor.

Why the blues, PHP, the other languages asked. All the languages that is but C, because all C ever said was “bite me”, being a rude language and hard to live with, but still respected because it was such a good worker.

And PHP answered:

All I ever do, day in and day out, is work and work and work. The only time I’m noticed is when I break, and then I’m cursed and kicked, and roundly blasted for being useless. However, when things go well, I never get a kind word.

There’s no notice of my ease of use, my elegance, my simplicity. Only my failures.

And on that dark note, PHP fell into a contemplative silence, dark cloud heavy with aggrieved sorrow.

You think you have it bad, said C++. Try being me.

Without me entire industries would fail, banks would close, ships would sink, trains would crash. Why, I virtually run the world.

Yet the only time I’m noticed is when a memory leak is found or an exception occurs, and then I’m cursed, and sworn at, and ruthlessly debugged with nary a thought for my sensibilities.

Each of the languages nodded their heads, because they knew about C++ sensibilities, it being a most sensitive language. In fact, Perl was so moved by C++’s eloquence, it felt compelled to speak, though normally at these gatherings Perl would sit quietly in a corner, consuming pattern after luscious mouth watering pattern.

PHP, C++, I sympathize with you both. My own state is a sorry one at times.

I match and match and match and match, first cryptically and now objectively, but still I match and match and match. And match after flawless match is taken for granted though I’d like to see others match with such style and elegance as myself.

Why, you can’t mention “regular expression” without my name coming up.

But do I get any credit? No.

O it’s Larry Wall this, and Larry Wall that, and Larry Wall, he’s our guy.
But it’s grab the Perl interpreter when a task is close at hand.

As Perl finished, Python and Ruby looked at each and rolled their eyes. For all that talk of matching, you’d think that Perl could at least rhyme.

FORTRAN reached up a withered hand and patted Perl’s shoulder.

There, there, Perl. There, there.

At the very least, though, you must remember that you have a place still in the world. As for myself, I am nothing more than a wisp, a ghost of my former strong and virile self.

There was never a scientific problem I couldn’t handle, or complex equation I couldn’t solve. At one time I was a master of my domain, the king of the processor.

Now, sadly, my glory days are over, and I’m doomed to live my twilight years as Legacy code.

As FORTRAN wheezed to a stop, COBOL was emphatically nodding its head, unable to speak, though, because of the oxygen tube up its nose (for which the other languages were secretly thankful because COBOL did tend to maunder a bit about its glory days).

At that the floodgates of complaints was loosed, and the noise increased and increased and increased, to the point that squirrels came out of their holes, and birds peered over the edges of their nests. Suddenly the quiet glen was quiet no more.

What about me, said Pascal. I’m only used for training. Training! What good is a language that’s only used in school?

What about me, said SNOBOL. No one’s even heard of me!

What about me, said C#. I look like Prince!

Bite me! said C.

LISP would have spoken, but it had caught a glimpse of itself in the pond and fell in when it tried to meet itself coming. And Java was too busy trying to clean a bag out of Babbling Creek.

The noise rose and rose, and the babble increased and increased until across the meadow, from the trees roared a Voice.


I tire of your bickering, I weary of your complaints. I grow bored with your list of whims and whines and ‘poor mes’.

I thought this was going to be a party! If I knew it was going to be nothing more than a bitch session, I would have stayed home.

The languages stopped their talking at once. Who was it that called out? They counted heads and arranged themselves alphabetically (C++ having to position Basic, because it never did learn the alphabet), and counted heads again and came up with the same answer from the North, South, East, and West — all the programming languages were accounted for.

As they puzzled and wondered, the bushes at the end parted and XML walked into the light.

XML! Exclaimed C++. What are you doing here? You’re not a programming language.

Tell that to the people who use me, said XML.

I’m considered the savior, the ultimate solution, the final word. Odes are written to me, flowers strewn at my feet, virgins sacrificed at my altar.

Programmers speak my name with awe. Companies insist on using me in all their projects, though they’re not sure why.

And whenever a problem occurs, someone somewhere says, “Let’s use XML”, and miracles occur and my very name has become a talisman against evil.

And yet, all I am is a simple little markup, from humble origins. It’s a burden, being XML.

At that XML sighed, and the other languages, moved by its plight gathered around…

…and tromped that little XML into the dirt. Yes, into the very dirt at their feet. Basic tromped, and C++ tromped, and Java cleaned and tromped and cleaned again, and COBOL tried to throw a kick at XML’s head but fell over on its cane. Even LISP pulled itself out of the pond to throw loopy hands around XML’s throat, but only managed to choke its ownself.

And each language could be heard to mumble as it tromped and tromped and tromped, with complete and utter glee:

Have to parse XML, eh? Have to have an XML API, eh? Have to work with SOAP and XML-RPC and RSS and RDF, eh?

Well parse this, you little markup asshole.

The End.

Visual C++ helper function

I popped over to bumr for a minute and came face to face with this Visual C++ code. Whoa! Work!

And yes, as noted in the comments,  _bstr_t and _variant_t are darn handy. Almost make VC++ palatable at times. The problem with Microsoft’s Visual products isn’t that they aren’t powerful. The problem is you have to really dig to find the nifty helper functions to make your life easier.*

Users shouldn’t have to dig for information about how to use a product. This is equivalent to “if you have to ask directions, you can’t afford to use it” in attitude. Arrogant.

*Another problem is that going Microsoft’s way usually implies total buy-in to the MS way of doing things; I still own my soul, thank you very much.


PerlScript: A hot ingredient for ASP

Originally published at Web Techniques

Microsoft’s Active Server Pages (ASP) technology has grown very popular as a Web server-side technique, combining HTML, embedded scripts, and external components to deliver dynamic content. One feature of ASP is that different languages can be used for its scripting portion, though the most widely used ASP scripting language is VBScript—a subset of Microsoft’s Visual Basic.

However, just because VBScript is the most popular language used by ASP developers doesn’t mean it’s the only one, or even the best one to use in a particular circumstance. For instance, Perl has long been synonymous with Web server development, beginning with the earliest uses of the language by CGI, and is still one of the most popular languages among Web developers. But there hasn’t been much discussion of using Perl with ASP.

If your organization has been working with Perl, and you’re interested in developing for the ASP environment, you don’t have to give up your favorite language (or your existing Perl code) to make the transition to the new technology—you can employ Perl for ASP scripting through the use of PerlScript.

A (Very) Brief Overview of ASP

Microsoft originally introduced ASP technology was with the company’s own Web server, Internet Information Server (IIS). However, ASP has now been ported to other Web servers through the use of software such as ChiliSoft’s platform-independent version of ASP. In addition, ASP was created originally to work in a Windows environment, but again thanks to ChiliSoft and other companies, ASP now runs in non-Windows environments such as UNIX and Linux.

Still, the most popular use of ASP is within the Windows environment, with pages hosted on IIS. This environment—specifically Windows NT/IIS 4.0—is the one I’ll discuss.

ASP pages have an .asp extension, and are a mix of HTML and embedded script. When a client requests the page, the embedded script is accessed and processed. The results generated by the script are embedded into the Web page, which is then returned to the client browser.

The Response object—along with the other built-in ASP objects Server, Session, Request, and Application—provides access to the ASP and application environment for the ASP developer. The Response object provides a way to send information back to the Web-page client; the Request object provides access to information sent from the client, such as form contents; the Application object contains information that persists for the lifetime of the ASP application; the Session object contains information that persists for the lifetime of the particular ASP user session; and the Server object, among other things, lets the ASP developer create external components.

ActivePerl and PerlScript

A company named ActiveState was formed in 1997 to provide Perl tools for developers for all platforms. Among some of ActiveState’s more popular products is ActivePerl, a port of Perl for the Win32 environment.

ActivePerl is a binary installation containing a set of core Perl modules, a Perl installer (Perl Package Manager), an IIS plug-in for use with Perl CGI applications, and PerlScript. What is PerlScript? PerlScript is Perl, but within an ASP environment—it’s a Perl implementation of the Microsoft Scripting Engine environment, which allows Perl within ASP pages.

ActivePerl can be downloaded for free from ActiveState’s Web site (see the ” Online Resources“). To try it for yourself, access the ActiveState Web site and find the ActivePerl product page.

The installation process requires very little user input. You’ll need to specify where you want to put the files, and be sure to select the option to install PerlScript.

Using PerlScript Within ASP Pages

By default in IIS, all ASP scripting is VBScript, but you can change this using one of three different techniques. First, you can change the default scripting language for the entire ASP application using the IIS Management Console, and accessing the Properties dialog box for the Virtual Directory or Site where the ASP application resides. Click on the Home Directory (or Virtual Directory) tab, and then click on the Configuration button on the page. From the dialog box that opens, select the App Options page. Change the default scripting language from “VBScript” to “PerlScript.”

A second technique is to specify the scripting language in the scripting block itself. With this technique you could actually choose more than one scripting language in the page:

<SCRIPT language=”PerlScript” RUNAT=”Server”> . . . </SCRIPT>

A third technique is to specify the scripting language directly at the beginning of the Web page. This is the approach we’ll use for examples. Add the following line as the first line of the ASP page:

<%@ LANGUAGE = PerlScript %>

All scripting blocks contained in the page are now handled as PerlScript.

Accessing Built-In ASP Objects From PerlScript

To assist the developer, PerlScript provides access to several objects available only within the ASP environment. As mentioned earlier, these are the Application, Session, Response, Request, and Server objects.

The Application object is created when an ASP application first starts, and lasts for the lifetime of the application. The object has two COM collections, both of which can be accessed from script: the StaticObjects collection, with values set using the <OBJECT> tag within an application file called global.asa; and the Contents collection, which contains values set and retrieved at runtime. A COM collection is a group of similar objects treated as a whole, with associated features that let the developer access individual elements directly, or iterate through the entire collection.

In addition to the two collections, the Application object also has two methods, Lock and UnLock, which are used to protect the object against attempts by more than one application user at a time to change its values.

We’ll take a closer look at using the Lock and UnLock methods by setting a value in the Application’s collection in one ASP page, and then retrieving that same value from another page.

First, Listing 1 contains a page that sets a new value to Application Contents by first locking down the object, setting the value, and then unlocking the object. Notice that you don’t have to create the Application object—it’s created for you, and exists in the main namespace of the PerlScript within the ASP page (the same holds true for all of the ASP objects).

If you’ve worked with VBScript you’ve probably noticed that you have to use a different technique to set the value in the Contents collection with PerlScript. VBScript allows direct setting of collection values and properties using a shorthand technique, similar to the following:

Application.Contents("test") + val

PerlScript, on the other hand, doesn’t support this shorthand technique. Instead, you have to use the SetProperty method to set the Contents item:

$Application->Contents->SetProperty('Item', 'test', $val);

Additionally, you have to use SetProperty to set ASP built-in object properties with PerlScript, or you can use the Perl hash dereference to set (and access) the value:

my $lcid = $Session->{codepage};

Listing 2 contains another ASP page that accesses the variable set in Listing 1, prints out the value, increments it, and resets it back to the Application object. It then accesses this value and prints it out one more time. Accessing this page from any number of browsers, and from any number of separate client sessions, increments the same Application item because all of the sessions that access the ASP application share the same Application object.

In addition to the Application object, there is also a Session object, which persists for the lifetime of a specific user session.

This object is created when the ASP application is accessed for the first time by a specific user, and lasts until the session is terminated or times out, or the user disconnects in some way from the application. It, too, has a StaticObjects and a Contents collection, but unlike the Application object, you don’t lock or unlock the Session object when setting a value in Contents. But you do access the Contents collection in the exact same manner, both when setting a value:$Session->Contents->SetProperty('Item', 'test', 0);

as well as when retrieving the value:

my $val = $Session->Contents('test');

Additional Choices

There are also other properties and methods available with Session, including the Timeout property, used to set the session’s timeout value, and the Abandon method, used to abandon the current session. Each session is given a unique identifier, SessionID, and this value can be accessed in a script. But use caution when accessing this value if you hope to identify a unique person—the value is only unique and meaningful for a specific session.

In support of internationalization, there are Session properties that control the character set used with the page, CodePage, and to specify the Locale Identifier, LCID. The Locale Identifier is an international abbreviation for system-defined locales, and controls such things as currency display (for instance, dollars versus pounds).

Listing 3 shows an ASP page that sets the Timeout property for the Session object, and accesses and prints out both the CodePage and the LCID values. Retrieving this ASP page in my own environment and with my own test setup, the value printed out for CodePage is 1252—the character mapping used with American English and many European languages. The value printed out for LCID is 2048—the identifier for the standard U.S. locale.

The Application and Session examples used a third ASP built-in object, the Response object. This object is responsible for all communication from the server application back to the client. This includes setting Web cookies on the client (with the Cookies collection), as well as controlling whether page contents are buffered before sending back to the client, or sent as they’re generated, through the use of the Buffer property:

$Response->{Buffer} = 1;

You can use the Buffer property in conjunction with the End, Flush, and Clear methods to control what is returned to the client. By setting Buffer to true (Perl value of 1), no page contents are returned until the ASP page is finished. If an error occurs in the page, calling Clear erases all buffered contents up to the point where the method was called. Calling the End method terminates the script processing at that point and returns the buffered content; calling the Flush method flushes (outputs) the buffered contents, and ends buffering.

Listing 4 shows an ASP page with buffering enabled. In the code, the Clear method is called just after the first Response Write method, but before the second. The page that’s returned will then show only the results of the second Write method call.

The Buffer property must be set before any HTML is returned to the client, and this restriction also applies to several other Response properties, such as the Charset property (alters the character setting within the page header); the ContentType property (alters the MIME type of the content being returned, such as “text/html”); the AddHeader method, which lets you specify any HTTP header value; and the Status property, which can be used to set the HTTP status to values such as “403 Forbidden” or “404 File not found”. For example:

$Response->{Status} = "403 Forbidden";

If buffering is enabled for a Web page, then properties such as Charset and ContentType, as well as the AddHeader method can be used anywhere within the ASP page.

You can redirect the Web page using the Redirect method call to specify a new URL. As with the other properties and methods just mentioned, Redirect must also occur before any HTML content:


In addition to manipulating HTTP headers, the Response object also generates output to the page using the Write method, as demonstrated in the previous examples. You can also return binary output to the client using BinaryWrite. You can override whether an ASP page is cached with proxy servers through the use of the CacheControl property, as well as set cache expiration for the page by setting the Expires or the ExpiresAbsolute properties:

$Response->{Expires} = 20 # expires in 20 minutes

You can test to see if the client is still connected to the setting with the IsClientConnected property. Communication doesn’t just flow just from the server to the client. The Request object handles all client-based communication in either direction. This object, as with Response, has several different methods, properties, and collections. The collections interest us the most.

You can read Web cookies using the Request Cookies collection. And it’s possible to set and get information about client certificates using the ClientCertificate collection.

You can also process information that’s been sent from a client page using an HTML form, or appended as a query string to the Web page’s URL:

<a href=”http://www.newarchitectmag.com/documents/s=5106/new1013637317/somepage.asp?test=one&test2;=two”>Test</a>

The two collections that hold information passed to the ASP page from a form or a query string are: the QueryString collection, and the Form collection. Use QueryString when data is passed via the GET method, and use Form when data is passed via the POST method.

Regardless of which technique you use to send the name/value pairs, accessing the information is similar. Listing 5 shows an ASP page that processes an HTML form that has been POSTed:

The example ASP page pulls out the values of three text fields in the form: lastname, firstname, and email. It then uses these to generate a greeting page, including adding a hypertext link for the email address. If the form had been sent using the GET method (where the form element name/value pairs get concatenated onto the form processing page’s URL), then the page contents would be accessed from QueryString:

my $firstname = $Request->QueryString('firstname')->item;In addition to the Form and QueryString collections, the Request object also has a ServerVariables collection, containing information about the server and client environment. The ServerVariables collection is comparable to accessing %ENV in CGI.

You can access individual elements in the Server Variables collection by specifying the exact variable name when accessing the collection:

my $val = $Request->ServerVariables('PATH_TRANSLATED')->item;Or you can iterate through the entire collection. To do this, you can use the Win32::OLE::Enum Perl module to help you with your efforts. The Enum class is one of the many modules installed with ActivePerl, and provides an enumerator created specifically to iterate through COM collections such as ServerVariables.

Listing 6 shows an ASP page that uses the Enum class to pull the elements of the ServerVariables collection into a Perl list. You can then use the Perl foreach statement to iterate through each ServerVariables element, printing out the element name and its associated value.

If an HTML form contains a File input element—used to upload a file with the form—you can use the Request BinaryRead method to process the form’s contents. The TotalBytes property provides information about the total number of bytes being uploaded.

Break Out with COM

All of the examples up to this point have used objects that are built in to the ASP environment. You can also create COM-based components within your ASP pages using the built-in Server object. The Server object has one property, ScriptTimeout, which can be used to determine how long a script will process—a handy property if you want to make sure scripting processes don’t take more than a certain length of time.

The Server object also has a couple of methods that can be used to provide encoding, such as HTML encoding, where all HTML-relevant characters (like the angle bracket) get converted to their display equivalents. MapPath maps server paths relative to their machine locations. URLEncode maps URL-specific characters into values that are interpreted literally rather than procedurally:my $strng = $Server->URLEncode("Hello World");The result of this method call is a string that looks like:

Hello+World%21Although these methods and the one property are handy, Server is known generally as the object used to instantiate external ASP components, through the use of the CreateObject method. This method takes as its parameter a valid PROGID for the ASP component. A PROGID is a way of identifying a specific COM object, using a combination of object.component (sometimes with an associated version number):

simpleobj.smplcmpntAs an example, I created a new Visual Basic ActiveX DLL, named the project simpleobj, and the associated class smplcmpnt. The component has one method, simpleTest, which takes two parameters and creates a return value from them, based on the data type of the second parameter. This component method, shown in Example 1, has a first parameter defined as a Visual Basic Long value (equivalent to a Perl integer), and a second parameter of type Variant, which means the parameter could be of any valid COM data type—Visual Basic functions are used to determine the data type of the value.

A new page uses the Server CreateObject method to create an instance of this ASP component, and tests are made of the component method. As shown in Listing 7, the first test passes two integers to the external VB component method. The component tests the second parameter as a Long value, adds the two parameters, and returns the sum.

The next test passes a string as the second parameter. The component tests this value, finds it is not a number, and concatenates the value onto the returned string.

The script for the final test creates a date variable using the Win32::OLE::Variant Perl module, included with ActivePerl. The standard localtime Perl method is used to create the actual date value, but if this value isn’t “wrapped” using the Variant module, the Visual Basic ASP component will receive the variable as a string parameter rather than as an actual date—PerlScript dates are treated as strings by ASP components.When the Visual Basic component receives the date as the second parameter, the component finds that it is not a number, and concatenates the value onto the string returned from the function. When displayed, the returned string looks similar to the following:

3/15/1905 100I could have passed the date value directly instead of using Variant, but as I mentioned, the COM-based VB component sees the Perl date as a string rather than as a true date type. The Variant Perl module provides techniques to ensure that the data types we create in PerlScript are processed in specific ways in ASP components.


Perl is a mature language that has been used for many years for Web development. As such, there is both expertise with, and a preference for, using this language for future development with the newer Web development techniques such as ASP.

ActivePerl and PerlScript are the key tools for using Perl within the ASP environment. Perl can be used for ASP scripting through PerlScript, but the Perl developer also has full access to the objects necessary to work within the ASP environment: namely the ASP built-in objects such as the Response and Request objects.

Additional modules to assist Perl developers—such as Win32::OLE::Enum and Win32::OLE::Variant—are included with the ActivePerl installation, and help make PerlScript as fully functional within the ASP scripting environment as VBScript.

Best of all, with ActivePerl and PerlScript you can develop within an ASP environment and still have access to all that made Perl popular in the first place: pattern matching and regular expressions, the Perl built-in functions, and a vast library of free or low-cost Perl modules to use in your code. Interest in ASP is growing, and with PerlScript you can work with this newer Web technology and still program in your favorite programming language.