Обсуждение: Perl Scope problem

Поиск
Список
Период
Сортировка

Perl Scope problem

От
Randall Perry
Дата:
I'm baffled by perl's scoping of variables. In the code below, the
$cust_data hash ref is inited outside the while loop. It's then set in the
while with the results of a PgSQL query.

In the if-else statement $cust_data can be seen in the 'if' but not in the
'else' (if I try to print a value in else, $cust_data->{'customer'}, I get
an undeclared variable error).

I understand that by using 'strict' I can't use any global variables.

Can someone explain why this happens and how to make it work right?


use strict;
$cust_data = {};

while ($condition) {
    ...

    $cust_data = get_cust_data();

    if ($condition2) {
        if (send_mail($cust_data)) {
        print $cust_data->{'customer'};
       ...

    }
    else {

        if (send_mail($cust_data)) {
        print $cust_data->{'customer'};
        ...

        }
}



--
Randy Perry
sysTame
Mac Consulting/Sales





Re: Perl Scope problem

От
Michelle Murrain
Дата:
On Wednesday 02 May 2001 11:27 pm, Randall Perry wrote:
> I'm baffled by perl's scoping of variables. In the code below, the
> $cust_data hash ref is inited outside the while loop. It's then set in the
> while with the results of a PgSQL query.
>
> In the if-else statement $cust_data can be seen in the 'if' but not in the
> 'else' (if I try to print a value in else, $cust_data->{'customer'}, I get
> an undeclared variable error).
>
> I understand that by using 'strict' I can't use any global variables.

No, my understanding is that it forces you to define variables both local and
global. I've used this statement to declare variables I need throughout a
script using strict:

use vars qw($val $var $value $conf @var_array @val_array %fields_hash);

Michelle

------------
Michelle Murrain, Ph.D.
President
Norwottuck Technology Resources
mpm@norwottuck.com
http://www.norwottuck.com

Re: Perl Scope problem

От
will trillich
Дата:
On Thu, May 03, 2001 at 08:39:18AM -0400, Michelle Murrain wrote:
> On Wednesday 02 May 2001 11:27 pm, Randall Perry wrote:
> > I'm baffled by perl's scoping of variables. In the code below, the
> > $cust_data hash ref is inited outside the while loop. It's then set in the
> > while with the results of a PgSQL query.
> >
> > In the if-else statement $cust_data can be seen in the 'if' but not in the
> > 'else' (if I try to print a value in else, $cust_data->{'customer'}, I get
> > an undeclared variable error).
> >
> > I understand that by using 'strict' I can't use any global variables.
>
> No, my understanding is that it forces you to define variables both local and
> global. I've used this statement to declare variables I need throughout a
> script using strict:
>
> use vars qw($val $var $value $conf @var_array @val_array %fields_hash);

"use vars" takes a list of package globals that you'd like
shortcuts for. instead of having to say 'my::package::name::var'
every time you can just say $var instead.

so scoping SHOULD work as you suspect:

    ##########################
    package Original::Package;

    use vars($OMNI);
    # package global var
    $Original::Package::OMNI = &something();
    # same variable here
    $OMNI .= &somethingElse();

    # lexically local to this file:
    my $FileGlobal;

    {
        my $localVar;

        {
            my $eensyVar;
            # all 4 are visible here
            print $eensyVar,$localVar,$FileGlobal,$OMNI;
        }
        # eensyVar is no longer extant
        print $localVar,$FileGlobal,$OMNI;
    }
    # only FileGlobal and OMNI exist here
    print $FileGlobal,$OMNI;

    #############################
    package Something::Else::Entirely;

    # whole 'nother package, but OMNI is till reachable
    print $Original::Package::OMNI;

none of which explains randall's quandary.

--
don't visit this page. it's bad for you. take my expert word for it.
http://www.salon.com/people/col/pagl/2001/03/21/spring/index1.html

will@serensoft.com
http://sourceforge.net/projects/newbiedoc -- we need your brain!
http://www.dontUthink.com/ -- your brain needs us!

Re: Perl Scope problem

От
"Jeff Duffy"
Дата:
On Thu, 3 May 2001 11:12:22 -0500, will trillich alluded:

> On Thu, May 03, 2001 at 08:39:18AM -0400, Michelle Murrain wrote:

>  "use vars" takes a list of package globals that you'd like
>  shortcuts for. instead of having to say 'my::package::name::var'
>  every time you can just say $var instead.

 Yes, but that (as you mention) still leaves the question of how code that
looks like:

use strict;
$cust_data = {};

even compiles, since he should have gotten a

 'Global symbol "$cust_data" requires explicit package name..'

compile-time error.

 As noted, the the vars pragma is one way around the issue. If you're using
perl 5.6.0 or higher, you can also use the 'our' declaration, which creates a
lexically (not package) scoped global variable, which is very useful for
creating globals you don't want to keep around for the length of the program.

Jeff

Perl Scope problem

От
Dan Lyke
Дата:
Randall Perry writes:
> I'm baffled by perl's scoping of variables.

You don't give exact error messages, but my guess is that this isn't a
scoping error, you're failing in get_cust_data(), so $cust_data is
undef and not a HASH ref. Imagine this rewritten as:

 > $cust_data = {};
 >
 > while ($condition) {
 >     ...
 >
 >     $cust_data = undef;
 >     print $cust_data->{'customer'};

Everyone else is right that all valid Perl programs start out:

   #!/usr/bin/perl -Tw
   use strict;

Dan

Re: [MacPerl] Perl Scope problem

От
Bart Lateur
Дата:
On Wed, 02 May 2001 23:27:28 -0400, Randall Perry wrote:

>I'm baffled by perl's scoping of variables. In the code below, the
>$cust_data hash ref is inited outside the while loop. It's then set in the
>while with the results of a PgSQL query.
>
>In the if-else statement $cust_data can be seen in the 'if' but not in the
>'else' (if I try to print a value in else, $cust_data->{'customer'}, I get
>an undeclared variable error).

No sir. You're wrong. And scoping has nothing to do with it. For this
source file, it is just as if it was a global variable.

>use strict;
>$cust_data = {};

This is an initial setting. Where's the "my"? Or else, do

    use vars '$cust_data';

>while ($condition) {
>    ...
>
>    $cust_data = get_cust_data();

Here's you're throwing away the previous value of $cust_data, and
overwriting it with the return value of get_cust_data(). This just might
return undef, for all I care.

>    if ($condition2) {
>        if (send_mail($cust_data)) {
>        print $cust_data->{'customer'};

This works, so $cust_data has been set properly.

>       ...
>    }
>    else {
>        if (send_mail($cust_data)) {
>        print $cust_data->{'customer'};

This doesn't. Is there some correlation between the return value of
get_custom_data() and the value of $condition2? There must be. My guess
is that get_custom_data() returned undef.

>        ...
>        }
>}


Now, in order to make scoping really confusing:

    if(my $cust_data = get_cust_data()) {
         # do something with it
    } else {
         ...
    }

Now, in the "else" part, the lexical variable $cust_data can still be
seen! So its scope is not limited to the "if" block, but it includes the
"else" block, and any "elsif" blocks in between.

--
    Bart.

Re: [MacPerl] Perl Scope problem

От
hciR nellA
Дата:
think this will work ...

use strict;
my ($cust_data) = {};
my ($condition, $condition2);

while ($condition) {
     #...

     $cust_data = get_cust_data();

     if ($condition2) {
         if (send_mail($cust_data)) {
         print $cust_data->{'customer'};
        # ...
        }

     }
     else {

         if (send_mail($cust_data)) {
         print $cust_data->{'customer'};
             #...

             }
         }
}

> use strict;
> $cust_data = {};
>
> while ($condition) {
>     ...
>
>     $cust_data = get_cust_data();
>
>     if ($condition2) {
>         if (send_mail($cust_data)) {
>         print $cust_data->{'customer'};
>        ...
>
>     }
>     else {
>
>         if (send_mail($cust_data)) {
>         print $cust_data->{'customer'};
>         ...
>
>         }
> }
- hcir
mailto:g3pb@alaska.net
Made with a Mac!