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

This is my first post, so I hope I don't mess anything up.

I am creating a module that deals with a specific kind of xml called ettx. The object it creates is supposed to hold two hashes for comparison later. This is the code so far:

#!/usr/bin/perl -l package ETTX; use strict; use warnings; use XML::Simple; use Data::Dumper; sub load(;$){#file name my $class = shift; my $self; if(@_ == 1){ my $xml = XML::Simple->new(); $self = { ettx => $xml->XMLin(shift), #for main file template => {}, }; } else{ $self = { ettx => {}, template => {}, } } bless $self, $class; return $self; }; sub loadEttx($){ my $self = shift; my $xml = XML::Simple->new(); $self=>{ettx} = $xml->XMLin(shift); } sub loadTemplate($){ my $self = shift; my $xml = XML::Simple->new(); $self=>{template} = $xml->XMLin(shift); } 1;

However, I'm getting a compile time error which says:

Can't modify anonymous hash ({}) in scalar assignment at C:\Texts\Programs\ETTX.pm line 31, near "};"

Line 31 being the one that says "$self=>{ettx} = {};"

I can't find my error anywhere. Can anyone spot it?

Thanks! ---Nathan

Replies are listed 'Best First'.
Re: can't modify anonymous hash ({}) in scalar assignment
by BrowserUk (Patriarch) on Jul 24, 2010 at 19:51 UTC
    "$self=>{ettx} = {};"

    Apart from I cannot see that particular line in the code you've posted; if it is there, it should probably be:

    $self->{ettx} = {}; .....^

    Update: Ah! You probably mean:  $self=>{ettx} = $xml->XMLin(shift); which should be:

    $self->{ettx} = $xml->XMLin(shift); ......^

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Yes, I apologize. I wrote the post and then deleted lines of code I had inserted for debugging but were not necessary for this. The line you mention was the problem one.

      And you were right about the syntax, too!. I thought => was for pointers and -> was for subs. I guess I should google that.

      Thanks!

        Comma Operator
            The "=>" operator is a synonym for the comma except that it causes its
            left operand to be interpreted as a string if it begins with a letter or
            underscore and is composed only of letters, digits and underscores.
        
        The Arrow Operator
        
            ""->"" is an infix dereference operator, just as it is in C and C++. If
            the right side is either a "[...]", "{...}", or a "(...)" subscript,
            then the left side must be either a hard or symbolic reference to an
            array, a hash, or a subroutine respectively. (Or technically speaking, a
            location capable of holding a hard reference, if it's an array or hash
            reference being used for assignment.) See perlreftut and perlref.
        
            Otherwise, the right side is a method name or a simple scalar variable
            containing either the method name or a subroutine reference, and the
            left side must be either an object (a blessed reference) or a class name
            (that is, a package name). See perlobj.
Re: can't modify anonymous hash ({}) in scalar assignment
by AnomalousMonk (Archbishop) on Jul 24, 2010 at 20:47 UTC
    sub loadEttx($){ ... $self=>{ettx} = $xml->XMLin(shift); } sub loadTemplate($){ ... $self=>{template} = $xml->XMLin(shift); }

    The error pointed out by BrowserUk is actually present twice in the posted code (AFAICS).

    In addition, there's no point in prototyping all the methods: prototypes are ignored in method calls. (The general monastic wisdom is: Just don't ever bother with prototypes unless you really know what they do and why you need one in a particular case!)

    Update: The methods in the OPed code are prototyped to take either zero or one, or else exactly one, scalar arguments – but all three methods take two arguments! Again, it doesn't matter because no prototype checking is ever done.

Re: can't modify anonymous hash ({}) in scalar assignment
by Jenda (Abbot) on Jul 25, 2010 at 14:47 UTC

    Apart from the syntax error there is one more possible problem. Are you sure XML::Simple returns the data in a consistent enough way? Without any options? What if some tag that may be repeated occurs just once in a particular file? Or some tag with optional attributes doesn't have them in some cases?

    See Simpler than XML::Simple.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

      I'm not worried about it in this case because an ettx file is wholly predictable and all of my Dump tests have printed exactly what I needed.
Re: can't modify anonymous hash ({}) in scalar assignment
by Anonymous Monk on Jul 24, 2010 at 20:51 UTC

    These subs seems to be called as methods. When they are, the prototype is not checked. See perlsub's "Prototypes" section.

    You might want to remove those prototypes, lest they lull you into thinking they're checking your methods' arguments.

      I was wondering why it didn't seem to matter that $self was always in the arguments... Really the reason they were there was to remind me of their usage. What do most people do? Something like this?

      sub loadEttx(){#scalar file name
        For small projects self-documenting code usually works well enough. Choose good variable names and append descriptors like "_aref" for array references, "_href" for hash references, etc. If you are passing a lot of variables in or you feel like you need to heavily document what is being passed in then you could probably do with so some code code refactoring. An obvious one is if you are passing in a lot of variables then think about putting them into a hash and then just passing in a reference to the hash instead (this also makes it easier to add new variables/hash entries as your code evolves). If you want some additional documentation then put in some POD above the subroutine explaining what is does, what it takes/expects, returns, etc. You might also want to check out Perl Best Practices.
         

        Elda Taluta; Sarks Sark; Ark Arks