Loading ...
Sorry, an error occurred while loading the content.

RE: [PBML] my what?

Expand Messages
  • Shawn Caldwell
    All that line is doing is declaring the variable $row You can declare a variable 2 ways: $row; or my $row; Either way works and it is just according to
    Message 1 of 7 , May 4, 2001
    • 0 Attachment
      All that line is doing is declaring the variable $row

      You can declare a variable 2 ways:

      $row;

      or

      my $row;

      Either way works and it is just according to programmers preference.

      -----Original Message-----
      From: john_20_28_2000@... [mailto:john_20_28_2000@...]
      Sent: Friday, May 04, 2001 1:58 PM
      To: perl-beginner@yahoogroups.com
      Subject: [PBML] my what?


      I have looking at different code, like in DBI. What does it mean in
      perl for a variable to have:

      my $row;

      or something like it? What is the "my" for?




      Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
    • J.E. Cripps
      ... It limits the lifespan and effects of $row to the block or package where it is declared. (The my does the declaring, which is not necessary in Perl.)
      Message 2 of 7 , May 6, 2001
      • 0 Attachment
        > I have looking at different code, like in DBI. What does it mean in
        > perl for a variable to have:

        > my $row;
        > or something like it? What is the "my" for?

        It limits the lifespan and effects of $row to the block or package
        where it is declared. (The "my" does the declaring, which is not necessary
        in Perl.) This is especially important, and a practical requirement for
        writing larger programs, to prevent unwanted interactions. That's why you
        see it in modules.

        **** Perl has two types of variable, global (also known as package) and
        private (also known as lexical). Perl gives you global variables when
        you don't use "my". They can be accessed anywhere in the program.
        This means that any subroutine can change the value of a global variable, and
        the change might well not be easy to detect.

        $a = 10;
        sub $some_sub {
        $a = 30;
        $c = $a/2;
        }

        $b = some_sub();
        #some_sub has changed $a to 30, as well as setting $b to 15

        One of the tenets of good programming design is that subroutines should
        be constructed on a "need to know" basis, and not have access to any more
        data elements that it needs to do its own job. One way of
        restricting the effect of a variable to a certain area of code is to use
        lexical variables, via the "my" operator.

        This limits the scope of variables, the section of code
        within which one can use, set, etc. the variable. Variables declared with
        "my" exist from the point of declaration to the end of the enclosing
        block, closing bracket, subroutine, or file. (The name "lexical" comes
        from this restriction to a well-defined chunk of text.) Rewriting the
        sniplet above:

        $a = 10;
        sub some_sub {
        my $a = 30;
        #a new lexical $a has been created; the earlier $a is now inaccessible
        my $c = $a/2;
        } #exiting the some_sub block the private $a now longer exists

        $b = some_sub();

        #the $a outside of some_sub is still set to 10
        # the $a inside some_sub has now gone out of scope, and no longer exists


        **** Imagine that each block has a page where it keeps a list of its
        current lexical variables. If Perl doesn't find the variable within that
        block it looks to the surrounding blocks until (and if) it finds it.
        Each variable name in the list is independent of all the other names in
        the lists other blocks maintain.

        **** N.B. Perl's private / lexically-scoped variables are called
        "local" in other languages. "local" in Perl is another kind of scoping
        operator, but has in practice a more limited range of use. One rule that
        is for beginners to remember is until one really understands the
        difference:

        "Don't use local. Use my."
        --Mark-Jason Dominus.

        **** Declaring variable with "my" is one way of complying with the
        requirements of the "use strict" pragma. The compiler will detect
        undeclared variables, and won't let the program run.

        **** An example with scoped variables inside loops, not subroutines:

        #!/usr/bin/perl -w
        use strict;
        # will have to declare all variables within this script

        my $num = 5;
        # need that "my" with "use strict"
        my @array = qw(1 2 3 4 5);

        print "package scope \$num is $num and \@array values are @array\n\n";
        print "multiplying each \$array[\$k] by the outer-scope \$num set to 5\n";

        foreach my $k(0..4) {
        my $j = $array[$k] * $num;
        #multiplying each element in @array by the outer $num, 5
        print "$j ";
        }
        print "\n\n";

        print "the multiplier will be \$num private to the loop, set to 10\n";
        print "multiplying each \$array[\$i] by the private \$num\n";

        foreach my $i(0..4) {
        my $num = 10;
        #using the lexical $num; the outer $num is no longer available

        my $j = $array[$i] * $num;
        #this is a new $j, the old one has already vanished

        print "$j ";
        }
        print "\n\n";

        print "back in main, the value of \$num is still $num\n";



        Sources: Simon Cozens _Beginning Perl_, Jim Gearing _C for COBOL
        Programmers_, the Llama, the Camel...etc.
      • Andrew Johnson
        Without wanting to sound pedantic, you mention package in a couple of places where it could easily cause confusion: ... Lexical variables are not scoped by
        Message 3 of 7 , May 7, 2001
        • 0 Attachment
          Without wanting to sound pedantic, you mention 'package' in a couple
          of places where it could easily cause confusion:

          Here you say:
          > It limits the lifespan and effects of $row to the block or package
          > where it is declared.

          And your example here:
          > #!/usr/bin/perl -w
          > use strict;
          > # will have to declare all variables within this script
          >
          > my $num = 5;
          > # need that "my" with "use strict"
          > my @array = qw(1 2 3 4 5);
          >
          > print "package scope \$num is $num and \@array values are @array\n\n";

          Lexical variables are not scoped by package at all, and you correctly
          do not mention 'packages' when you define the scope of a lexical in
          this sentence:

          > Variables declared with "my" exist from the point of declaration to
          > the end of the enclosing block, closing bracket, subroutine, or file.

          My point is, a lexical variable exists from point of declaration to
          the end of the innermost enclosing block or the end of the file. But
          you can have multiple packages within a single file, and a
          file-scoped lexical will be in scope across package declarations
          within that file:

          #!/usr/bin/perl -w
          use strict;
          # we are in package main by default here:
          my $num = 5;
          {
          my $string = "Hello World"; # exists only in this block
          print "$num: $string\n"; # both $string and $num exist
          }

          # print "$string\n"; # this would fail: $string no longer exists

          # let's jump into package Foo:
          package Foo;
          use vars '$foo'; # can use unqualified $foo in package Foo
          $foo = 42;
          print "$foo\n"; # $foo is fine here
          print "$num\n"; # $num still in file-scope in inner package Foo

          # jump back to package main:
          package main;
          print "$num\n"; # $num still in scope
          # print "$foo\n"; # this will fail
          print "$Foo::foo\n"; # but qualifying it will work
          __END__

          This is certainly a contrived example, but it is by no means uncommon
          to create modules that contain more than one package (often one
          primary module/package and one or more helper packages). Thinking
          that a lexical defined in the first package in the file wouldn't exist
          in later packages would be incorrect (you'd want to wrap each full
          package in a block to give it any private lexicals).

          Assuming one knows what a block is, then a simple description of
          the scope of a lexical variable can be given in two parts:

          a) a lexical variable exists from declaration to the end of the
          current block.
          b) a file is implicitly a block.

          regards,
          andrew

          --
          Andrew L. Johnson http://members.home.net/andrew-johnson/
          In theory, there's no difference between
          theory and practice, but in practice there is!
        • J.E. Cripps
          ... Thanks for the correction.
          Message 4 of 7 , May 7, 2001
          • 0 Attachment
            > Without wanting to sound pedantic, you mention 'package' in a couple
            > of places where it could easily cause confusion:

            Thanks for the correction.

            > Assuming one knows what a block is, then a simple description of
            > the scope of a lexical variable can be given in two parts:
            >
            > a) a lexical variable exists from declaration to the end of the
            > current block.
            > b) a file is implicitly a block.
          • Greg Matheson
            I have a question about where the lexically scoped variable is defined. Does $num really exist in the block below in the message from Andrew Johnson? ... ^^^^^
            Message 5 of 7 , May 7, 2001
            • 0 Attachment
              I have a question about where the lexically scoped variable is
              defined. Does $num really exist in the block below in the
              message from Andrew Johnson?

              On Mon, 07 May 2001, Andrew Johnson wrote:

              > My point is, a lexical variable exists from point of declaration to
              > the end of the innermost enclosing block or the end of the
              > file.....

              > #!/usr/bin/perl -w
              > use strict;
              > # we are in package main by default here:
              > my $num = 5;
              > {
              > my $string = "Hello World"; # exists only in this block
              > print "$num: $string\n"; # both $string and $num exist
              > }
              ^^^^^

              I ask because I thought the reason I was gettign the following
              error message:

              > Use of uninitialized value at Anon.pm line 68, <PAIRS> chunk 27.

              for the following subroutine,

              > sub studentboxes {
              > my $self = shift;
              > my @mailboxes = ();
              > open (PAIRS, "groups.alt") or die "CAn't open pairs:$!\n";
              > LINE: while (my $line = <PAIRS>) {
              > next LINE if $line =~ /^$/;
              > chop $line;
              > my ($group, $first, $second, $third) = split (/ /, $line, 5);
              > push @mailboxes, ( "=" . $group . "/" . $first , "=". $group . "/" . $second , "=" . $group . "/" . $third );
              > }
              > @mailboxes = sort byid @mailboxes;
              > return @mailboxes;
              > }

              [Line 68 is: push @mailboxes, ( "=". $group . "/" etc etc ]
              was because I define my @mailboxes outside the while loop. What
              else could be undefined?

              And that's the problem. I don't want to "litter in the park", but
              I also don't want the error message. So how can I push onto my
              array within the while loop and then still have it defined at the
              end of the loop while still making it a lexically scoped
              variable?

              --
              Greg Matheson Teaching: computer programming
              Chinmin College, done by monkeys.
              Taiwan
            • Andrew Johnson
              ... Yes, it does. A lexical can be accessed anywhere in the current block, including inside of nested blocks within the current block (unless a new lexical of
              Message 6 of 7 , May 7, 2001
              • 0 Attachment
                Greg Matheson wrote:
                > I have a question about where the lexically scoped variable is
                > defined. Does $num really exist in the block below in the
                > message from Andrew Johnson?

                Yes, it does. A lexical can be accessed anywhere in the current
                block, including inside of nested blocks within the current
                block (unless a new lexical of the same name is declared within
                the nested block, masking the outer one).

                > > Use of uninitialized value at Anon.pm line 68, <PAIRS> chunk 27.
                [snip]
                > > my ($group, $first, $second, $third) = split (/ /, $line, 5);
                > > push @mailboxes, ( "=" . $group . "/" . $first , "=". $group . "/" . $second , "=" . $group . "/" . $third );

                [snip]

                > [Line 68 is: push @mailboxes, ( "=". $group . "/" etc etc ]
                > was because I define my @mailboxes outside the while loop. What
                > else could be undefined?

                You have to declare @mailboxes prior to the loop as you need it after
                the loop. I'd guess it would be your $third variable that is
                uninitialized and perhaps line 27 of your PAIRS file doesn't have the
                requisite number of fields.

                Also, a tip on your 'split / /' call -- that will split on every
                space, and if there is a leading space, or multiple spaces between
                any fields you may not get what you expect:

                my $line = ' 1 2 3 4';
                my @fields = split / /, $line;
                print join('|', @fields),"\n";

                which produces eight fields:

                |1|2||||3|4

                the 1st, 4th,5th,and 6th of which are empty strings. If your data may
                contain leading or multiple spaces, then the special case version of
                splitting on " " (a string of one space rather than a regex of one
                space) may be what you want:

                my $line = ' 1 2 3 4';
                my @fields = split " ", $line;
                print join('|', @fields),"\n";

                This prints:

                1|2|3|4

                Which is more likely what is wanted. See 'perldoc -f split' for
                further info.

                regards,
                andrew

                --
                Andrew L. Johnson http://members.home.net/andrew-johnson/
              Your message has been successfully submitted and would be delivered to recipients shortly.