[Kc] infix pointer question

Andrew Moore amoore at mooresystems.com
Thu Aug 31 14:28:54 PDT 2006


Hi Jay - 

I'm not a computer linguist, and I don't even play one on TV, so I'll
get all of the terminology wrong. But I can give you the gist of this
stuff if you give me some slack on the jargon...

On Thu, Aug 31, 2006 at 11:01:44AM -0500, JYOUNG79 at kc.rr.com wrote:
> Just curious if someone wouldn't mind explaining how the 'infix' 
> pointer works?  I've been looking at some code here at work that an 
> outside programmer did a long time ago.  I'm totally confused as to how 
> this works:

The "->" operator essentially does two vaguely similar things. One is
that it dereferences references. In other words, it lets you get at
the stuff that a reference points to. The other thing it does is call
methods on an object. You're running into both types of usage here.

First, here's a somewhat simpler description of dereferencing. If you
have a reference to a hash (a hashref), you can use "->" to get at its
insides:

my $hashref = { dog => 'fido',
                cat => 'fluffy',
                cow => 'bessie' };

That $hashref points to an (unnamed) hash. Since it's a reference, you
use "->" to get to the internals.

print "my dog's name is: " . $hashref->{'dog'};

You can also have references to arrays (and scalars and
filehandles...). See 'perldoc perlref' and 'perldoc perlreftut' for
more information on this stuff.

Now, if you have an object (which is typically just a hashref that has
been 'blessed'), it typically has methods associated with it. (They're
just subroutines defined in the object's package). To call these, you
use "->", too. You may have seen this if you use the DBI object:

my $error = $db->do( 'delete from table where id = 4' );

Here, $db is a DBI object and we're calling the "do" method on it. You
can probably go in the DBI.pm file somewhere and see the definition of
do:

sub do {
 # some funky database magic here.
}

or, maybe you use the object oriented interface to CGI:

print $q->header('text/html');

Here, $q is a CGI object, and we're calling the "header" method on
it. That returns a string.

see these perldocs for more information on this object stuff:
perlboot - beginner's object oriented tutorial
perltoot - Tom's OO tutorial
perltooc - Tom's OO Class data tutorial

Now, to confuse the issue, as I said before many objects are blessed
hashrefs. Since they're hashrefs, sometimes people like to use "->" to
dereference them and get at some of their internals. This isn't always
the best object oriented policy, but it (usually) works.

let's look at your code:


> -----------------------------
> At first it looks like it's getting info for the scalar $HKrepobj...
> -----------------------------
> 
> # Grab the HKreport data block
> my $HKrepobj = $repobj->getHKreportobj( );

$repobj is probably an object that they're calling the
'getHKreportobj' method of. Go look in the .pm file that defines the
class that $repobj is a member of and look for "sub getHKreportobj"
for the definition of what gets run.

> 
> 
> sub getHKreportobj
> {
> 	my ( $obj ) = @_;
> 	return $obj->{ 'HKreport' };
> } # end sub getreportobj

Hey, there it is!

Since this sub is being called as a method, it's automagically passed
an argument of the object itself. This is often called $self, but I
see here it's called $obj. That's fine.

This is an accessor method. It pretty much just returns a piece of
object data. The way it gets that data is to dereference the hashref
called $obj with "$obj->{ 'HKreport' };

You could stick a call to Data::Dumper in there to see what $obj looks
like inside. I'll bet it would be enlightening. Try:

use Data::Dumper;
warn Data::Dumper->Dump( [ $obj ], [ 'obj' ] );
 


> 
> -----------------------------
> Next it's getting info for the scalar $madeinstr...
> -----------------------------
> 
> my $madeinstr = $HKrepobj->getmadein( );

call the 'getmadein' method on the $HKrepobj object.

 
> sub getmadein
> {
> 	my ( $obj ) = @_;
> 		# Make a shortcut to the actual data hash.
> 	# my $dh = $obj->{ 'data' };
> 	# return $dh->{ 'madein' };
> 	return $obj->{ 'data' }{ 'madein' };
> } # end sub getmadein

Here's a dereference into $obj to get to the 'data' element. The value
held in the 'data' element appears to me to be another hashref, and
we're accessing the 'madein' element of that one. (I believe that this
is more formally written as "$obj->{ 'data' }->{ 'madein' };" but you
can leave out that second arrow because it's kind of redundant)

put another call to Data::Dumper in there to see that the object here
is a hashref with a hashref stuck inside one of its elements. Maybe
something like this:

$obj = bless( { data => { madein => 'USA',
                          foo    => 'bar' },
                HKreport => 'blue' }, 'HK::Report )

notice that the thing that is in 'data' is another hashref. Maybe a
quick read of 'perldoc perldata' or 'perldoc perllol' or 'perldoc
perldsc' would be useful here.

> 
> I've researched a little about this - it looks like 'infix' pointers 
> dereference a reference??  I understand tha
> t a reference is a value that holds the location to another value but 
> the syntax above just doesn't seem to make any sense to me.  Instead of 
> using 'infix' pointers why not just return a regular scalar value or 
> array?

I believe that it is returning a scalar in most of these cases. It's
getting that scalar out of a hashref, though. Note that hashrefs,
arrayrefs, and ojbects are just scalars themselves. They may hold
references to larger things like hashes, though.

> 
> Thanks.
> 
> Jay

You bet!

If you want more information on this and you do better talking about
it than reading perldocs, ask at the next meeting. I bet that saying
"Can anyone explain the two uses of the skinny arrow to me, please?"
would result in a lively discussion. I hope I remember to bring a
pencil and paper that day.

-Andy



More information about the kc mailing list