Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Scalar Value Not Available To Subroutine

by BrowserUk (Patriarch)
on Dec 20, 2012 at 17:23 UTC ( [id://1009764]=note: print w/replies, xml ) Need Help??


in reply to Scalar Value Not Available To Subroutine

The code below prints the uid as expected from within the foreach loop. However, it will not print it in the subroutine. Why not and how can I fix it?

The reason is that the foreach loop localises $uid; but the subroutine mail closes over the variable declared above and outside the foreach loop, which is never initialised or assigned to.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

RIP Neil Armstrong

Replies are listed 'Best First'.
Re^2: Scalar Value Not Available To Subroutine
by tobyink (Canon) on Dec 20, 2012 at 17:42 UTC

    So loop "localisation" is different to the "localisation" done by local?

    #!/usr/bin/perl use strict; our $uid; my @array = ("one","two","three"); for (my $i = 0; $i < @array; $i++) { local $uid = $array[$i]; print "uid in loop=$uid\n"; # prints each value of $uid as expected mail($uid); } sub mail { # never prints the value of $uid ? ? print "uid in sub=$uid\n"; }
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Seems so. Effectively, the loop variable has no relationship with any pre-existing variable with the same name:

      my $i; for $i ( 1..10 ){ 1; }; print $i };; Use of uninitialized value $i in print at (eval 9) line 1, <STDIN> lin +e 1.

      I believe it is a throw-over from pre-lexical Perl.

      I've often wished (and occasionally argued in favour of), that for didn't localise pre-existing, lexical loop variables.

      It makes for messy workarounds to the situation where a counting loop can exit early conditionally, and you want to know how far it counted:

      my $i; for $i ( 1 .. $N ) { last if <SOMECOND>; ... } ## Here we have no way of knowing if we took an early exit; ## thus necessitating additional, unnecessary complexity to retain or +discover that.

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      RIP Neil Armstrong

        Effectively, the loop variable has no relationship with any pre-existing variable with the same name:

        Same goes for local, fyi.

        >perl -E"say 0+\$x; local $x; say 0+\$x;" 4885852 2403948

        I've often wished (and occasionally argued in favour of), that for didn't localise pre-existing, lexical loop variables.

        It would be useful and intuitive. It would drastically change the behaviour of the following, though

        for $lex (...) { push @f, sub { ... $lex ... }; }

        As it is now, I never use a pre-existing var.

      > So loop "localisation" is different to the "localisation" done by local?

      yes and no, since (unfortunately) you can't use local with lexicals!

      But foreach tries to mimic this behaviour (a tribute to DWIM)

      As you can see localization is as predicted with package vars, but seems to rebind the var to the new pad for lexical vars.

      lanx@ubuntu:~$ perl our $i; for $i (1..9) { tst(); } sub tst { print $i; } 123456789 lanx@ubuntu:~$ perl my $i=42; for $i (1..9) { tst(); } sub tst { print $i; } 424242424242424242

      we already had similar discussions.

      Cheers Rolf

      So loop "localisation" is different to the "localisation" done by local?

      No, the difference you are seeing is because subs capture lexical vars but not package vars.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-18 01:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found