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