in reply to Re: Subroutines with differing behaviour created from AUTOLOAD
in thread Subroutines with differing behaviour created from AUTOLOAD

Untested is right. That method will DEFINITELY work with more than one object in the class. I should know - I use it in production. You are NOT "injecting"(?) closures over the current $self. Test it before you make pronouncements like that.

However, the method will have issues for other reasons. The code implies that two difference instances might have the same field be editable or not at the instance level. If that's the case, then the first instance to access the field will set its editable-ness for all instances of the class.

There are two solutions. If each instance needs to maintain editability, then you have to go to the OP's solution, which is to have AUTOLOAD evaluate everything on a case by case basis. (This can still be gotten around, but you'd have to attach the closures to the instance and have the class methods dispatch to the instance's method. Too much work!)

If the fields are editable based on the class, then hoist the editability to the class level and deal with it there.

my $class = ref($self); my %editable = do { no strict 'refs'; %{"${class}::__EDITABLE__"}; }; die "No such method $AUTOLOAD. Barfing\n" unless exists $editable{$field}; if ($editable{$field}) { *$AUTOLOAD = sub { my $self = shift; $self->{$field}{value} = shift if @_; $self->{$field}{value}; }; } else { *$AUTOLOAD = sub { my $self = shift; die "Can't modify readonly field '$field'" if @_; $self->{$field}{value}; }; } goto &$AUTOLOAD;

------
We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

I shouldn't have to say this, but any code, unless otherwise stated, is untested

Replies are listed 'Best First'.
Re^3: Subroutines with differing behaviour created from AUTOLOAD
by hv (Prior) on Jun 08, 2004 at 16:15 UTC
    Untested is right. That method will DEFINITELY work with more than one object in the class. I should know - I use it in production. You are NOT "injecting"(?) closures over the current $self. Test it before you make pronouncements like that.

    With the original poster's code, this test:

    my $test = Foo->new(); my $test2 = Foo->new(); $test->read_write("water"); $test2->read_write("wine"); print "test: should be water, is ", $test->read_write, "\n"; print "test2: should be wine, is ", $test2->read_write, "\n";
    gives me:
    test: should be water, is wine test2: should be wine, is wine

    I'm confused as to what you're saying will definitely work - the OP's code has an AUTOLOAD sub which defines a lexical $self, in which he defines a couple of anonymous subs which refer to that $self. Nothing that can't be fixed by adding a my $self into the subs, as I did in my code and as you've done in yours.

    Hugo

      Nothing that can't be fixed by adding a my $self into the subs
      After a couple of /msg's with dragonchild, I realise this is what I should have done in my created subs. To do otherwise creates the problem you originally told me about.

      davis
      It's not easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.
      Ahhh. You were referring to a problem with the OP's code, not a problem inherent with the algorithm. Your code didn't have the problem you mentioned, but you didn't say that. Hence why I thought you were referring to a problem that your code would still have.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re^3: Subroutines with differing behaviour created from AUTOLOAD
by davis (Vicar) on Jun 08, 2004 at 16:16 UTC
    Can you explain what
    my %editable = do { no strict 'refs'; %{"${class}::__EDITABLE__"}; };
    does please? It looks to me like it's using a filehandle to populate a hash of the attributes that should be editable. Can you give an example of how to use this?
    Cheers

    davis
    It's not easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.
      Filehandle?? Nonono. Read up on do. Basically, it's a way of wrapping a block around an assignment, kinda like what I've done there. The idea is to directly access the symbol table using a soft (or symbolic) reference to find the %__EDITABLE__ hash in the class of the object being used. This way, we don't have to hardcode the classname in.

      Better yet would be to provide a method (called editable()?) which would return those values. This would play nicer with inheritance. Of course, the best solution is to have something that walks the @ISA tree, but that gets more complicated.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested