Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables used inside Lexical Subroutines are not being recognized #48

Open
gnustavo opened this issue Dec 23, 2022 · 0 comments
Open
Labels

Comments

@gnustavo
Copy link

Hi there. I'm converting some anonymous subroutines into lexical subroutines in Git::Hooks but Test::Vars started to complain in a way that a do not understand.

I was able to come up with a small script that shows the problem directly. I call it test-vars-lexical-sub.pl and it contains the following code:

#!/usr/bin/env perl

use v5.26.0;

use Path::Tiny;
my $tempdir = Path::Tiny->tempdir;
my $lib = $tempdir->child('lib');
$lib->mkpath;
my $script = $lib->child('Test.pm');
$script->spew(<<'EOF');
package Test;

use v5.26.0;

sub outer_ref {
    my (@args_ref) = @_;

    my $var_ref;

    my $inner_ref = sub {
        $var_ref = @args_ref;
        return $var_ref;
    };

    return $inner_ref->();
}

sub outer_lex {
    my (@args_lex) = @_;

    my $var_lex;

    my sub inner_lex {
        $var_lex = @args_lex;
        return $var_lex;
    };

    return inner_lex();
}

1;
EOF

use Test::More 0.96 tests => 1;
use Test::Vars;

vars_ok($script);

It creates a test script and invokes vars_ok() on it, which complains like this to me:

$ ./test-vars-lexical-sub.pl
1..1
not ok 1 - /tmp/jj_DZalwGb/lib/Test.pm
#   Failed test '/tmp/jj_DZalwGb/lib/Test.pm'
#   at ./test-vars-lexical-sub.pl line 47.
# checking Test in Test.pm ...
# @args_lex is used once in &Test::outer_lex at /tmp/jj_DZalwGb/lib/Test.pm line 19
# $var_lex is used once in &Test::outer_lex at /tmp/jj_DZalwGb/lib/Test.pm line 21
# Looks like you failed 1 test of 1.

It complains about the variables @args_lex and $var_lex not being used, but they are used in the inner_lex lexical subroutine, as you can see.

Note that the test doesn't complain about the similar variables @args_ref and $var_ref not being used. But the only significant difference between them that the *_ref variables are used inside an anonymous subroutine (saved in the $inner_ref variable) while the *_lex variables are used inside a lexical subroutine (inner_lex).

It took me a while to notice that the test only complains if the code is inside a package and if the script is in a file named after the package and inside a lib directory. If you remove the package line, rename the package, rename the Test.pm file, or rename the lib directory, the test succeeds:

$ ./test-vars-lexical-sub.pl
1..1
ok 1 - /tmp/iBuAaKsLti/lib/Test.pm
# checking Test in Test.pm ...

I'm at a loss here. Is it a bug in Test::Vars or is it due to some subtle behavior of lexical subroutines interacting with packages?

@jkeenan jkeenan added the Bug label Sep 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants