in reply to Re: defining methods on the fly
in thread defining methods on the fly

hmm... Does the cache get rebuilt? And does the second glob assignment cause the same problem? Class::Accessor::Lvalue (mentioned above) uses an eval. Is the eval faster?

Replies are listed 'Best First'.
Re^3: defining methods on the fly
by diotalevi (Canon) on Aug 03, 2006 at 16:18 UTC

    Yes, the cache is rebuilt. You're just resetting it. All new method lookups after it's been reset are cached until it's reset again. Here's some code I ran in bleadperl which includes a function to look at the version number of the method lookup cache. Things that you do once during setup aren't usually of any account. It's worth blowing your cache then because you get all the utility of whatever it is that you stopped to do and you don't usually incur lots of extra runtime work. When you blow your cache during your run you impact your overall performance because now you're penalizing all the time consuming regular stuff too.

    use B 'sub_generation'; sub show_cache_version { print sub_generation, "\n" } show_cache_version; # 554 { show_cache_version; # 554 local *call = sub { }; show_cache_version; # 555 <- @ISA cache reset } show_cache_version; # 555

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      The following modification does not assign to a glob. Do this avoid the cache reset issue?
      #!/usr/local/bin/perl use warnings; use strict; use Want; sub lvalueMethod($) { my ($name) = @_; my ($package) = caller; no strict 'refs'; *{$package . "::" . $name} = sub :lvalue { my $self = shift; if (!want('LVALUE') && ref($self->{$name}) eq 'CODE') { goto &{$self->{$name}}; } $self->{$name}; }; } { package Foo; sub new { bless {}, shift; } main::lvalueMethod("bar"); } my ($x) = Foo->new(); print "$x\n"; $x->bar = 5; print $x->bar, "\n"; $x->bar = sub { print( @_, "\n" ); }; $x->bar("Hello World");

      Remember: There's always one more bug.
        From my understanding of his response that avoids the issue.
        The following modification does not assign to a glob.

        Apologies if I'm misunderstanding something here, but isn't the following code assigning to a glob?

        *{$package . "::" . $name} = sub :lvalue {

        Update: Thanks for the reply -- I was indeed "misunderstanding something here."