Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

local & global function

by dideod.yang (Sexton)
on Oct 16, 2018 at 23:53 UTC ( [id://1224131]=perlquestion: print w/replies, xml ) Need Help??

dideod.yang has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks. I want to search some function about fusion local & global. I want to use value on special loop. below is example. I want to use special value when only special condition is defined not always. Is there any fuction to meet my purpose?
my $test,$test2; print "$test\n"; ## print nothing if(not defined $test){ my $test = "GOOD"; print "$test\n"} ## print GO +OD ( I need to define $test becasue I use $test at second "if" functi +on only ) print "$test\n"; ## print nothing ( It is my purpose to print nothing +so I cann't use global function at first "if" function ) if(not defined $test2){ print "$test\n" } # I want to print GOOD. GOOD + is defined on first "if" function. but It print nothing becuase I us +e local function(my)

Replies are listed 'Best First'.
Re: local & global function
by Jenda (Abbot) on Oct 17, 2018 at 11:12 UTC

    Maybe what you are after is somewhat like this:

    use strict; { # just a block my $test; # the lexical one sub foo { print "In foo: \$test=$test\n"; $test = "Hello world"; print "In foo: \$test=$test\n"; } sub bar { print "In bar \$test=$test\n"; } } my $test; # the global one print "Global \$test=$test\n"; foo(); print "Global \$test=$test\n"; bar(); print "Global \$test=$test\n";

    The two functions are defined in a block and therefore share the lexical (please do not use the term local in Perl) variables declared within that block ABOVE the functions.

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

      > The two functions are defined in a block and therefore share the lexical

      Additional note: this is a fine example for using Closures.

      The two functions are "closing" over the lexical variable $test.

      And this $test has a lexical (i.e. static) scope restricted to the block.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      PS: it also demonstrates that closure don't need to be anonymous. There is a widespread misconception in some other languages that "closure" is a synonym for "anonymous function".

Re: local & global function
by 1nickt (Canon) on Oct 17, 2018 at 00:22 UTC

    You want the same variable to hold two different values in the same scope. That won't work.

    Unless you do something weird like use dualvar and evaluate in number or string context to force one or another value to be used.

    use strict; use warnings; no warnings 'uninitialized'; ## not recommended use Scalar::Util 'dualvar'; my ($test, $test2); print sprintf('1: %s', $test), "\n"; if (not defined $test) { $test = dualvar(0, 'OK'); print sprintf('2: %s', $test), "\n"; } print sprintf('3: %s', $test > 1 ? $test : undef), "\n"; if (not defined $test2) { print sprintf('4: %s', $test), "\n"; } __END__
    ... but really it seems like you need to rethink your program design. Can you share the big picture of what you are trying to do?

    Hope this helps!


    The way forward always starts with a minimal test.
Re: local & global function (scopes)
by LanX (Saint) on Oct 17, 2018 at 00:30 UTC
    It's not easy to understand what you want.

    use strict; use warnings; my ($test,$test2,$test3); # parens needed for my(LIST) print "$test\n"; ## print nothing if(not defined $test){ $test3 = "GOOD"; # no my, no private but upper scope print "$test3\n" } ## print GOOD print "$test\n"; ## print nothing if (not defined $test2) { print "$test3\n"; # print $test3 from upper scope } ## print GOOD. GOOD is defined on first "if" function.

    RESULT:

    Use of uninitialized value $test in concatenation (.) or string at d:/ +tmp/pm/my.pl line 8. Use of uninitialized value $test in concatenation (.) or string at d:/ +tmp/pm/my.pl line 15. GOOD GOOD
    it's generally a bad idea to print undefined values. I suppose it's a test so I left the warnings in.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: local & global function
by morgon (Priest) on Oct 17, 2018 at 00:20 UTC
    This is not about "fusion", it's about confusion.

    I have absolutely no clue about what exactly you are trying to achieve, but maybe it helps you to point out that "my"-variables are lexically scoped and that means that they are only visible within the nearest "{"-block.

    And if you stack my-declarations you simply shadow previous ones.

    Consider this:

    use strict; my $whatever = "outer"; if (1) { my $whatever = "inner"; print "$whatever\n"; } print "$whatever\n";
    Here you have a lexically-scoped variable in the outer scope and the same one in the scope introduced by if.

    Within the if-block $whatever is changed to "inner", and that is what is printed from the print there, but once you leave this scope you refer to the outer definition and so the outer print prints "outer" (what else?).

    In your case you have "my $test" in the outer scope.

    Then you introduce a new scope with "if" and declare a new variable with "my $test" and set that to "GOOD". Here you shadow the already introduced variable. Later (in another if-scope) you introduce yet another variable (again shadowing the outer one) and that of course knows nothing about the assignment you did in another scope.

    Short story:

    You are dealing with three different variables here: The outer $test, the $test in the first if and the $test in the second if.

    This probably was confusing - sorry for that but I am a bit drunk...

Re: local & global function
by BillKSmith (Monsignor) on Oct 17, 2018 at 15:04 UTC
    I think that you intend to use two scalar variables, both named '$test', which you describe as 'global' and 'local'. That is possible, but probably not a good idea. Your code would be much clearer if you used different names for the two variables. Please post a version that works as intended. If there still is a good reason to use one name, we can address that later.
    Bill

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-20 02:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found