in reply to Removing CODE slot in typeglob / Reversing "use subs ...;"

The only way I see is saving the typeglob, destroying it and re-creating it with all but the CODE slot:
use 5.010; use strict; our $FOO; BEGIN { $FOO = 'still foo'; } sub FOO () { 'foo' } BEGIN { *BAR = *FOO; say "in BEGIN (1): \$FOO = '$FOO'"; undef *FOO; say "in BEGIN (2): \$FOO = '$FOO'"; *FOO = *BAR{SCALAR}; undef *BAR; } say defined &FOO ? 'subroutine defined' : 'subroutine undef'; say eval 'my $false; FOO if $false; 1' ? 'FOO allowed' : 'FOO not allowed' ; say $FOO; __END__ in BEGIN (1): $FOO = 'still foo' in BEGIN (2): $FOO = '' subroutine undef FOO not allowed still foo

update: tweaked the code to more closely resemble the OP's.

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: Removing CODE slot in typeglob / Reversing "use subs ...;"
by stvn (Monsignor) on Jan 03, 2008 at 22:33 UTC
    The only way I see is saving the typeglob, destroying it and re-creating it with all but the CODE slot

    Yup, that is correct. That is how we do it in Class::MOP::Package, and when I was writing that bit at the YAPC::NA 2005 hackathon I queried the collective wisdom of the gurus in attendence (larry, audrey and chromatic to name a few) and they all agreed that was the only way. And AFAIK there is no cleaner way to do it in XS either.

    -stvn
      I wonder, is that a design accident or intended? you can assign to a typeglob slot (assigning a specific ref to that typeglob), but you cannot undef its value, you have to destroy the whole glob. You cannot assign e.g. an 'undefined subref' to a CODE slot, because... no such thing. Something undef is not a CODE ref.

      Did you get told the rationale behind that? Does anybody know? Cloning a typeglob to get rid of one entry in it looks like "useless use of hoops" to me. IMHO there should be a syntax to remove slots, keys, values and all, as delete does with plain hashes.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        Did you get told the rationale behind that? Does anybody know?

        No one told me or gave me any rationale. Most just shrugged and said "yeah its kinda messed up like that". You might note the distinct lack of typeglobs in Perl 6, I don't think they are really thought of as having been that great an idea in the end.

        -stvn
        It has to do with the method cache
Re^2: Removing CODE slot in typeglob / Reversing "use subs ...;"
by lodin (Hermit) on Jan 04, 2008 at 02:52 UTC

    The reason I didn't like this was that you couldn't access formats using *foo{THING} in Perl 5.6. I'd missed that *foo{FORMAT} now works (perl58delta). *foo{FORMAT} is not mentioned in either perldata or perlmod, but I found it in perlref. Really, that's not the first place I'd look to see which slots there are in a typeglob ...

    Thanks for forcing me to try (and fail) to proof that *foo{FORMAT} doesn't work, because that's what I originally intended to reply with. :-)

    *foo{FORMAT} and the resulting *foo{NAME} for the no-longer-constants was my only conserns, both of which are now solved. So I guess that marks the issue solved, unless you can see some other pitfall with this technique.

    lodin