• Variable scopes?

    From Otto J. Makela@21:1/5 to All on Tue Oct 25 15:38:00 2022
    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 <om@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 * * * * * * */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From E. Choroba@21:1/5 to Otto J. Makela on Wed Oct 26 02:34:41 2022
    On Tuesday, October 25, 2022 at 2:38:06 PM UTC+2, Otto J. Makela wrote:
    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 * * * * * * */

    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Eric Pozharski@21:1/5 to Otto J. Makela on Thu Nov 3 09:00:25 2022
    with <87eduwkriv.fsf@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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)