TOPIC: CROSS-PLATFORM SOFTWARE
WARNING: The quoted string currently being processed has become more than 262 characters long…
This is a SAS error that can be seen from time to time:
WARNING: The quoted string currently being processed has become more than 262 characters long. You may have unbalanced quotation marks.
In the days before SAS version 8, this was something that needed to be immediately corrected. In these days of SAS character variables extending beyond 200 characters in length, it becomes a potential millstone around a SAS programmer's neck. If you run a piece of code like this:
data _null_;
x="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
run;
What you get back is the warning message at the heart of the matter. While the code is legitimate and works fine, the spurious error is returned because SAS hasn't found a closing quote by the required position and the 262-character limit is a hard constraint that cannot be extended. There is another way, though: the new QUOTELENMAX option in SAS9. Setting it as follows removes the messages in most situations (yes, I did find one where it didn't play ball):
options noquotelenmax;
This does, however, beg the question as to how you check for unbalanced quotes in SAS logs these days; clearly, looking for a closing quote is an outmoded approach. Thanks to code highlighting, it is far easier to pick them out before the code gets submitted. The other question that arises is why you would cause this to happen anyway, but there are occasions where you assign the value of a macro variable to a data set one and the string is longer than the limit set by SAS. Here's some example code:
data _null_;
length y $400;
y=repeat("f",400);
call symput("y",y)
run;
data _null_;
x="&y";
run;
My own weakness is where I use PROC SQL to combine strings into a macro variable, a lazy man's method of combining all distinct values for a variable into a delimited list like this:
proc sql noprint;
select distinct compress(string_var) into :vals separated by " " from dataset;
quit;
Of course, creating a long delimited string using the CATX (new to SAS9) function avoids the whole situation and there are other means, but there may be occasions, like the use of system macro variables, where it is unavoidable and NOQUOTELENMAX makes a much better impression when these arise.
Tidying dynamic URL’s
A few years back, I came across a very nice article discussing how you would make a dynamic URL more palatable to a search engine, and I made good use of its content for my online photo gallery. The premise was that URL's that look like that below are no help to search engines indexing a website. Though this is received wisdom in some quarters, it doesn't seem to have done much to stall the rise of WordPress as a blogging platform.
http://www.mywebsite.com/serversidescript.php?id=394
That said, WordPress does offer a friendlier URL display option too, which you can see in use on this blog; they look a little like the example URL that you see below, and the approach is equally valid for both Perl and PHP. Since I have been using the same approach for the Perl scripts powering my online phone gallery, now want to apply the same thinking to a gallery written in PHP:
http://www.mywebsite.com/serversidescript.pl/id/394
The way that both expressions work is that a web server will chop pieces from a URL until it reaches a physical file. For a query URL, the extra information after the question mark is retained in its QUERY_STRING variable, while extraneous directory path information is passed in the variable PATH_INFO. For both Perl and PHP, these are extracted from the entries in an array; for Perl, this array is called is $ENV and $_SERVER is the PHP equivalent. Thus, $ENV{QUERY_STRING} and $_SERVER{'QUERY_STRING'} traps what comes after the ? while $ENV{PATH_INFO} and $_SERVER{'PATH_INFO'} picks up the extra information following the file name (/id/394/ in the example). From there on, the usual rules apply regarding cleaning of any input but changing from one to another should be too arduous.
Perl vs. PHP: A Personal Experience
Ever since I converted it from a client-side JavaScript-powered affair, my online photo gallery has been written in Perl. There have been some challenges along the way, figuring out how to use hash tables has been one, but everything has worked as expected. However, I am now wondering if it is better to write things in PHP for the sake of consistency with the rest of the website. I had a go a rewriting the random photo page and, unless I have been missing something in the Perl world, things do seem more succinct with PHP. For instance, actions that formerly involved several lines of code can now be achieved in one. Reading the contents of a file into an array and stripping HTML/XML tags from a string fall into this category, and seeing the number of lines of code halving is a striking observation. I am not going to completely abandon Perl, it's a very nice language, but I do rather suspect that there is now an increased chance of my having a website whose server-side processing needs are served entirely by PHP.
Getting one’s HTTP headers in a twist
I am in the process of further linking the content of hillwalking blog into the fabric of other parts of my website. To date, this has included adding a list of all the posts to the site map and a dossier of the latest entries to the site's welcome page. One thing that started to crop up were a series of warnings of the form:
Cannot modify header information - headers already sent by...
The cause of this was my calling a PHP script that was part of my hillwalking blog installation, and this caused Bad Behaviour to be invoked. The result was that an HTTP header was being sent to create a cookie after one already had been sent to display a web page. A spot of conditional coding and the use of an extra flag resolved the problem.
Apparently, there is another surefire way of getting the same result: whitespace before or after the <?php ... ?> tag in an included script. The cookie issue is one that I can understand, but it does seem strange that an attempt is made to send HTTP header information when the latter arises. It causes loads of questions, though...
Restrictions on SAS libraries when macro catalogs are used
When you open up a SAS macro catalogue so that its entries for use by other programs, it has a major impact on the ability to change the library reference used to access the catalogue after it has apparently been unlocked.
options mstored sasmstore=bld_v001;
Using the line above will open the catalogue for reading, but there is no way to close it to change the library reference or unassign it until the SAS session is shut down. Even this line will not do the trick:
options nomstored sasmstore='';
What it means in practice is that if you have a standard macro setting up access to a number of standard macro libraries, then that setup macro needs to check for any library references used and not try to reassign them, causing errors in the process.
SQL Developer Java error
Last night, I tried starting up Oracle's SQL Developer so that I could add a listing of my hillwalking blog posts to my website's site map with a spot of PHP scripting. However, all that I got was something like that which you see below:

I must confess that this one threw me. The solution, though challenging to find (they often are, even with the abilities of Google) was to use a batch file called sqldeveloper.bat that you can find in the [installation directory]\sqldeveloper\bin directory. It does start the thing when all else seems to fail and got me up and running again. I did get that blog post listing added to the site map after all; Having more visibility of the MySQL tables was a definite plus point.
Photo gallery trouble
The recent woes at Zooomr (mustn't forget that it is spelt with three O's...), have prompted me to ponder photo galleries. My own is a self-hosted affair, with Perl doing the honours of reading and processing data stored in an XML file. It may seem an unsophisticated system, but it has worked well and, apart from the matter of server administration, I am in full control. Yes, there is a development and maintenance overhead, but I enjoy programming and scripting anyway; I just have to find the time for it. If this is not your idea of fun, then using a service like Flickr, Zooomr or Photobucket is attractive so long as things don't go awry as they have for Zooomr and all the bad publicity and user frustration can't have done Zooomr's future prospects any good at all.
Are developers and designers overcomplicating their CSS?
When I have been tweaking the widgets in this blog, the thought crossed my mind that purveyors of open source blogging and CMS's may be overcomplicating matters with the CSS that they are writing. Using inheritance without much thought as to others having to pick it up is one irritation, but bunching styles together can confuse too. For instance, you can draw from two different styles for the same HTML element (it's what's going when you see class="class1 class2" in a tag definition), which is OK if done simply but can confuse matters when customisation is attempted later. Drupal particularly suffers from this bugbear, but it's there on WordPress too, though not to the same extent. Using a hierarchy to define and attach your styles (#id1 .class2 tag1 {style definition...} is the kind of thing that I have in mind), can also confound, even if I admit to finding the approach very useful for myself. I think that I know what's driving this: the need to cut down the bulk of CSS files but using the advanced features that I mentioned above without clear commenting and other documentation hampers later efforts. It would be nice if every developer of a theme to use in blogging or CMS software was forced to document their work extensively and share that documentation with interested users. After all, sharing is the whole purpose of their endeavours...
Oracle SQL Developer and MySQL
Because of my work, I recently have had a bit of exposure to Oracle SQL Developer, which I have been using as part of application development and testing activities. For further investigation, I decided to have a copy at home for further perusal (it's a free download) and it was with some interest that I found out that it could access MySQL databases. To accomplish this, you need Connector/J for MySQL so that communication can occur between the two. Though you quickly notice the differences in feature sets between Oracle and MySQL, it seems a good tool for exploring MySQL data tables and issuing queries.

FCKeditor and Drupal
My Drupal investigation is currently in hiatus, but I did get to exploring the world of modules and adding to the standard ones supplied. Drupal doesn't have a WYSIWYG editor supplied in the standard package, so I went and added one that I have used elsewhere: FCKEditor. Setting wasn't much of a problem until I encountered the following error: Unknown element of UniversalKey panel. The solution to the problem is to remove the reference to UniversalKey from the configuration file fckeditor.config.js. Since it took a spot of finding, here it is for posterity and so that I'll find again...