Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Variable scopes?

15 views
Skip to first unread message

Otto J. Makela

unread,
Oct 25, 2022, 8:38:06 AM10/25/22
to
This is a boiled-down version of a bit of sofware where I discovered I
apparently don't fully understand variable scopes. In the following,
the "our" variable $request will be undef in the unnamed Start
subroutine if I just try to define it with "my". Apparently using it in
foreach is the cause, but I am a bit unclear on how/why this happens?

Anyone have pointers to web pages etc where this is spelled out?

Also, using a global variable here is obviously kludgy. Forgive me.

----

#!/usr/bin/perl
use strict;
use warnings;
use XML::Parser::Lite;

my $xmldata = <<'END';
<response>
<record value="first"/>
<record value="second"/>
</response>
END

our $request;

my $parser = XML::Parser::Lite->new(
Handlers => {
Start => sub {
shift;
# Only process "record" blocks
return unless shift eq 'record';
# Load parsed xml into hash for access
my %data=@_;
print $request,"\t",$data{'value'},"\n";
},
},
);

foreach $request ( qw(datarequest) ) {
# Here we would retrieve xml data from SOAP using $request etc
$parser->parse($xmldata);
}

--
/* * * Otto J. Makela <o...@iki.fi> * * * * * * * * * */
/* Phone: +358 40 765 5772, ICBM: N 60 10' E 24 55' */
/* Mail: Mechelininkatu 26 B 27, FI-00100 Helsinki */
/* * * Computers Rule 01001111 01001011 * * * * * * */

E. Choroba

unread,
Oct 26, 2022, 5:34:45 AM10/26/22
to
The code can be simplified, you don't need the XML parser to demonstrate the behaviour:

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

# Replace "our" with "my".
our $request = 10;

my $print = sub { say 'print ', \$request, ": $request" };

for $request (12) {
say 'for ', \$request, ": $request";
$print->();
}

You can see the *address* of the variable is different when you use my. I'm not sure it's the expected behaviour, though, as the documentation says:

| If the variable was previously declared with "my", it uses that variable instead of the global one, but it's still localized to the loop.

I've never used "for/foeach $var" without "my". It's a good habit to get into and you then just need to assign the actual iteration value to the outer closed over variable.

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my $request = 10;

my $print = sub { say 'print ', \$request, ": $request" };

for my $r (12) {
$request = $r;
say 'for ', \$request, ": $request";
$print->();
}

E. Choroba

Eric Pozharski

unread,
Nov 3, 2022, 6:33:17 AM11/3/22
to
with <87eduwk...@tigger.extechop.net> Otto J. Makela wrote:

*SKIP*
> Also, using a global variable here is obviously kludgy. Forgive me.

I hope this horse is already dead and doesn't deserve any more beating.

*CUT*

--
Torvalds' goal for Linux is very simple: World Domination
Stallman's goal for GNU is even simpler: Freedom
0 new messages