Understanding Scope with 'my'

Discussion in 'Perl Misc' started by Roger, May 17, 2004.

  1. Roger

    Roger Guest

    My code is this:

    use warnings;
    use strict;

    my $number = my_rand();
    print "The number is ".$number;
    { my $seed = 1;
    sub my_rand (){

    $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768;
    return $seed;
    }

    I derived it from an article here: (apparently wrong??)
    http://perl.plover.com/FAQs/Namespaces.html#glos_lexical_variable

    The issue is that declaring 'seed' inside the brackets as shown above yields an
    error of:
    main::my_rand() called too early to check prototype at test_scope.pl line 6.
    Use of uninitialized value in multiplication (*) at test_scope.pl line 11.

    Basically I understand local, and am working on 'my' ... it would seem as if
    using 'my' one needs to always use it in a sub in the context of returning it as
    an lvalue...
    like:
    my $number = my_rand();
    but like I said the code above does not work the way they:
    http://perl.plover.com/FAQs/Namespaces.html#glos_lexical_variable
    said it should or I am missing the big picture. BTW before I posted I read
    'Learning Perl' 3rd edition... and prehaps I *should* have 'got it' from that
    the example URL I reference above has me scratching my head...

    TIA


    --
    Use our news server 'news.foorum.com' from anywhere.
    More details at: http://nnrpinfo.go.foorum.com/
    Roger, May 17, 2004
    #1
    1. Advertising

  2. Roger

    Ben Morrow Guest

    Quoth Roger <>:
    >
    > My code is this:
    >
    > use warnings;
    > use strict;
    >
    > my $number = my_rand();
    > print "The number is ".$number;
    > { my $seed = 1;


    Why the bizzare indentation?

    > sub my_rand (){
    >
    > $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768;
    > return $seed;
    > }


    You have a missing } here.

    > I derived it from an article here: (apparently wrong??)
    > http://perl.plover.com/FAQs/Namespaces.html#glos_lexical_variable


    No, this is a good basic description of how my and local work. The
    problem is elsewhere.

    > The issue is that declaring 'seed' inside the brackets as shown above yields
    > an error of:
    > main::my_rand() called too early to check prototype at test_scope.pl line 6.
    > Use of uninitialized value in multiplication (*) at test_scope.pl line 11.


    The problem is with these:

    sub my_rand () {
    ^^

    They are called a prototype, for which see perldoc perlsub. It will
    suffice to say now that 1. they are an advanced feature of Perl and you
    don't need to use them and 2. that perl needs to know a sub's prototype
    *before* it encounters any calls to that sub (as the warning said).

    The other warning comes from the fact that the assignment $seed = 1 is
    not executed until after the call to my_rand. There are two fixes for
    this: either move the whole block up above any calls to the sub, so that
    the variable is initialised properly, or, better, make it into a BEGIN
    block that will *definitely* be run before anything else. For BEGIN
    blocks c.f. perldoc perlmod.

    So, to fix your code you want

    use warnings;
    use strict;

    # if you put
    # use subs qw/my_rand/;
    # here, you can call my_rand without parens

    my $number = my_rand();
    print "The number is $number\n";

    BEGIN {
    my $seed = 1;
    sub my_rand { # Note: no ()
    $seed = int (...);
    return $seed;
    }
    }

    Ben

    --
    Musica Dei donum optimi, trahit homines, trahit deos. |
    Musica truces molit animos, tristesque mentes erigit. |
    Musica vel ipsas arbores et horridas movet feras. |
    Ben Morrow, May 18, 2004
    #2
    1. Advertising

  3. Roger

    Roger Guest

    "The other warning comes from the fact that the assignment $seed = 1 is
    not executed until after the call to my_rand. There are two fixes for
    this: either move the whole block up above any calls to the sub, so that
    the variable is initialised properly, or, better, make it into a BEGIN
    block that will *definitely* be run before anything else."

    Yes that's right as it turns out. Just like a shell script if not for the BEGHIN
    block. Thank you for pointing this out and I might say that URL I referenced
    might be improved with this tidbit of info and the Llama book never explains
    about begin blocks, although I'm sure it mentions the way the interpreter parses
    a file... but then again the BEGIN block info is important to that.
    Thanks again.
    Roger

    --
    Use our news server 'news.foorum.com' from anywhere.
    More details at: http://nnrpinfo.go.foorum.com/
    Roger, May 18, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul Opal
    Replies:
    12
    Views:
    948
    Paul Opal
    Oct 11, 2004
  2. Pyenos
    Replies:
    9
    Views:
    291
    WaterWalk
    Dec 29, 2006
  3. Alex

    understanding list scope

    Alex, Sep 21, 2008, in forum: Python
    Replies:
    5
    Views:
    272
  4. Prabh

    Understanding 'scope'

    Prabh, Feb 15, 2004, in forum: Perl Misc
    Replies:
    7
    Views:
    123
    robic0
    Nov 29, 2005
  5. Andrew Falanga
    Replies:
    2
    Views:
    201
    Andrew Falanga
    Nov 22, 2008
Loading...

Share This Page