PGTS PGTS Pty. Ltd.   ACN: 007 008 568

point Site Navigation

point Other Blog Threads



  Valid HTML 4.01 Transitional

   Stop The Internet Filter!

   No Clean Feed

   The Internet Filter Is An Ex-parrot!






PGTS High and Mighty Blog

Thread: Perl Programming

Author Image Gerry Patterson. The world's most humble blogger
Edited and endorsed by PGTS, Home of the world's most 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.