in reply to Modifying a parameter to a recursive function

The immediate 'problem' is that the for loop variable ($_ in your case) is an alias to each element in turn of the list being iterated over. It really isn't the same $_ that is used outside the loop. The same thing happens with $_ in map and grep. If you really want to retain the last processed value in a for loop you need to copy it to another variable explicitly:

sub traverse { my $result; for my element (@_) { ... $result = 'my interesting value to be retained on the last ite +ration'; } return $result; }

You really, really, really ought to use a variable instead of the default variable for your for loop variable btw. Using the default variable for more than a couple of lines and expecting it not to change by magic is just asking for trouble!

Oh, and you should use the three parameter version of open and lexical file handles:

open my $outputFile, '>', $output or die "Failed to create $output: $! +\n";

True laziness is hard work

Replies are listed 'Best First'.
Re^2: Modifying a parameter to a recursive function
by bellaire (Hermit) on Apr 08, 2009 at 21:11 UTC
    While your points are definitely good advice, I'm not sure that's what he's asking about. I think the OP is asking about modifying the parameters to the subroutine in-place. For example:
    @a = (1..10); sub x { foreach (@_) { $_++; } } x(@a); print @a; #prints 234567891011
    So in principle, you can modify a subroutine's arguments using the default variable $_ inside a foreach loop. Question is, why isn't it working inside his recursive function?

      I don't think that is really the OP's problem. What you suggest can be checked trivially by:

      use strict; use warnings; my @array = (1 .. 8); print "Before: @array\n"; nastyModifyParamsSub (@array); print "After: @array\n"; sub nastyModifyParamsSub { for my $element (@_) { ++$element; } }

      Prints:

      Before: 1 2 3 4 5 6 7 8 After: 2 3 4 5 6 7 8 9

      Which shows that modifying the parameters is possible and that there is nothing magical about requiring $_ to do it. The following though shows one way that OP's code could be going awry:

      use strict; use warnings; my @array = (1 .. 8); print "Before: @array\n"; nastyModifyParamsSub (@array); print "After: @array\n"; sub nastyModifyParamsSub { for (@_) { ++$_; clobberDefVar (); } } sub clobberDefVar { $_ = 0; }

      Prints:

      Before: 1 2 3 4 5 6 7 8 After: 0 0 0 0 0 0 0 0

      The bottom line though to that the OP's description is an fuzzy unclear thing and there is too much code and no data at all.


      True laziness is hard work

        I'm trying to see it your way, but I don't see where you think there's an unlocalized $_.

        tag and content_list could theoretically clobber $_, but you'd figure that subsequent method calls would fail if they did.