in reply to Re: Access a global variable from a subroutine when used as "for" iterator
in thread Access a global variable from a subroutine when used as "for" iterator

While I don't think the OP really wanted a closure and knows their purpose, I wouldn't call them "smelly" if used appropriately.

With this short demo we can't really guess the overall intention.

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

  • Comment on Re^2: Access a global variable from a subroutine when used as "for" iterator

Replies are listed 'Best First'.
Re^3: Access a global variable from a subroutine when used as "for" iterator
by GrandFather (Saint) on Dec 21, 2023 at 02:17 UTC

    Closures are not generally smelly, but global variables almost always are. My impression is the OP was aiming for a global variable rather than a closure. Very likely if a closure is intended by an OP the fact is mentioned because that has a strong influence on the expected behavior of the code. No mention, no closure.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond

      It was just to simplify the maintenance of a special portion of the code at the expense of supporting functions/methods. The full story is here.

Re^3: Access a global variable from a subroutine when used as "for" iterator
by vitoco (Hermit) on Dec 21, 2023 at 00:41 UTC

    You are right... my demo was to present what I found. In the real code, the equivalent to show() function receives a parameter, but under certain conditions, I wanted it to default to the iterator.

      We really need to know more for a good advice. For instance, do you plan to export that function?

      For instance:

      Another possibility it's a second closure function to set this closure variable.

      Yet another is using a full qualified $private::package::var

      In short: TIMTOWTDI, but it depends.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

        The full story is that I'm parsing some documents in Excel spreadsheets and I just wanted to simplify the expresions, so the list c('A1'),c('A'),c('B') just means that the value at the constant cell A1 is followed by the values of columns A and B at the "current row" in the details area, without having to include the iterator variable as in c('A',1),c('A',$i),c('B',$i) (which is also supported). The problem was that I always got the values at a fixed row based on the previous value of the iterator variable when it was not explicit as an argument, either as c('A',$i) or c("A$i").

        Of course, there are also some helper functions to get formated values. For instance, d('A',1) internally calls c(@_) and returns a date properly formatted (and not an epoch number). As there could be many levels of nested functions, I decided to use a global variable and avoid the optional parameter.

        Now I know that for over lists does a special treatment on the iterator variable, probably because of a perl 4 inheritance, and I should use a C-like for or a while construct when using a global variable as iterator from subroutines called from the loops, but for the moment, I'm using this construct:

        my $row = 0; for (2..10) { $row = $_; gen(d('A1'), c('A'), c('B'), t('C'), c('D')+c('E')); }

        I think it is much more clear and easy to maintain when the spreadsheet changes than:

        my $row = 0; for ($row = 2, $row <= 10; $row++) { gen(d('A',1), c('A',$row), c('B',$row), t('C',$row), c('D',$row)+c(' +E',$row)); }

        Now I see that if I had declared the global variable without an initial value of zero, an error should have been raised and saved many hours trying to identify why I got wrong values from the spreadsheet. >:-(