develooper Front page | perl.module-authors | Postings from November 2003

Re: Class::FakeAttributes -- Opinions Wanted

Thread Previous | Thread Next
From:
Fergal Daly
Date:
November 7, 2003 01:17
Subject:
Re: Class::FakeAttributes -- Opinions Wanted
Message ID:
20031106175810.GC30069@dyn.fergaldaly.com
On Thu, Nov 06, 2003 at 05:58:25PM +0100, A. Pagaltzis wrote:
> Read it too. My point is that the method would be accessible from
> a much broader scope (ie globally, really) than would the
> attribute hash in Yves' code (stricly local to the method).

Yes, _all_ methods are globally accessible.

As you said, my method is accessible globally and Yves' hash is strictly
local to the method. However Yves's method is also accessible globally and
my hash is also strictly local to the method. So I don't see the point of
this comparison.

> I'm not interested in where the attribute is stored. I'm talking
> about the attribute. Whether it is accessed by hash lookup or
> closure call makes no difference. In Yves' code, the attribute is
> only accessible to the method in its scope (by looking it up in
> the lexically scoped hash), while using your code, the attribute
> would be accessible globally (by calling the exported function).

Again, this is the same comparison as above. In Yves' code as in mine, the
the attribute is only accessible to the sub and the sub is accessible
globally. Not exporting it makes no difference. Anyone can call that
inside_out method from anywhere. Just because a sub is declared inside {},
along with %attrib doesn't mean that the sub is locally scoped, if it did
then nothing at all would be able to call the Yves' inside_out method, which
would make it a bit pointless.

I think you're misunderstanding the purpose of my code. Here it is again
except this time I've provided the import() method rather than just leaving
it to the imagination. It's a method maker that makes methods in the style
of Yves' example method, so you can make lots of them without having the
type refaddr all over the place.

F

######### Inside out method maker

use strict;
package InsideOut;

use Scalar::Util qw(refaddr);

sub import
{
  my $self = shift;

  my $class = caller();
  foreach my $attr (@_)
  {
    make_attr($class, $attr);
  }
}

{
  my %attribs;
  sub make_attr {
    my $class = shift;
    my $attr = shift;

    my $full = "${class}::${attr}";

    my $sub = sub {
      my $s=shift;
      if (@_) {
        $attribs{$full}->{refaddr($s)}=shift;
        return $s;
      } else {
        return $attribs{$full}->{refaddr($s)};
      }
    };
    {
      no strict 'refs';
      *{$full} = $sub;
    }
  }
}

1;


#########################
#### Usage example

use Test::More tests => 4;   

my $red9 = Object->new;
my $blue1 = Object->new;

$red9->Colour("red")->Size(9);
$blue1->Colour("blue")->Size(1);

is($red9->Colour, "red");
is($red9->Size, 9);
is($blue1->Colour, "blue");
is($blue1->Size, 1);
 
package Object;

# these attributes will be stored somewhere else because there's nowhere to
# store them in the object itself.

use InsideOut qw( Colour Size );

sub new
{
        my $pkg = shift;

        my $a = "string";
        return bless \$a, $pkg;
}

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About