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

strict or not strict?

by rsiedl (Friar)
on Aug 19, 2005 at 13:51 UTC ( [id://485130]=perlquestion: print w/replies, xml ) Need Help??

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

Hi monks,

Just have a simple question...

Can anyone tell me if there is a way of using a variable from a "non strict" routine outside of that routine without turning off strict?
Maybe the code below explains better than I do...
#!/usr/bin/perl use strict; use warnings; my %data = ( "blah"=>1, "boo"=>2, "hoo"=>3 ); # assign each key to a variable of the same name foreach (keys %data) { no strict; my $$_ = $data{$_}; } # end-foreach print $blah; exit;
returns an error
Global symbol "$blah" requires explicit package name at tmp.pl line 15.
Execution of tmp.pl aborted due to compilation errors.
Any help?

Cheers,
Reagen

Update: Just changed what $$_ is equal to...

Update: Ok, looks like people arent happy with my methods in this post, which I did rather expect. The reason that I'm trying to do this is that I'm trying to plug a hash into an old piece of code (for a once off) and I was hoping not to have to change every instance of i.e $blah to $hash{'blah'}. Just being lazy...

Replies are listed 'Best First'.
Re: strict or not strict?
by Tanalis (Curate) on Aug 19, 2005 at 14:01 UTC
    no strict 'vars';

    .. but I'm not 100% sure what you're trying to do. Typically, if you need to turn off strictness, something needs rethinking, in my experience.

      Typically, if you need to turn off strictness, something needs rethinking, in my experience.
      That, I disagree with. Whenever I turn off strictness, I do so *after* thinking. Your statement suggests that turning off strictness is something bad, and ought to be avoided at all costs. Sometimes there are alternatives for turning off strictness, but they are not always better.

      I think it's a sign of poor programming if your code bends backwards to satisfy strict, when the code could have been shorter, easier to understand and maintain and less error prone with a strategic 'no strict'.

        I think it's a sign of poor programming if your code bends backwards to satisfy strict, when the code could have been shorter, easier to understand and maintain and less error prone with a strategic 'no strict'.

        I buy that, when applied to short scripts, one-liners and throw-away code. For anything longer, or anything where a large number of people are going to be working on the code, it's nearly always easier to adhere to strict than to take the shortcuts and risk having to explain to colleagues and maintainers why you've made the decision you made.

        In the context of the OP (which is the context in which my comment should be read), where the snippet seems to be a cut-down excerpt from something bigger, I think that turning off strictness to kludge something in is a bad idea. In this context, I stand by what I said: something needs rethinking.

        Update: What ++Transient said :)

      Thanks!
Re: strict or not strict?
by Fletch (Bishop) on Aug 19, 2005 at 14:03 UTC

    To start with my $$_ = $_; isn't even valid syntax. You're trying to declare a lexical with a dynamically generated name. Aside from the fact that the lexical would go out of scope when the block was exited (i.e. immediately in this case), it's a syntax error. A more recent perl (5.8.6) would tell you:

    Can't use global $_ in "my" at spoo line 11, near "$$_ "

    The real question is what do you think you're trying to accomplish with this. You have $data{blah} already, just use the hash you've got.

    --
    We're looking for people in ATL

      *grin*

      Interestingly, in the two versions of Perl that I have access to here, 5.004_04 and 5.6.1, this snippet

      $_ = "aa"; $$_ = "bb"; print $aa;
      outputs bb.

      Notice the lack of my, and the lack of use strict; - it only works without strictness, which I guess was the point of the OP's question about turning off strict vars.

      It's not a good thing to do, admittedly - though it would seem to be valid syntax, at least historically.

      Updates to add a few words so that the post makes a little more sense.

      Update 2: Just noticed that my $$_ appears in both the OP and in Fletch's reply. Doh. Fletch is right, of course, my $$_ = $_ isn't valid syntax.

Re: strict or not strict?
by ikegami (Patriarch) on Aug 19, 2005 at 14:08 UTC

    There's a way of doing it that doesn't cause use strict 'refs' to complain, but that doesn't change the fact that what you are doing is exactly what use strict 'refs' is meant to stop you from doing. Why are you creating variable names? Why isn't a hash good enough?

    Either use no strict 'refs' to get rid of the error or don't use symbolic refs. Using the workaround (symbol table manipulation) just hides the problem, while no strict 'refs' documents that you are using this dangerous feature.

    Oh and get rid of the my. You can't my a dereferencing.

Re: strict or not strict?
by xdg (Monsignor) on Aug 19, 2005 at 14:24 UTC

    Here's a way of doing it -- but it uses package variable (i.e. globals) and, of course, you have to fully qualify them. (Or else declare them with "our").

    #!/usr/bin/perl use strict; use warnings; my %data = ( "blah"=>1, "boo"=>2, "hoo"=>3 ); # assign each key to a package variable of the same name foreach (keys %data) { no strict 'refs'; ${"main::$_"} = $data{$_}; } # end-foreach # note, this causes a "used only once" warning as the symbolic referen +ce # above doesn't count. Irrelevant for this example. print $main::blah; exit;

    It's still unclear what this gains you. Anytime you're resorting to symbolic references or package variables, it should be a warning sign that something isn't well thought out. There are relatively few areas where it makes sense (e.g. writing modules which manipulate the symbol table of the package that uses them.)

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: strict or not strict?
by Roger (Parson) on Aug 19, 2005 at 14:20 UTC
    You could also checkout the cute little module Class::Data::Inheritable for an alternative solution...

    #!/usr/bin/perl use strict; use warnings; use base 'Class::Data::Inheritable'; my %data = ( "blah"=>1, "boo"=>2, "hoo"=>3 ); # assign each key to a variable of the same name foreach (keys %data) { # no strict; __PACKAGE__->mk_classdata($_, $data{$_}); } # end-foreach print blah(); exit;


Re: strict or not strict?
by Tanalis (Curate) on Aug 19, 2005 at 14:15 UTC
    I'm trying to plug a hash into an old piece of code (for a once off) and I was hoping not to have to change every instance of i.e $blah to $hash{'blah'}. Just being lazy...

    Replace All is your friend, surely? That or write a one-liner to replace it for you ...

      Of course 'replace all' was my first thought, but then I did think of the above method and just wanted to investigate further down this road.
      Hence my question...
      Thanks for your help.

        If the variables are declared already above your loop, then you can do it via string eval. E.g.

        #!/usr/bin/perl use strict; use warnings; my ($blah, $boo, $hoo); # DECLARED HERE my %data = ( "blah"=>1, "boo"=>2, "hoo"=>3 ); # assign each key to a variable of the same name foreach (keys %data) { eval " \$$_ = \$data{$_} "; } # end-foreach print $blah; exit;

        Replace is still probably a better long run strategy.

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: strict or not strict?
by chromatic (Archbishop) on Aug 19, 2005 at 17:21 UTC

    You can make a hash of references:

    my %hash_refs = ( foo => \$foo, bar => \$bar );

    Then look up the reference by name use it where you'd use the hash.

Log In?
Username:
Password:

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

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

    No recent polls found