http://qs1969.pair.com?node_id=11128531


in reply to Closure Over Scalar?

You have received really good answers already (points all round) so if you don't mind I'll just don my consulting hat for a moment and provide a different viewpoint.

You have a scalar variable $FIXED_STRING to which you assign a literal string once and never change it. Bonus points to you for choosing an appropriate name for your scalar! However, if this is a real indicator of your situation why not side-step the problem entirely by using a constant instead? In that case your block becomes:

{ use constant FIXED_STRING => 'fixed_string'; my %persistent; sub do_something { my $x = $_[0]; $persistent{$x}{FIXED_STRING} = rand; END { for my $k (keys %persistent) { print "$k: $persistent{$k}{FIXED_STRING}\n"; } } } }

and you do not need to worry about compile-time vs run-time or returning subs or any of that. This might be considered a work-around and that's just fine - sometimes a work-around is precisely what is required.

Update: Haarg has spotted the flaw here and supplied a fix in his reply (++).


🦛

Replies are listed 'Best First'.
Re^2: Closure Over Scalar?
by Haarg (Curate) on Feb 19, 2021 at 08:16 UTC
    This doesn't work as you intended. The bareword FIXED_STRING in a hash access will be used as the string 'FIXED_STRING' , not as an expression that would evaluate the constant. To use the constant, you need to prevent it from being treated as a bareword. $persistent{$x}{+FIXED_STRING} is one possibility.
      Yes. The reason I don't like string literals as hash keys, is it's too easy in some contexts to create data on one hash key, look for it with another key, and decide that nothing interesting happened. I'd much prefer the interpreter tell me "no such variable" -- I'd rather have the explicit message, rather than a quiet failure.

      And missing out the + to avoid string interpolation of the bareword is something I'm likely to do.

      In production code, I try never to have string literals, except where they are assigned to variables or constants. And since, in Perl, constants are a bit funny, I use scalars as being less likely to be accidentally overwritten.

      I liked the idea of restricted keys, such as in Hash::Util, though I can still mistype string literals when accessing hashes, so "constant" scalars are still valuable to me.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

Re^2: Closure Over Scalar?
by stevieb (Canon) on Feb 18, 2021 at 17:56 UTC

    I do like the constant way of doing things (++) the best in this case. Primarily because this is a hard-coded variable that doesn't appear that it'll change.

    Also, constants are usually declared/defined at the top of a file, so if a change is needed, they're not hard to find within the code.