Skip to content

universal.c - handle version style imports as a version check #21279

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

Open
wants to merge 2 commits into
base: blead
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion t/test.pl
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,8 @@ ($$@)
my $p = 0;
$p++ while substr($got,$p,1) eq substr($expected,$p,1);
push @mess,"# diff at $p\n";
push @mess,"# after "._qq(substr($got,$p-40<0 ? 0 : $p-40,40))."\n";
push @mess,"# after "._qq(substr($got,$p < 40 ? 0 : $p - 40,
$p < 40 ? $p : 40)) . "\n";
push @mess,"# have "._qq(substr($got,$p,40))."\n";
push @mess,"# want "._qq(substr($expected,$p,40))."\n";
}
Expand Down
65 changes: 57 additions & 8 deletions universal.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,17 +461,66 @@ XS(XS_UNIVERSAL_import_unimport)
dXSI32;

if (items > 1) {
char *class_pv= SvPV_nolen(ST(0));
SV *class_sv = ST(0);
char *class_pv = SvPV_nolen(class_sv);
if (strEQ(class_pv,"UNIVERSAL"))
Perl_croak(aTHX_ "UNIVERSAL does not export anything");
/* _charnames is special - ignore it for now as the code that
* depends on it has its own "no import" logic that produces better
* warnings than this does. */
if (strNE(class_pv,"_charnames"))
Perl_croak(aTHX_
"Attempt to call undefined %s method with arguments via package "
"%" SVf_QUOTEDPREFIX " (Perhaps you forgot to load the package?)",
ix ? "unimport" : "import", SVfARG(ST(0)));
* depends on it has its own "no import" logic that produces
* better warnings than this does. We special case
* Test::SubExport::SETUPALT as Sub::Export is high in the CPAN
* river, and is owned by rjbs, who will fix it soon. For now
* special case it. */
if (strNE(class_pv,"_charnames") &&
strNE(class_pv,"Test::SubExport::SETUPALT"))
{
/* !ix means "import was called" */
IV cmp_items = 1;

if (!ix && Perl_looks_like_number(aTHX_ ST(1))) {
SV *want_version = ST(1);
cmp_items = 2;

/* it looks like the caller has done one of the following:
*
* use Thing '1234';
* Thing->import('1234');
*
* But Thing doesn't define its own import() method.
* So we convert this call into
*
* Thing->VERSION('1234')
*
* which does the version check. VERSION will throw
* an exception if the Thing package isn't defined.
*/

/* note it would be nice if we could do the
* equivalent of 'goto &UNIVERSAL::VERSION'
* here and avoid having to repush items onto the
* stack.
*/
ENTER_with_name("call_VERSION_from_import");
SAVETMPS;
EXTEND(SP, 2);
PUSHMARK(SP);
PUSHs(class_sv);
PUSHs(want_version);
PUTBACK;
(void)call_method("VERSION", G_VOID);
SPAGAIN;
PUTBACK;
FREETMPS;
LEAVE_with_name("call_VERSION_from_import");
}

if ( items > cmp_items ) {
Perl_croak(aTHX_
"Attempt to call undefined %s method with arguments via package "
"%" SVf_QUOTEDPREFIX " (Perhaps you forgot to load the package?)",
ix ? "unimport" : "import", SVfARG(ST(0)));
}
}
}
XSRETURN_EMPTY;
}
Expand Down