in reply to Re^2: A Class:: module I don't want to write
in thread A Class:: module I don't want to write

Doesn't an accessor method generator have to make assumptions about how your object's data is stored? I don't see how it could access the data if it didn't. Support could be added to these modules for array-based objects and the like as separate options, but you'd still need to tell it what your object looks like, or else use a multi-level get/set like Class::Accessor so you can define that part in your code.
  • Comment on Re^3: A Class:: module I don't want to write

Replies are listed 'Best First'.
Re^4: A Class:: module I don't want to write
by Perl Mouse (Chaplain) on Nov 23, 2005 at 12:01 UTC
    Doesn't an accessor method generator have to make assumptions about how your object's data is stored?
    Not if the generator takes care of storing the data. The generator could treat the object as if it were an inside-out object, and store attribute data in a hash - either a package variable, or a lexical hash using a source filter (a source filter doesn't have to parse the source, it can also be used to add something to the code - as what generators are basically doing). Then it doesn't really matter whether the object is an inside-out object, or a hash-based one, or something else.
    Perl --((8:>*
Re^4: A Class:: module I don't want to write
by Martynoff (Initiate) on Nov 23, 2005 at 14:05 UTC
    Not nessesarily. You may create an accessor as a closure over some local hashref. Then, store data in this hash with "self" object references as keys.
    sub create_accessor { my $hash = {}; return sub { # accessor my ($self, $value) = "_æ return $value ? $hash{$self} : $hash{$self} = $value; } }
    This sub will return an accessor, storing value without knowing anything of object structure :)

    --
    Sergey Martynoff

      Beside a memory leak, there's the possibility of a subtle bug. I had to modify your code slightly, but consider the following class:
      use strict; use warnings; package Class::SomeMethodMaker; sub create_accessor { my %hash = (); return sub { my ($self, $value) = @_; $hash{$self} = $value if @_ > 1; return $hash{$self}; } } package MyClass; { no strict 'refs'; *{"MyClass::colour"} = Class::SomeMethodMaker::create_accessor; } sub new {bless {}, shift} 1; __END__
      It's a simple class with a single accessor.

      Now I use this class in the following way:

      use strict; use warnings; use MyClass; for my $colour (qw /green yellow/) { my $obj = MyClass->new; $obj->colour($colour) unless $obj->colour; print $obj->colour, "\n"; } __END__
      You would expect it to print green\nyellow\n. However, it prints green\ngreen\n. The problem is that references are unique - but only references that exist at the same moment in time. References are not necessarely unique over time - they may be reused. Your technique only works if you do some work at DESTROY time - and that makes it trickier.
      Perl --((8:>*