Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

scoping problems

by naturalsciences (Beadle)
on Jun 03, 2013 at 11:07 UTC ( #1036718=perlquestion: print w/replies, xml ) Need Help??
naturalsciences has asked for the wisdom of the Perl Monks concerning the following question:

Hi, the scope of variables has been a problem for me as I'm writing my casual scripts. For some reasons I have been having trouble accessing some of my variables (declared by "my")although they should be inside the block as I do see those. Maybe some of you can show me what is wrong. I guess I am having some trouble understanding what a block is that could contain a declaration. For example this script:

#!/usr/bin/perl -w use strict; use warnings; while (my $line=<>) { my @part=split(/\t/,$line); my @saba=split(/\|/,$part[2]); for(my $i=0;$i<@saba;++$i) { if ($saba[$i]!~m/unclassified/) {(if $i==$saba){print "$_\n";} else {print "$_|";} } else {if ($i==$saba){print "unclassified_$saba[$i-1]\n";} else {print "unclassified_$saba[$i-1]|";} } } }
will post errors
syntax error at ./ line 13, near "(if" Global symbol "$saba" requires explicit package name at ./ l +ine 13. syntax error at ./ line 16, near "else" Global symbol "$i" requires explicit package name at ./ line + 17. Global symbol "$saba" requires explicit package name at ./ l +ine 17. syntax error at ./ line 18, near "else" Execution of ./ aborted due to compilation errors.
I do not understand as I have declared my @saba already in encasing brackets. Should a loop inside those understand that I am trying to access the variable a "a level" up so to speak. What I want is for all those loops to have access to variable @saba (or $saba in scalar context). Right now it seems perl looks the innermost loops and checks that the saba is not declared locally within these (by not having "my" infornt them) - then demands it to be declared globally. What would be seem more normal for me would it to check one loop outside to check if it is declared in this - a sort of inheritance so to speak. I do not dare do declare it inside these innermost loops as then it would probably remain empty == not assosiated with the actual saba form outer loop. And I do not want to declare it globally - as to eventually avoid colliding variable names.

Replies are listed 'Best First'.
Re: scoping problems
by hdb (Monsignor) on Jun 03, 2013 at 11:16 UTC

    I have not all answers but

    • In line 13, it should be if( and not (if which causes the syntax error.
    • Variables $saba and @saba are not related. This is the second error message. Do you mean $saba[$i] which refers to an element of @saba?
    • The error about $i requiring explicit package might be caused by the previous errors.

      OK. Thanks for pointing out the $saba and @saba not being related. It is probably bug out of convenience - I seem to have used an array in scalar context easily getting an array length but it seems that a shorthand like this cant travel well around different loops etc.? I did put

      for(my $i=0;$i<@saba;++$i) {my $sabasize=scalar(@saba);

      on the top of the for loop and it seems to be almost getting somewhere from there. :D so it seems to be that you led me to a better path here.

        Further to hdb's reply:

        ... it seems that a shorthand like [evaluating an array in scalar context] cant travel well around different loops etc.?

        It travels perfectly well. hdb and others have already pointed out that  @saba and  $saba are quite different things and are in no way inherently related.

        What may be confusing you is the fact that an element of the  @array array is accessed by the syntax  $array[n] (note the  $ sigil). The logic of this, determined by Larry at the Dawn of Time (Perl version 1.0), is that the elements of arrays (and also of hashes – associative arrays) are always and only scalars. But you always have to distinguish between an array, which contains (like a hash) a certain number of elements and thus has, among other properties, a size, and an element of an array.

        If you use @saba, not $saba, in scalar context, you get the arraysize indeed. This is why your $i<@saba works.

      Sorry 'bout a ninja updater I spotted and replaced if ($saba[$i]!~m/unclassified/) myself. (there was $_ instead of $saba$i ) Thanks for the other bugs - I look at these and we'll see if the scoping problem persist and what do to with it in this case. For $saba I tried to use @saba in scalar context to get nr. of elements - probably shoudl write it out somewhere - like $newscalar=$saba etc?
Re: scoping problems
by moritz (Cardinal) on Jun 03, 2013 at 12:08 UTC

    If you have syntax errors and errors about undeclared variables, fix the syntax errors first. Sometimes the errors about undeclared variables are caused by mis-parses which again come from the syntax errors, so they go away once you fix the syntax errors. (Sometimes, not always).

      Heh...   I’ve consistently found, with all such languages, that if there is even one “syntax error,” everything else is totally-bogus until that error is fixed.   Each syntax-error represents a point where the parser/lexer landed completely and unceremoniously on its (ice-skating) ass, then struggled valiantly to get back on its feet and to continue with the program ... knowing, alas, that it would never win the medal. (At this point, the only objective is to see how many additional times the skater might trip up.)   Until the source-code parses clean, no other messages the compiler/interpreter may generate are worth anything at all.   (At that point, it’s just trying to smile and keep up appearances.)

      Thanks, that seems to be a good rule to remember

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1036718]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (8)
As of 2018-06-19 09:46 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (113 votes). Check out past polls.