Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re^2: Is use strict always appropriate?

by Je55eah (Novice)
on Jun 19, 2012 at 04:26 UTC ( #976954=note: print w/ replies, xml ) Need Help??


in reply to Re: Is use strict always appropriate?
in thread Please help me print this hash.

Thanks,

Somehow I missed that option. I suppose that for my purposes I should just write our a lot. I am working with a long list a variables and I would like to see the value next to the variable name.

I see that you are pushing for my but I am not convinced that is the best choice based on what I have been reading. It is easy enough to swap back and forth, so I suppose it doesn't matter much..... ( I went and made this to satisfy my curiosity at this point: )

# Begin use strict; our ( $var1 ) = ( 1 ); my ( $var2 ) = ( 2 ); our $ourcode = 'In ourcode eval:\n\$var1 = ${var1}\n\$var2 = ${var2}\n +'; my $mycode = 'In mycode eval:\n\$var1 = ${var1}\n\$var2 = ${var2}\n'; print eval('"' . $ourcode . '"'); print eval('"' . $mycode . '"'); print "In the main:\n\$var1 = ${var1}\n\$var2 = ${var2}\n"; # End

I thought that the eval might have tripped up with variables scoped to my, but everything worked out fine with the above test. I can't think of too many reasons that another script might call on variables within this script, so I may go with my after all.


Comment on Re^2: Is use strict always appropriate?
Download Code
Re^3: Is use strict always appropriate?
by Anonymous Monk on Jun 19, 2012 at 10:42 UTC

    I see that you are pushing for my but I am not convinced that is the best choice based ...  eval('"' . $ourcode . '"'); ...

    For the moment you can just take my our word for it :) I know it sounds like an appeal to authority, but its the benefit of experience speaking

    I can't think of too many reasons that another script might call on variables within this script, so I may go with my after all.

    Well, you really should be writing modules instead of scripts, see Simple Module Tutorial and Program Repair Shop ( Declarations and File-Scope "my" Variables )

Re^3: Is use strict always appropriate?
by Jenda (Abbot) on Jun 19, 2012 at 15:46 UTC
    sub one { my $x = "we are in one()\n"; print $x; two(); print $x; } sub two { my $x = "we are in two()\n"; print $x; } one();
    versus
    sub one { our $x = "we are in one()\n"; print $x; two(); print $x; } sub two { our $x = "we are in two()\n"; print $x; } one();

    Don't use our() until you learn what does it really mean.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

      There may not be any good way to say this, but I'll take a stab at it.

      When using my within a subroutine, it seems that the subroutine cannot share modified variable values with other subroutines unless the other subroutine is defined within the sub containing the my scoped valiable. Likewise, the my scoped value is not shared with the parent block unless the sub returns the value to the containing scope so that the desired modifications can be made. local is similar, but while the block where a local variable is defined or redefined is being parsed any subs that it triggers get to use the local value. If it were my variable then the subs would have whatever value they inherit from their own parent scope. If the variable is defined in the same block as the subroutines then my and local are effectively the same because the local scope is active as long as the subs are being defined and the subs inherit from my scope.

        A couple of points.

        "unless the other subroutine is defined within the sub containing the my scoped valiable" - don't define named subroutines within named subroutines! Ever!

        sub outer { ... sub inner { } ... }

        This is never a good idea. First, the inner() subroutine will not be local to the outer() one, it will still be globally accessible. Second, if you use a lexical variable (variable declared with my) defined in outer() within inner() you will get the "Variable will not stay shared" warning and strange things will happed in runtime. The thing is that each invocation of the outer() creates a new instance of the lexical variable, but the inner() may be called directly or recursively or ... so there is no good way to tie the $x in inner() to a specific instance in outer().

        If you want a subroutine to change a lexical declared in another, pass a reference or make use the fact that $_[...] is an alias to the parameter. If you want to have a shared state for two subroutines, use this:

        { my $hidden_data; sub one { ... access the $hidden_data; ... } sub two { ... access the $hidden_data; ... } }

        It's legal though to use a lexical variable in an unnamed subroutine defined within a subroutine like this:

        sub outer { my $lexical = ...; ... my $inner = sub { ...; access $lexical; ... }; ... $inner->(...); #or even return $inner; }

        In this case the $inner subroutine is lexical and defined in the same or smaller scope as the $lexical so there is no confusion regarding which instance of $lexical should it be accessing. And if you return or store the $inner, the value of $lexical will be preserved and will not be garbage collected until all references to the unnamed subroutine are cleared.

        local is in no way similar. First and foremost, local doesn't declare a new variable. It takes a "slot" (it may be global variable or array or hash element, but not a lexical variable), stacks its value away and undefines the slot. Then when the execution leaves the enclosing block, the old value is reassigned to the slot.

        Apart from other things this means that

        my $hash{key} = ...; # is illegal local $hash{$key} = ...; # is legal #on the other hand my $x = 1; { my $x = 2; # is legal, a new variable was created, outer $x is not v +isible } #while my $x = 1; { local $x = 2; # is illegal. Can't localize a lexical variable

        "If the variable is defined in the same block as the subroutines then my and local are effectively the same" - INCORRECT! Try this:

        our $variable = 15; { local $variable = 33; sub one { print "in one(): \$variable = $variable\n"; } sub two { print "in two(): \$variable = $variable\n"; } } one(); two(); $variable = 99; one(); two();
        versus
        our $variable = 15; { my $variable = 33; sub one { print "in one(): \$variable = $variable\n"; } sub two { print "in two(): \$variable = $variable\n"; } } one(); two(); $variable = 99; one(); two();

        In the first example the $variable (the only $variable in the whole script! A global variable!) is only ever set to 33 while defining the two subroutines, but not when you call them.

        In the second there are two variables called $variable. A global one assigned on line 1 and 16 and a lexical one declared at line 4 and accessed at lines 6 and 9. The lexical variable is visible only within the enclosing block but stays alive for the whole runtime of the script, the RUNTIME effects of local only lasted for a tiny moment before any of the subroutines were called.

        Read also Coping with Scoping

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://976954]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (12)
As of 2014-07-28 17:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (204 votes), past polls