Q: re the kind of reference to be bless()ed in OO perl

M

Michele Dondi

I must say in advance that I know the most basic aspects of OO
programmin in Perl, but I've never been really proficient with it. So
pardon my ignorance...

It is often said that the reference that gets bless()ed to create an
object is one to an anonymous hash, which makes perfectly sense, as
the examples abunding everywhere clearly indicate.

I've also seen bless()ing something like an empty {array,hash}ref to
be used "solely" as an index into a package/class global hash to
enforce some degree of encapsulation.

Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.


Michele
 
A

Ala Qumsieh

Michele said:
I've also seen bless()ing something like an empty {array,hash}ref to
be used "solely" as an index into a package/class global hash to
enforce some degree of encapsulation.

I'm not sure what you mean there. Can you show a code snippet please?

Note that bless() returns the blessed reference, so it can be used as
the last statement of the constructor to return the object (blessed
reference).
Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.

I believe Damian Conway has a few examples in his Object-Oriented Perl
book. Personally, I have written many Perl classes, and can only recall
one that didn't use a hashref for the object representation (I used an
arrayref, to be precise, since the data structure I was after was easily
representable as a matrix).

--Ala
 
A

Andrew Lee

I must say in advance that I know the most basic aspects of OO
programmin in Perl, but I've never been really proficient with it. So
pardon my ignorance...

It is often said that the reference that gets bless()ed to create an
object is one to an anonymous hash, which makes perfectly sense, as
the examples abunding everywhere clearly indicate.

I've also seen bless()ing something like an empty {array,hash}ref to
be used "solely" as an index into a package/class global hash to
enforce some degree of encapsulation.


Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.

Certainly ... though I don't know how smart, cool or witty.

z.B.

#!/usr/bin/perl
use strict;

package Foo;

my $action = {
Default => \&Default,
PrintThis => \&PrintThis,
DumpENV => \&DumpENV
};

if ($action->{$ARGV[0]}) {
$action->{$ARGV[0]}->();
} else {
$action->{Default}->();
}

sub Default { print "no args?\n"; }
sub PrintThis {print "foo\n"; }
sub DumpENV {
for (keys %ENV) {
print "$_ => $ENV{$_}\n";
}
}

_END_


$ ./lookup_table.pl PrintThis
foo
$

*shrug*

Naturally you can bless $action ... which just means it can be used in another
Perl program like a static class member as $Foo::action
 
B

Brian McCauley

Michele Dondi said:
I must say in advance that I know the most basic aspects of OO
programmin in Perl, but I've never been really proficient with it. So
pardon my ignorance...

It is often said that the reference that gets bless()ed to create an
object is one to an anonymous hash, which makes perfectly sense, as
the examples abunding everywhere clearly indicate.

I've also seen bless()ing something like an empty {array,hash}ref to
be used "solely" as an index into a package/class global hash to
enforce some degree of encapsulation.

Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.

The obvious example of the filehandle (or actually the GLOB) is
the IO:: classes.

The other time you'd need to use something other than an ARRAY or HASH
is when you want an object that implements an array and hash API. For
this you need to overload the @{} and %{} operators to return (often
tied) array and hashes. You can't sensibly define the %{} operator if
the object is itself a blessed hash.

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
A

Anno Siegel

Brian McCauley said:
[...]
Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.

The obvious example of the filehandle (or actually the GLOB) is
the IO:: classes.

The other time you'd need to use something other than an ARRAY or HASH
is when you want an object that implements an array and hash API. For
this you need to overload the @{} and %{} operators to return (often
tied) array and hashes. You can't sensibly define the %{} operator if
the object is itself a blessed hash.

Well, you can, for relaxed values of "sensibly".

Say you want an object that looks like a hashref to the user, but counts
accesses in an internal field:

package MyClass;

sub new {
my $class = shift;
bless {
count => 0,
content => { @_ },
}, $class;
}

The user should only see the "content" hash, but other methods must
be able to access the full object. The trick is to make the overloading
accessor caller dependent:

sub as_hash {
my $ob = shift;
return $ob if caller eq __PACKAGE__;
$ob->{ count} ++;
return $ob->{ content};
}

use overload ( '%{}' => 'as_hash' );

A method like

sub count { $_[ 0]->{ count} }

can still access the "outer" hash because its caller is MyClass.

Anno
 
N

nobull

Brian McCauley said:
[...]
Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.

tied) array and hashes. You can't sensibly define the %{} operator if
the object is itself a blessed hash.

Well, you can, for relaxed values of "sensibly".

The trick is to make the overloading accessor caller dependent:

sub as_hash {
my $ob = shift;
return $ob if caller eq __PACKAGE__;

That's too relaxed a definition of sensible for me. It means that
every access to the blessed hash has to go throught the accessor.
This is rather a high price to pay.
 
A

Anno Siegel

(e-mail address removed)-berlin.de (Anno Siegel) wrote in message
Brian McCauley said:
[...]

Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.

tied) array and hashes. You can't sensibly define the %{} operator if
the object is itself a blessed hash.

Well, you can, for relaxed values of "sensibly".

The trick is to make the overloading accessor caller dependent:

sub as_hash {
my $ob = shift;
return $ob if caller eq __PACKAGE__;

That's too relaxed a definition of sensible for me. It means that
every access to the blessed hash has to go throught the accessor.
This is rather a high price to pay.

Well, if it's fast enough, it's fast enough. Sometimes brute force
is what you need, temporarily or for good. The technique has helped
me to establish inheritance between otherwise incompatible classes.

Anno
 
M

Michele Dondi

I'm not sure what you mean there. Can you show a code snippet please?

Sorry, I must have been not particularly clear. What I've seen at
times is along these lines:

{
package Foo;

use warnings;
use strict;

my %attribs;

sub new {
my $class=shift;
my $self=bless [], $class;
$attribs{$self}={ bar => undef };
$self;
}

sub DESTROY {
my $self=shift;
delete $attribs{$self};
}

sub set_bar {
my $self=shift;
$attribs{$self}{bar}=shift if @_;
}

sub get_bar {
my $self=shift;
$attribs{$self}{bar};
}
}

Note that bless() returns the blessed reference, so it can be used as
the last statement of the constructor to return the object (blessed
reference).

I knew that... So what?!? (No offense intended)
I believe Damian Conway has a few examples in his Object-Oriented Perl
book. Personally, I have written many Perl classes, and can only recall
one that didn't use a hashref for the object representation (I used an
arrayref, to be precise, since the data structure I was after was easily
representable as a matrix).

I see... well, I can think of rather "artificial" examples as follows:

package Adder;

use warnings;
use strict;

sub new {
my ($class,$n)=@_;
bless sub {
$n+shift;
}, $class;
}

sub doit {
shift->(pop);
}

but I was asking exactly if there are known cases in which using e.g.
a subref brings some real advantage or is quite a natural approach for
the problem being tackled.


TIA,
Michele
 
M

Michele Dondi

Now I wonder if there are common/cool/smart/witty cases in which it is
natural to use a reference to some other kind of object, like e.g. a
sub, or filehandle, etc.

Certainly ... though I don't know how smart, cool or witty. [snip]
my $action = {
Default => \&Default,
PrintThis => \&PrintThis,
DumpENV => \&DumpENV
}; [snip]
Naturally you can bless $action ... which just means it can be used in another
Perl program like a static class member as $Foo::action

Thank you for the example. But this is not exactly what I was asking
(it may well be that the question was not well posed). $action is
still a hashref...


Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top