http://qs321.pair.com?node_id=240063


in reply to Flag variables

Interesting question, I've never given it much consideration and I'm guilty of using somthing like it. Consider a snippet I wrote recently: Ordering hash replacements to avoid clobbering things (update chaining). At one point I check whether two arrays are equal.

In other words, @one = qw/a b c/; @two = qw/a b c/; die if @one == @two; (where == in this instance is a deep equality: each element is compared in turn (and thus will die with these inputs)). As soon as two elements differ, I know the arrays can't be the same, so I can bail out early.

The code looks like:

my $is_loop = 1; for( my $n = 0; $n < scalar @loop_keys; ++$n ) { if( $loop_keys[$n] ne $loop_vals[$n] ) { $is_loop = 0; last; } } die if $is_loop;

I suppose there's a more compact way if saying that, but I pondered the question for about 1.38 seconds before banging out the above code. I assume perl 6's hyper operator is going to be of great help to me in this respect.

Note that I'm actually doing the opposite: seeing whether the flag still has the same value, not whether it has changed.

I often resort to this type of algorithm. It's like setting up a hypothesis at the beginning of the loop and seeing whether it can be disproved. The flag variables always seem to be named $found or $is_foo. In this particular case, it's easy to see whether the two are different. As soon as one pair fails to line up, you know they can't be equal, hence you can leave early (in the particular domain this code comes from it's usually the first iteration).

update: a few wordos and typos fixed

Another update: As IlyaM points out, there are better ways of doing the above example. That's the problem with contrived examples. But the idea still stands that you start in a certain condition, do a whole lot of stuff and then see if you remained in the initial condition.

You might move out of the condition quickly, or not at all. It's more the idea of short-circuiting a possibly lengthy examination... in the worst case you will have to examine every single element anyway, but if you can bail out early, so much the better.


print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'