Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^4: Tutorial: Introduction to Object-Oriented Programming

by adrianh (Chancellor)
on Dec 13, 2002 at 08:32 UTC ( #219532=note: print w/ replies, xml ) Need Help??


in reply to Re^3: Tutorial: Introduction to Object-Oriented Programming
in thread Tutorial: Introduction to Object-Oriented Programming

Another issue has just come to mind. With the object attributes being keyed on "$self", which includes the name of the class, you can no longer bless an object into a sibling class to implement state transitions.

Again, I guess some people would consider this a feature. I quite like the technique myself :-)

To overcome you'll need to strip out the class name. Assuming nobody changes the output format of references in later perl versions something like this should work.

package Foo; use strict; use warnings; use overload; my %foo = (); my %self = (); # we access self enough for it to be worth caching sub self { my $self = overload::StrVal shift; return $self{$self} if exists $self{$self}; $self{$self} = substr($self, index($self, '=')+1); }; sub new { my $class = shift; bless [], $class; }; sub foo { my $self = shift->self; $foo{$self} = @_ if @_; $foo{$self}; }; sub DESTROY { my $self = shift->self; delete $foo{$self}; undef %self; };

Also, there is another advantage to Abigail-II's method. Storing the attributes in separate hashes should less expensive in memory - buckets cost less than hashes. Might make a difference if you're creating lots of objects.


Comment on Re^4: Tutorial: Introduction to Object-Oriented Programming
Download Code
Re: Tutorial: Introduction to Object-Oriented Programming
by Abigail-II (Bishop) on Dec 13, 2002 at 11:02 UTC
    There's an easier way to strip out the class name. A reference in numeric context returns just the number part - so you could do my $self = 0 + shift;.

    Abigail

      Your right - forgotten about that.

      You still have the problem of overloading tho - what if a subclass overloads "+"?

      Unfortunately, there isn't an overload::NumVal to match overload::StrVal (unless I'm missing something somewhere ;-)

      You can get around this by blessing the object into another class you know isn't overloaded, get the numeric ID, and then bless the object back into it's original class. For example:

      package Foo::Base; use strict; use warnings; sub self { my $self = shift; my $package = ref($self); bless $self, __PACKAGE__; my $id = $self+0; bless $self, $package; return($id); }; package Foo; use base qw(Foo::Base); use strict; use warnings; my %foo = (); sub new { my $class = shift; bless [], $class; }; sub foo { my $self = shift->self; $foo{$self} = @_ if @_; $foo{$self}; }; sub DESTROY { my $self = shift->self; delete $foo{$self}; };

      Mildly evil - but seems to work.

        Unfortunately, there isn't an overload::NumVal to match overload::StrVal (unless I'm missing something somewhere ;-)

        I think the best way to do this is Scalar::Util::refaddr. And its much faster than parsing overload::StrVal.
        :-)

        But it isn't core (at 5.6 anyway)
        :-(

        --- demerphq
        my friends call me, usually because I'm late....

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://219532]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (10)
As of 2014-09-18 14:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (116 votes), past polls