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
*CORE::GLOBAL::caller=\&CORE::caller doesn't work #12061
Comments
From @xdgCreated by @xdgAssigning *CORE::GLOBAL::caller = \&CORE::caller does not appear However, *CORE::GLOBAL::caller = sub { goto &CORE::caller } works This seems likely to lead to subtle errors down the line. I have not tested any of the other CORE subs for similar behavior. Example files that demonstrate the problem are included inline below. (sigh -- __Foo.pm__ # fails # works sub override { sub fake_caller { 1; __test.pl__ use Foo; sub join_caller { # line 99 is( wrapper( \&join_caller ), "main - test.pl - 99", "not localized" ); done_testing; __output.log__ Perl Info
|
From @cpansproutOn Tue Apr 17 11:28:13 2012, dagolden@cpan.org wrote:
Argh!!! I wrote a two-page response and the RT server failed to The new core subs use cv_set_call_checker to inline themselves. Any XS The problem here is that we have two different things that people expect These two expectations conflict, resulting in things like bug #24250. I don’t really know what the best way forward is. I’m not even sure One approach might be to special-case the way built-in keywords fall -- Father Chrysostomos |
The RT System itself - Status changed from 'new' to 'open' |
From @cpansproutOn Tue Apr 17 14:51:16 2012, sprout wrote:
Including a proper global caller override, which would not exhibit this: $ perl5.15.9 -ce 'caller(1,2)' $ perl5.15.9 -ce 'BEGIN { *CORE::GLOBAL::caller = sub { goto -- Father Chrysostomos |
From @xdgOn Tue, Apr 17, 2012 at 5:51 PM, Father Chrysostomos via RT
Sorry to hear that. I hate it when that happens.
That's a long and twisty bug report. I'd like to ignore the general
I agree that the "right" approach is not obvious. I can see not -- David |
From @cpansproutOn Tue Apr 17 17:04:04 2012, xdaveg@gmail.com wrote:
In my head I just can’t make this fit together. :-( CORE::GLOBAL allows the prototypes of overridable keywords to be changed. Allowing the prototypes to change (i.e., calling the call checker) also So how do we force the sub call to compile down to an entersub while BTW, we already have this problem with sub () { 1 }. -- Father Chrysostomos |
From @nwc10On Tue, Apr 17, 2012 at 05:12:34PM -0700, Father Chrysostomos via RT wrote:
I don't think that you can ignore the general case. Because I'm pretty sure that the *CORE::GLOBAL::XXX case has all the
Right. Components of this are: 1: There is a concern that subroutine invocation is slow. By implication of the above design description, these cannot be 2: Historically the built in functions have been special, in that they aren't a) you couldn't take references to them, because they aren't actually 2a - 2c are addressed by changing %CORE:: so that one can get a reference However, it gives a lot of scope to *also* solve 2d, and simplify a very This, 2d, means that the functions provided in %CORE:: need to be of the They are new. This isn't a change from old behaviour.
I'm not convinced that all the desired features do fit together.
Without warning. I'm wondering if it should warn, given that this warns: $ perl -le 'sub CORE::GLOBAL::gzgetss($$;$) {}; *CORE::GLOBAL::gzgetss = sub {}' ie %CORE::GLOBAL:: should either *be* pre-populated with references to all Should that be a new ticket?
And we will have this problem with any other inlining subroutine that which gets to 3: Consistency - if subroutine in %CORE::GLOBAL:: is one that inlines, it which, I would argue, means that things like this *CORE::GLOBAL::getppid = \&CORE::getppid; is a) taking a reference to a known self-inlining subroutine and hence should behave the same way as sub PI () { 4; }; If we have self-inlining subroutines, then those subroutines by intent can't We break consistency of the internals if the built in functions exposed To do that seems to end up with a few possible ways to cope 1) any self-inlining function found in %CORE::GLOBAL:: doesn't inline I appreciate the desire to be able to run-time localise any function *CORE::GLOBAL::getppid = sub () { goto &CORE::getppid; }; I'm still preferring what I'd view as option 0 0) any self-inlining function found in %CORE::GLOBAL:: inlines. as it makes the common things easy, the uncommon things are still possible, Nicholas Clark |
From zefram@fysh.orgNicholas Clark wrote:
+1. Runtime-swappable overriding of builtins is a rather specialised -zefram |
From @xdgOn Fri, Apr 20, 2012 at 10:05 AM, Nicholas Clark <nick@ccl4.org> wrote:
I see *CORE::GLOBAL:XXX as a special case because it (more or less) In other words, it was an *explicit* mechanism for replacing an That is very distinct from the more general desire that Foo::bar() (Arguably, the original intended semantic was "replace this builtin
I think there should be a warning if a subroutine is assigned to I want to defer considering the proposed mechanism for a bit until I
In this conversation, I realized that even prior to 5.15, you can *CORE::GLOBAL::rand = sub() { 0 }; That exhibits the same problem with localization as the caller example. On reflection, I mostly agree with your "option 0" (for the reasons *CORE::GLOBAL::rand = sub() { 0 }; I think that makes a lot of sense when localizing *CORE::GLOBAL I don't think that should warn generally for localizing *Foo::bar Then, addressing the earlier question about the behavior of On the other hand, doing so would ensure the warning about localizing Summary: I think localizing *CORE::GLOBAL::XXX should warn in two - *CORE::GLOBAL::XXX{CODE} is an inline sub It seems like that would sufficiently address the issue of surprising It might also be good for some existing or new module to offer a C<< -- David |
From @cpansproutOn Fri Apr 20 07:06:10 2012, nicholas wrote:
Probably. (Now I’m straying from the topic of this ticket:) That (Maybe we should move this to a new ticket. :-) -- Father Chrysostomos |
From @cpansproutOn Fri Apr 20 10:06:41 2012, xdaveg@gmail.com wrote:
I don’t think there is any way to determine whether a subroutine’s call
I don’t understand how that would help. Could you elaborate? -- Father Chrysostomos |
From @xdgOn Fri, Apr 20, 2012 at 4:42 PM, Father Chrysostomos via RT
In "Foo.pm" -- note commented out line: package Foo; # *CORE::GLOBAL::caller = sub { goto \&CORE::caller }; sub override { sub fake_caller { 1; In "test.pl" use Test::More; sub join_caller { join " - ", caller; } is( Foo::override( \&join_caller ), "fake - fake.pl - 1" ); done_testing; With the initial C<< local *CORE::GLOBAL::caller = ... >> commented N.B. This is why Sub::Uplevel has to assign a (pure perl) Thus, I think they are similar kinds of errors -- someone is trying to There could be situations where localizing without a prior override is -- David |
From zefram@fysh.orgDavid Golden wrote:
No, it's an explicit mechanism for replacing an op with *something else*.
I agree with this, if it can be done cleanly.
Not possible in the general case. You could perhaps do a might_inline(), -zefram |
Migrated from rt.perl.org#112504 (status was 'open')
Searchable as RT112504$
The text was updated successfully, but these errors were encountered: