Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Detect a localized variable

by Sewi (Friar)
on Nov 18, 2011 at 13:20 UTC ( [id://938813]=perlquestion: print w/replies, xml ) Need Help??

Sewi has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I got a module which handles caching of various items. Items may be changed far away from the module actually filling the cache and I want to provide a way for scripts to force cache refreshing even if the source actually getting/setting the data is another file.

My idea was a global

our $FORCE_REFRESH = 0;

in my Cache module which should be set to 1 to force all subsequent read's to fail and refresh the cache this way:

{ local $My::Cache::FORCE_REFRESH=1; &some_sub_requesting_the_data; }

I want My::Cache to complain (and refuse to force refreshing) if someone starts modifying the variable without using local.

I don't want a My::Cache::set_force_refresh() function because I'm pretty sure people will set it without resetting it as soon as possible.

Is there any way to detect if a variable is currently localized?

Thanks,
Sebastian

Replies are listed 'Best First'.
Re: Detect a localized variable
by Anonymous Monk on Nov 18, 2011 at 13:44 UTC

    I want My::Cache to complain (and refuse to force refreshing) if someone starts modifying the variable without using local.

    Um, no you don't, that sounds like horrible API design :)

    $ perl use Devel::Peek; use Scalar::Util qw' refaddr '; our $snot = 66; Dump $snot; warn refaddr \$snot; local $snot = 77; Dump $snot; warn refaddr \$snot; __END__ SV = IV(0x99acf8) at 0x99acfc REFCNT = 1 FLAGS = (IOK,pIOK) IV = 66 10071292 at - line 5. SV = IV(0x3f8c58) at 0x3f8c5c REFCNT = 1 FLAGS = (IOK,pIOK) IV = 77 4164700 at - line 8. $ perl -le " print 0x3f8c5c 4164700 $ perl -le " print 0x99acfc 10071292
      $ perl -e " our $snot = 66; push @snot, \$snot; local $snot = 77; push + @snot, \$snot; print qq[$_ $$_\n] for @snot " SCALAR(0x99aa64) 66 SCALAR(0x3f8cc4) 77
      I don't like the idea, too, but I know that not taking care about this issue will lead to big problems in the future, mainly due to high time pressure and partly due to the skill level of the people who should use it :-).
Re: Detect a localized variable
by Anonymous Monk on Nov 18, 2011 at 13:47 UTC
    Huge code smell, accessing that global state. Can't you use something sane, like a instance destructor or Scope::Guard?
Re: Detect a localized variable
by Perlbotics (Archbishop) on Nov 19, 2011 at 14:25 UTC

    Seems, you're doing some kind of lazy cache clearing? Perhaps the situation can be relieved a bit

    • by restricting access to the flag (i.e. $My::Cache::FORCE_REFRESH), and
    • by giving the user an environment that operates on a cleared cache?

    Maybe just:

    with_cache_cleared_do { some_sub_requesting_the_data; };

    Example:

    use strict; use warnings; { #--- confine flag in lexical scope my $refresh_request_flag; #--- use closures to access flag sub refresh_requested { return !! $refresh_request_flag } sub with_cache_cleared_do (&) { $refresh_request_flag = 1; my @result = shift->(); # run block $refresh_request_flag = 0; return unless defined wantarray; return wantarray ? @result : $result[0]; } } # usage: -run: with_cache_cleared_do { some block }; # -check: refresh_requested() #--- that's it - now the tests ... use Test::Simple tests => 6; ok( ! refresh_requested() , 'before: flag is cleared' ); with_cache_cleared_do { ok( refresh_requested() , 'flag set within bl +ock' ); }; ok( ! refresh_requested() , 'after: flag is cleared agai +n' ); sub nested { ok( ( $_[0] == 42 and refresh_requested() ), 'flag set within nested calls with parameters') } with_cache_cleared_do { nested( 42 ) }; my $x = with_cache_cleared_do { return 'foo'; }; ok ( $x eq 'foo' , 'result in scalar context' ); my @x = with_cache_cleared_do { return ( 'one', refresh_requested() ) +; }; ok( ( $x[0] eq 'one' and $x[1] == 1 ) , 'result in list context' );

    HTH

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://938813]
Approved by sundialsvc4
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (6)
As of 2024-03-28 23:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found