TOPIC: CROSS-PLATFORM SOFTWARE
Escaping brackets in SAS macro language
14th November 2007Rendering opening and closing brackets as pieces in SAS macro language programming caused me a bit of grief until I got it sorted a few months back. All the usual suspects for macro quoting (or escaping in other computer languages) let me down: even the likes of %SUPERQ
or %NRBQUOTE
didn't do the trick. The honours were left to %NRQUOTE(%()
, which performed what was required very respectably indeed. The second %
escapes the bracket for %NRQUOTE
to do the rest.
The case of a wide open restriction
7th November 2007The addition of IMAP capability to Gmail attracted a lot of attention in the blogosphere last week, and I managed to flick the switch for the beast courtesy of the various instructions that were out there. However, when I pottered back to the settings, the IMAP settings had disappeared.
A brief look at the Official Gmail Blog confirmed why: the feature wasn't to be available to those who hadn't set their language as US English. My setting of UK English explained why I wasn't seeing it again, a strange observation given that they are merely variants of the same language; I have no idea why I saw it the first time around.
My initial impression was that the language setting used was an operating system or browser one, but this is not how it is. In fact, it is the language that you set for Gmail itself in its settings; choosing US English was sufficient to make the IMAP settings reappear, while choosing UK English made them disappear again.
Personally, I am not certain why the distinction was made in the first place, but I have Evolution merrily working away with Gmail's IMAP interface without a bother. To get it going, I needed that imap.gmail.com needed an SSL connection while smtp.gmail.com needed a TLS one. After that, I was away and no port numbers needed to be supplied, unlike Outlook.
Setting up a test web server on Ubuntu
1st November 2007Installing all the bits and pieces is painless enough so long as you know what's what; Synaptic does make it thus. Interestingly, Ubuntu's default installation is a lightweight affair with the addition of any additional components involving downloading the packages from the web. The whole process is all very well integrated and doesn't make you sweat every time you need to install additional software. In fact, it resolves any dependencies for you so that those packages can be put in place too; it lists them, you select them and Synaptic does the rest.
Returning to the job in hand, my shopping list included Apache, Perl, PHP and MySQL, the usual suspects in other words. Perl was already there, as it is on many UNIX systems, so installing the appropriate Apache module was all that was needed. PHP needed the base installation as well as the additional Apache module. MySQL needed the full treatment too, though its being split up into different pieces confounded things a little for my tired mind. Then, there were the MySQL modules for PHP to be set in place too.
The addition of Apache preceded all of these, but I have left it until now to describe its configuration, something that took longer than for the others; the installation itself was as easy as it was for the others. However, what surprised me were the differences in its configuration set up when compared with Windows. There are times when we get the same software but on different operating systems, which means that configuration files get set up differently. The first difference is that the main configuration file is called apache2.conf
on Ubuntu rather than httpd.conf
as on Windows. Like its Windows counterpart, Ubuntu's Apache does use subsidiary configuration files. However, there is an additional layer of configurability added courtesy of a standard feature of UNIX operating systems: symbolic links. Rather than having a single folder with the all configuration files stored therein, there are two pairs of folders, one pair for module configuration and another for site settings: mods-available/mods-enabled and sites-available/sites-enabled, respectively. In each pair, there is a folder with all the files and another containing symbolic links. It is the presence of a symbolic link for a given configuration file in the latter that activates it. I learned all this when trying to get mod_rewrite going and changing the web server folder from the default to somewhere less susceptible to wrecking during a re-installation or, heaven forbid, a destructive system crash. It's unusual, but it does work, even if it takes that little bit longer to get things sorted out when you first meet up with it.
Apart from the Apache set up and finding the right things to install, getting a test web server up and running was a fairly uneventful process. All's working well now, and I'll be taking things forward from here; making website Perl scripts compatible with their new world will be one of the next things that need to be done.
Numeric for loops in Korn shell scripting: from ksh88 to ksh93
18th October 2007The time-honoured syntax for a for
loop in a UNIX script is what you see below, and that is what works with the default shell in Sun's Solaris UNIX operating system, ksh88.
for i in 1 2 3 4 5 6 7 8 9 10
do
if [[ -d dir$i ]]
then
:
else
mkdir dir$i
fi
done
However, there is a much nicer syntax supported since the advent of ksh93. It follows C language conventions found in all sorts of places like Java, Perl, PHP and so on. Here is an example:
for (( i=1; i<11; i++ ))
do
if [[ -d dir$i ]]
then
:
else
mkdir dir$i
fi
done
New FileZilla
14th October 2007First, I must admit that the release of FileZilla 3 passed me by until recently. From the user interface point of view, the changes don't look too radical, but it is now cross-platform, a bonus for Linux and Mac users. It can also co-exist with FileZilla 2 for those Windows users needing features from that offering that aren't yet available in FileZilla 3. That does pose the question: why upgrade when that which you have works just as well? It is just as well that transferring settings is as easy as importing the FileZilla 2 settings into its successor is as easy as importing an XML file: in version 3, go to Edit > Import... on the menus and pick up the FileZilla.xml file from the installation directory for version 2. Though you might get some warnings and I certainly did, the FTP sites that I had set up already came over intact.
Running SQL scripts with MySQL
23rd September 2007Here's another of those little things that you forget if you aren't using them every day: running MySQL scripts using the Windows command line. Yes, you can also run SQL commands interactively, but there's a certain convenience about scripts. I am putting an example here so that it can be found again easily:
mysql -u username -p databasename < script.sql
Though I wouldn't be at all surprised if the same line worked under Linux and UNIX, I haven't needed to give it a try.
WordPress database error: [Can’t create table … (errno: 121)]
22nd September 2007When I was trying to upgrade one of my test blogs to WordPress 2.3 RC1, I got error messages like the above littering the screen during the installation. The PHP functions mysql_noerr
(or mysqli_noerr
) and mysql_error
(or mysqli_error
) seem to have been busily at work. These messages told me that the upgrade hadn't worked, so I went off googling as usual and perusing the MySQL tomes in my possession. Not for the first time, the web yielded nothing but dross and, in the end, I tried deleting the relevant database and starting from scratch again. That resolved the problem.
The reason for database deletion sorting things out is that MySQL got confused when there was a mismatch between what was in the file system and what its InnoDB table was saying. Now, I think that the cause of this was that I naively copied in tables using Windows Explorer. Deleting the database cleared the air and all was well once I allowed WordPress to do the needful in its time-honoured way. With another lesson learned for the future, I wish that frustration wasn't part of the learning experience too...
WARNING: The quoted string currently being processed has become more than 262 characters long…
20th June 2007This 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
15th June 2007A 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
11th June 2007Ever 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.