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

unset is not setting the magic #1

Open
Ovid opened this issue May 17, 2024 · 9 comments
Open

unset is not setting the magic #1

Ovid opened this issue May 17, 2024 · 9 comments

Comments

@Ovid
Copy link
Owner

Ovid commented May 17, 2024

On my Mac, I'm getting the following error when I run make test:

PERL_DL_NONLAZY=1 "/Users/ovid/perl5/perlbrew/perls/perl-5.38.2/bin/perl" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/unset.t .. 1/?
#   Failed test 'var should start as unset'
#   at t/unset.t line 9.
# Looks like you failed 1 test of 4.
t/unset.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/4 subtests

Test Summary Report
-------------------
t/unset.t (Wstat: 256 (exited 1) Tests: 4 Failed: 1)
  Failed test:  1
  Non-zero exit status: 1
Files=1, Tests=4,  0 wallclock secs ( 0.01 usr  0.01 sys +  0.02 cusr  0.01 csys =  0.05 CPU)
Result: FAIL
Failed 1/1 test programs. 1/4 subtests failed.
make: *** [test_dynamic] Error 1

Somehow, the magic is not getting set when I do this:

my $var = unset;
@haarg
Copy link

haarg commented May 17, 2024

Outside of some special cases, magic is not copied across assignments.

@Ovid
Copy link
Owner Author

Ovid commented May 17, 2024

Oh! Duh. Don't I feel stupid. Working on a project with magic now and that should have been dead obvious to me.

Originally I had unset($var) and that worked, but it doesn't work for this use case:

sub something ($self, $new = unset) {
    if ( is_set($new) ) {
        $self->{something} = $new;
    }
    else {
        return $self->{something};
    }
}

Any pointers on where I can read those special cases?

@Ovid
Copy link
Owner Author

Ovid commented May 17, 2024

Or is there some way the code can know what it's been assigned to and attach magic to that? (I assume the answer is "no")

@Leont
Copy link
Contributor

Leont commented May 17, 2024

Any pointers on where I can read those special cases?

The special case is tainting, and it's very special and widely hated.

@haarg
Copy link

haarg commented May 17, 2024

vstring magic is the only one that "copies" across assignment, and it has special handling in sv_setsv_flags. tainting is another special case, but it's not even really doing copying. It sets a global flag that impacts every assignment in a given statement.

@Leont
Copy link
Contributor

Leont commented May 17, 2024

I almost got it to work using the vstring approach, but the magic vtable doesn't get copied along so it doesn't quite work. A one-line fix in core probably would make this possible (but should it?)

@Ovid
Copy link
Owner Author

Ovid commented May 20, 2024

@Leont What is the one-line fix, what does it do, and what would the impact be? Would it allow for more things like this to be possible?

@Leont
Copy link
Contributor

Leont commented May 20, 2024

@Leont What is the one-line fix, what does it do, and what would the impact be? Would it allow for more things like this to be possible?

this sv_magic call would need to become a sv_magicext call with smg->mg_vtbl as vtable argument.

Though in reality it's probably a bit more complicated as this path is only taken by SVp_POK values, and you probably want unset values to be undefined.

@Ovid
Copy link
Owner Author

Ovid commented May 20, 2024

@Leont Yeah, they would need to be undefined. Setting them to any value, even undef, would make them "set."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants