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

I have made my constructors:
package HIT; sub new { my $class = shift; my $class = ref($class) || $class; my $self = {}; $self->{Name} = "Default"; $self->{Length} = 0; $self->{Score} = 0; $self->{Expect} = 0; $self->{Ident} = "Default"; $self->{Strand} = "Default"; $self->{Match} = "Deafult"; bless ($self,$class); return $self; }
Everything works well. Until I add a second instance of my object class. ie $a = new HIT; $b = new HIT; I have some methods that change each of these variables, only they change BOTH not just one. Any ideas? I have searched and read FAQ's! Thanks.

Replies are listed 'Best First'.
Re: Object Troubles
by davorg (Chancellor) on Jul 13, 2000 at 12:27 UTC

    I think maybe that you'd better show us the code that changes the attributes as there doesn't seem to be anything seriously wrong with the code that you've posted here.

    --
    <http://www.dave.org.uk>

    European Perl Conference - Sept 22/24 2000, ICA, London
    <http://www.yapc.org/Europe/>
Re: Object Troubles
by mikfire (Deacon) on Jul 13, 2000 at 16:52 UTC
    davorg has the right of it, but I did notice something in your examples of how you are creating the objects. I am not claiming this will fix your problem, but the syntax
    my $a = new Hit;
    is some very bad juju. In a couple nasty ways, this syntax can break and is now considered the Wrong Way ( if Conway himself is threating to beat people up for using this method, I figure we can classify it as the Wrong Wat ).

    The Better Way is to say

    my $a = Hit->New();
    But please do post the code as davorg requested and we can offer more help.

    mikfire

      This is news to me. Is it something new in 5.6?

      ++ for you, milkfire, if you update with references explaining how this syntax can break, or at least a few people who have expressed their disapproval.

      Update: Aha. I see it now. Thanks to milkfire and chromatic for setting me straight. I hadn't read that far down perlobj and was relying on fading memories of Programming Perl.

      ++ for all involved, 'cept me of course. ;)

        It depends on at least two things. First (and most important), that the interpreter knows about the existence of that class before you make that call. Otherwise, the program could die with an 'unquoted bareword' error. That doesn't sound too bad, until you get a few thousand lines in your program and don't remember what gets defined where. Ack.

        The second is a little more obscure, but equally mysterious. Suppose you have an overloaded method somewhere, and you use the indirect syntax (verb object, not object->verb) to call it. What happens if there's a namespace collision? Perl will try for the main::method_name() first, and that'll probably break things.

        Yes, you can program for a long time before running into those kinds of errors, but when you do, you'll wish you'd listened. :)

        It is in perlobj. Search for indirect and read - perlobj describes it better than I can. The essence is that perl's smoke-and-mirrors can get confused when using the indirect syntax and it can be very painful to track down. The wisdom of the elders is to leave it alone.

        mikfire

        mikfire is right that I should have spotted this. As far as I know it's always been a deprecated way to call object methods. I don't have the references with me at the moment, but I'm sure it's discussed in Object Oriented Perl and The Perl Cookbook.

        --
        <http://www.dave.org.uk>

        European Perl Conference - Sept 22/24 2000, ICA, London
        <http://www.yapc.org/Europe/>
(chromatic) Re: Object Troubles
by chromatic (Archbishop) on Jul 14, 2000 at 02:48 UTC
    Without seeing the accessor methods, I can only surmise that you're setting class (not instance) variables:
    sub name { my $self = shift; # the following is the broken line $self = ref($self) || $self; if (@_) { $self->{Name} = shift; } return $self->{Name}; }
    The following demonstrates what happens:
    my $a = new HIT; my $b = new HIT; print $a->Name('Corwin, Prince of Amber'); print $b->Name();
    Even calling the constructors with the direct object syntax doesn't work. Of course, this all depends on how your methods work.