seaver has asked for the wisdom of the Perl Monks concerning the following question:

Dear all,

I've come across something that I'm sure is related to inheritance, but for all my ignorance, could be a bug.

I have these three packages:

PDB PDB::Line PDB::Line::Atom

Each line from a PDB is saved in a new PDB::Line object, in an array in PDB.

If the line happens to be an ATOM line, then a new PDB::Line::Atom object will be created and stored in PDB::Line. I will be creating a variety of modules that cover all the different types of PDB Lines.

OK, in PDB::Line i do this:

($self->{'TYPE'},$self->{'data'}) = unpack("A6 A74", $self->{'string'} +); if($self->{'TYPE'} eq 'ATOM'){ $self->{'object'} = new PDB::Line::Atom($self->{'data'}); }
in PDB::Line::Atom, this happens:
sub new { my $class = shift; my $self = {}; $self->{'AN'} = ''; $self->{'A'} = ''; $self->{'AL'} = ''; $self->{'R'} = ''; $self->{'RN'} = ''; $self->{'IC'} = ''; $self->{'X'} = ''; $self->{'Y'} = ''; $self->{'Z'} = ''; $self->{'OC'} = ''; $self->{'TE'} = ''; $self->{'SI'} = ''; $self->{'E'} = ''; $self->{'C'} = ''; bless $self, $class; $self->parse(shift); return $self; } sub parse{ my $self=shift; ($self->{'AN'}) = unpack("A5", $_[0]); print $self->{'AN'}."\n"; }
each ATOM line looks like this:
ATOM 242 CE2 PHE A 16 9.011 14.465 -20.603 1.00 0.00 + C
but the unpack line in the PDB::Line means that PDB::Line::Atom only gets this:
242 CE2 PHE A 16 9.011 14.465 -20.603 1.00 0.00 + C
Which is true, it works. But ONLY, and ONLY if I subscript the @_ with a number.

If I try using '$_', since I am only passing one value, this is what I used instinctively, it will output "ATOM'. Meaning it passes the entire line including the 'ATOM' header. But how can it, when the '$self->{'data'} doesn't have it!!

My best guess is that when I open and read the file using <>, it is remembering the $_ from that??

Any explanation would be greatly appreciated.

Thanks

Sam Seaver

20030923 Edit by jeffa: Changed title from 'Inheritance of $_?? '

Replies are listed 'Best First'.
Re: Why are @_ and $_ not linked?
by dragonchild (Archbishop) on Sep 22, 2003 at 17:13 UTC
    Well, first off, $_ and @_ have absolutely no relationship with one another. None. So, even if you only pass one item, $_ isn't set to it. (Unless, of course, you do something like $_ = shift;)

    Now, you are correct that $_ is "remembering" when it was last set. This is because $_ (and @_) are both global variables in the truest sense of the word. (This, btw, is why you should always do local $_; in a sub within a module you intend on manipulating $_ within.)

    So, the question I ask you is why aren't you doing something like

    sub parse{ my $self=shift; my ($line) = @_; ($self->{'AN'}) = unpack("A5", $line); print $self->{'AN'}."\n"; }

    Or, some other, more relevant, variable name ...

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Why are @_ and $_ not linked?
by BrowserUk (Patriarch) on Sep 22, 2003 at 17:27 UTC
    My best guess is that when I open and read the file using <>, it is remembering the $_ from that??

    You hit the nail on the head! $_ is global, and is not reset when you call a subroutine. The parameters to a sub are passed via @_, even if there is only one parameter.

    As $_ and @_ are completely different entities, sharing only a name, and that you can access the whatever value $_ had before the sub was called when inside the sub is completely unrelated to value of any parameters passed.

    That $_ and $_[n] look similar is perhaps the source of your confusion, but they are not related other than by their name. The first is a scalar, then second an array of scalars.

    Or perhaps what is fooling you is that with some of perl's built-ins, if no parameters are passed, they default to using the current value of $_. It is possible to code your own subs to do this also

    sub thing{ my( $arg) = @_ ? @_ : $_; ... }

    but this is generally frowned upon.

    Reading that back, I'm not sure if it clarifies anything much, but maybe it does:)


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.