On Sunday 16 July 2006 13:20, Charles K. Clarkson wrote:
> Daniel D Jones wrote:
> : Ah!  Simple change:
>
>    Subroutines should not normally operate on external data.

What do you mean by "operate on?"  I avoid altering external data, but I don't 
see the harm in reading external data.  Too, this was test code to get the 
algorithm right.  Since @tests is a global variable, it doesn't seem to make 
sense to push it on the stack each function call.  There may be ten or 
fifteen variables and I'm testing every permutation, so the function may get 
called 10! or 15! times.  

> Pass data into and out of each subroutine. As a matter of style,
> I avoidsqashingwordsinvariableandsuborutinenamesalltogether. I
> like to use an underscore for most names.

Hmmm.

for_each($tests, $values) = @_;

Now I'm getting an error... :-)

> run_tests( [EMAIL PROTECTED], [EMAIL PROTECTED] );
>
> : sub runtests() {
>
> sub run_tests {
>
>       my( $tests , $values ) = @_;
>
> :         my $test;
> :         foreach (@tests) {
> :                 $test = $_;
>
>     foreach my $test ( @$tests ) {
>
> :                 $test =~ s/([a-z])/$values[ord($1) - ord('a')]/g;
>
>     $test =~ s/([a-z])/$values->[ord($1) - ord('a')]/g;
>
> :                 return 0 unless eval $test;
>
>     This doesn't look right. If eval fails half way through @tests
> you will have half of @tests converted and half unconverted. 

The conversion isn't important - the eval of the test after conversion is what 
matters.  The short circuiting is intentional.  If any test fails, the whole 
thing fails - that particular permutation of the array doesn't meet the 
tests.  There's no sense in testing the rest of the tests as soon as you know 
that one fails.  

> Are you sure you want to change @tests and not work on a copy?

I should be working on a copy of the data, not the original string.  That was 
exactly the bug which bit me.  In my original code, I thought that making 
$test local would create a copy, not work on the original.  That is, I 
thought these two methods were equivalent:

foreach my $test(@tests){


my $test;
foreach (@tests){
        $test = $_;

Obviously, they are not.  In the first, $test is an alias for the string in 
the original global array.  In the second, $test is a copy of the string.  
The second is what I wanted.  In my original code, the global array was 
altered, so the substitution did nothing after the first pass.  Even though 
the array values were shuffled, the substitution had already been made and so 
the new values weren't getting put into the test.  It was just testing the 
first permutation over and over again.




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to