PGTS PGTS Pty. Ltd.   ACN: 007 008 568

point Site Navigation

point Other Blog Threads



  Valid HTML 4.01 Transitional

   Download Kubuntu Today

   Ubuntu

   The Power Of KDE + Ubuntu






PGTS High and Mighty Blog

Thread: Perl Programming

GP JPG
Gerry Patterson, Your Most Esteemed And Humble Blogger

Those Bold No Strict Days


Chronogical Blog Entries:



Date: Thu, 29 May 2008 00:56:48 +1000

When I first started using perl (about ten years ago), I was a bold and irreverent awk convert (i.e. converted from C). In my first trial of perl I just ploughed into programming without using the strict or warnings pragmas. I was a programmer on the edge, having thrown off the tight boots of C declarations, reveling in my awk freedom.

Of course as some of those perl programs grew, I became more enthusiastic about these two pragmas.

However one of the annoying things that I found was incrementing simple counters. In my earlier bold no strict, no warnings days I could do something like:

	if ( $foo{$bar}++ <= $#baz) {
		blah blah blah
		....
	}

And the hash element (and the variable $bar) would be defined "on the fly" and would furthermore be post-incremented every time the test was executed.

In the rather less bold, and more sensible strict environment, I would have to say:

	$foo{bar} = 0 unless ($foo{bar});
	if ( $foo{$bar}++ <= $#baz) {
		blah blah blah
		....
	}

Of course I would also need these declarations somewhere in the strict code:

	my $bar;
	my %foo;
	my @baz;

Ok, it's only an extra statement, but in a very large script I might do it hundreds of times. It gets rather tedious.

One way around this might be to say:

	if ( ($foo{$bar} = ($foo{$bar} ) ? ++$foo{$bar} : 1) < $#baz) {
		blah blah blah
		....
	}

That would get the job done with a single statement. And it might also win you a minor mention in the obfuscation dispatches. Note: this now acts like a pre-increment operator, so in order to make the code equivalent the comparison uses < rather than <=.

With the following subroutine:

	use subs qw(incr);

	sub incr {
		return (++$_[0]) if ($_[0]);
		return 1;
	}

It might be possible to use the incr() subroutine in place of a pre-increment operator. But wherever it is invoked it would have to be as follows:

	$foo = incr($foo);

Note: Because it has been declared with the subs pragma, you can omit the brackets:

	$foo = incr $foo ;

The following code, may be a bit long-winded. But in a large script, it might be useful:

use subs qw(pre_mod post_incr);

	sub pre_mod {
		my ($scalaref,$incr) = @_;
		$incr = 1 unless ($incr);
		if ($$scalaref) {
			$$scalaref += $incr;
		} else {
			$$scalaref = $incr;
		}
		return($$scalaref);
	}
	sub post_mod {
		my ($scalaref,$incr) = @_;
		my $v = ($$scalaref) ? $$scalaref : 0;
		$incr = 1 unless ($incr);
		if ($$scalaref) {
			$$scalaref += $incr;
		} else {
			$$scalaref = $incr;
		}
		return($v);
	}

This would mean that the following code could be used:

	if ( post_mod(\$foo{$bar}) <= $#baz) {
		blah blah blah
		....
	}

or

	if ( pre_mod(\$foo{$bar}) < $#baz) {
		blah blah blah
		....
	}
And if you want to post-increment by a value other than 1 you can say;
	my $foo = post_mod(\$blah,5);
	my $bar = post_mod(\$ecky,-1);

Other Blog Posts In This Thread:

Copyright     2008, Gerry Patterson. All Rights Reserved.