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

Hi,

let's say that I have an object with a definition like:

my $self = { _username => Polo, _user_tags = [], _user_pass => undef }

And I want to save the status of the object like an XML file.

I tried first with:

my $data = $xml->XMLout(%$self , XMLDecl => 1, OutputFile => $xmlf +ile, NoAttr=>1 );

which results in:

Options must be name=>value pairs (odd number supplied) at...

Then I tried

foreach (keys %$self) { $hash->{$_} = $self->{$_}; } my $data = $xml->XMLout($hash , XMLDecl => 1, OutputFile => $xmlfi +le, NoAttr=>1 );

with no luck:

Operation "==": no method found, left argument has no overloaded magic, right argument in overloaded package Net::IP at inc/XML/Simple.pm +line 1406

And afterwards:

$hash->{_username} = $self->{_username} $hash->{_user_tags} = $self->{_user_tags} $hash->{_user_pass} = $self->{_user_pass} my $data = $xml->XMLout($hash , XMLDecl => 1, OutputFile => $xmlfile, +NoAttr=>1 );

and that works as I expected giving the XML I need

And the question is, Why the different behaviour if all the options I tried are basically the same?

Thanks to all monks

Replies are listed 'Best First'.
Re: XMLout $self hash
by jethro (Monsignor) on Jul 29, 2011 at 11:55 UTC

    Your first version is different from the others because you give the hash itself as parameter instead of a reference to the hash. The parameter list of a subroutine invocation is an array context. But a hash in array context is simply an array with key value pairs. So with your first version

    XMLout(%$self , XMLDecl => 1 ... # is nearly* equivalent to XMLout(_username, Polo, _user_tags, [],_user_pass, undef , XMLDecl => +1 ... # * not exactly equivalent because the order of the hash # contents is random

    Your second version seems to be identical to your third version (at least I couldn't spot a difference at first glance, but I didn't test it), could it be that you made some typing or copying error somewhere?

Re: XMLout $self hash
by kcott (Archbishop) on Jul 30, 2011 at 07:18 UTC

    It's important to provide sufficient information so that your problem can be reproduced. You have not stated what $xml is. I've assumed this is an XML::Simple object: it could be a subclass of XML::Simple or, indeed, any class providing an XMLout() method. Do let us know if my assumption is wrong! So, my test code (xml_simple_args.pl) starts with:

    use strict; use warnings; use XML::Simple; my $xmlfile = q{xml_simple_args.xml}; my $xml = XML::Simple->new();

    It's important to post the code you've actually tested. The assignment to $self produces these messages:

    $ xml_simple_args.pl Bareword "Polo" not allowed while "strict subs" in use at ./xml_simple +_args.pl line 9. Execution of ./xml_simple_args.pl aborted due to compilation errors.

    and after quoting Polo:

    $ xml_simple_args.pl Can't modify constant item in scalar assignment at ./xml_simple_args.p +l line 11, near "]," Bareword "_user_tags" not allowed while "strict subs" in use at ./xml_ +simple_args.pl line 9. Execution of ./xml_simple_args.pl aborted due to compilation errors.

    My test code uses:

    my $self = { _username => q{Polo}, _user_tags => [], _user_pass => undef, };

    I was able to reproduce the first error you posted. The third line of the XML::Simple documentation SYNOPSIS has:

    my $xml = XMLout($hashref [, <options>]);

    I changed %$self to $self and this worked without error. jethro has provided information about this (above).

    I was unable to reproduce your second error: the code you posted worked just fine.

    I was unable to reproduce your success with the third version you posted; however, after terminating each statement with a semi-colon, this worked fine as well.

    Each successful run produced the same output:

    $ cat xml_simple_args.xml <?xml version='1.0' standalone='yes'?> <opt> <_user_pass></_user_pass> <_username>Polo</_username> </opt>

    Lessons learned from this exercise:

    • Post sufficient code so others can reproduce your results (e.g. state what class you're using).
    • Post the code you actually tested.
    • Read the documentation.
    • Add use strict; and use warnings; near the start of your code.

    -- Ken

      Thanks, your comment made me, finally, realize the error in my code

      First I want to apologize for not posting correct code, but I am unable to disclose the code i am workning with right now

      So, the problem rised when in the object I had..

      sub new { ... $self = { ... _IP => undef, ... } bless ($self, $class); return $self; } sub set_ip { my ($self,$ip) = @_; $self->{_IP} = new Net::IP($ip) or die (Net::IP::Error()); }

      The problem here is that Net::IP does not overload the method '==' so XMLout explodes at line 1406 in Simple.pm.

      if(grep($_ == $ref, @{$self->{_ancestors}}));

      You can see this line is trying to look for references to the present node (circular references)

      So either a) overload '==' at XML::Simple b) Instead of using Net::IP use simple strings c) comment lines 1405 and 1406

      Thanks

Re: XMLout $self hash
by Anonymous Monk on Jul 29, 2011 at 11:31 UTC

    And the question is, Why the different behaviour if all the options I tried are basically the same?

    Because in real life (unlike the sample you've shown here), they are different, they are not the same