DISCLAIMER: THESE PAGES ARE STILL UNDER CONSTRUCTION. NO CODE EXAMPLE BEEN TESTED YET.

Perl - my idiosyncracies

Boolean operations - or, and, not


[Previous Page] |[Next Page] Table of Contents: small | med | large

Here's a quick one. In Perl 5 (might be 5.005, I'm not sure...), they introduced some new boolean operators, or, and, not which can be used instead of ||, &&, ! respectively. In an earlier page, I went over the example:

	if ( (($hr < 10) && ($ampm eq 'pm'))
			|| (($name1 eq 'Jennifer') && ($name2 eq 'Love')
						&& ($name3 eq 'Hewitt'))
			|| ($cashBox < 200)) {
		&admitGuest();
	}

Well, these days, I would do this instead:

	if ( (($hr < 10) and ($ampm eq 'pm'))
			or (($name1 eq 'Jennifer') and ($name2 eq 'Love')
						and ($name3 eq 'Hewitt'))
			or ($cashBox < 200)) {
		&admitGuest();
	}

Similarly, if I was trying to set a default value I might do something like this:

	if (! defined($shadingRate)) {
		$shadingRate = 0.25;
	}

but these days, I would say:

	if (not defined($shadingRate)) {
		$shadingRate = 0.25;
	}

So I think it's pretty much a no-brainer that or/and/not is more readable than ||/&&/!. However, there are a few things that you need to be careful about. The main thing is operator precedence. In an earlier page I discussed precedence issues and suggested the over-use of parenthesis () to explicitly declare precedence rather than counting on the implicit precedence inherent to Perl. This is mainly because I can never remember what the precedence tables are.

This can actually come back to bite you in weird ways. The big difference here is that or/and/not are the absolute bottom precedence, so any other operator will tend to want to bind first.

Supposing (real life example) you are editing someone's scene browser (in this case, Doug Cooper's) and you want to do something to each file satisfying a certain criterion. Suppose, for example, that you want to do something with all files that satisfy:

Now, usually, I don't like to implicitly use the $_ variable, but I was working on someone else's program, and when I do that, I try to emulate the other person's coding style (unless it excessively annoys me). For that matter, I still haven't decided whether or not I like putting the grep inside the iteration array, but that's an issue for another day. One way we could code our little test is:
	foreach my $filename (grep /\.tif$/ && (! -l), @fileList) {
		# do something with each filename
	}
So what happens if we blindly change out the && with an and?
	foreach my $filename (grep /\.tif$/ and (not -l), @fileList) {
		# do something with each filename
	}
Well, if you tried to enter that, I believe Perl would actually refuse to compile. It looks pretty mysterious, but here's what is happening: and has such low precedence that (not -l) is binding with the , so that it sees (not -l), @fileList, which evaluates to the scalar version of the second argument, @fileList will evaluate to be the number of elements in @fileList. Then the and comes into play and evaluates /\.tif$/ and scalar(@fileList), which evaluates to a scalar. grep, however, requires at least 2 arguments, but because of the bizarre precedence, we only have 1, so it won't compile.

Of course, this can all be saved with some parenthesis:

	foreach my $filename (grep (/\.tif$/ and (not -l)), @fileList) {
		# do something with each filename
	}

So in summary:


© 2001 Steve Hwan, hostname: @pacbell.net, username: svhwan
You should probably use the word "PERL" in the subject line to get my attention.
Last Modified: Wed Apr 25 22:58:50 2001