in reply to How to get content of an XML::easytree output

G'day Tworec,

Welcome to the monastery.

Firstly, I see you've commented out "use strict;" - uncomment this and also add "use warnings;". Removing the output of warnings does not remove the problem they're telling you about!

You've commented out the declaration "my $element;". You assign nothing to $element. You then use $element as if it's a hashref - this is why you're getting the error message you report.

Your print_easy_tree() subroutine assigns its argument to $node; you then make no further reference to $node! Each instance of $element in this function should probably be $node.

I believe that should fix up your immediate problems. Here's some tips that you may find generally useful (i.e. not just for this code); the first two won't necessarily change how your code runs, but they should make it easier to read and understand:

-- Ken

Replies are listed 'Best First'.
Re^2: How to get content of an XML::easytree output
by tobyink (Canon) on Mar 08, 2013 at 06:44 UTC

    "e.g. instead of print "<$element->{name}>";, use print '<', $element->{name}, '>';

    Personally, I'd prefer:

    printf '<%s>', $element->{name};

    Update: just for the heck of it, this ain't too bad either:

    print "<$_>" for $element->{name};

    Using postfix for to temporarily alias $_ is an idiom I don't see used very much, but is quite cute, and in this case has no speed penalty (quite the opposite in fact)...

    use strict; use Benchmark ':all'; open $::dummy, ">", \$::data; cmpthese(100_000, { print_for => q[ $::data = ''; print {$::dummy} "<$_>" for "a" ], printf => q[ $::data = ''; printf {$::dummy} "<%s>", "a" ], }); __END__ Rate printf print_for printf 7663/s -- -79% print_for 36765/s 380% --

    (PS: kcott's follow-up was posted before this update, so please don't read it as necessarily endorsing the for postfix technique.)

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

      That, too, is good; it isolates the $element->{name} (++).

      Tworec states "I am a perl newbie" and "<$element->{name}>" didn't seem to scream clarity; in particular, the <$element-> bit.

      -- Ken

Re^2: How to get content of an XML::easytree output
by Tworec (Initiate) on Mar 08, 2013 at 08:52 UTC
    First of all, thanks for your reply. I changed all variables $element to $node and errors I reported are gone. But unfortunately a new one came. Not a HASH reference at line: if ($node->{type} eq 'e'). I think it's because of the $tree variable is ARRAY, but there is the main problem. My brain cannot really understand how to go threw an array of hashes and print it's elements. Should I write something like
    if(ref($node) eq HASH) do the code I have elsif(ref($node) eq ARRAY) $node = shift;
    ?

      Something like the following (untested) skeleton code:

      sub print_easy_tree { my $node_array_ref = shift; for my $node (@$node_array_ref) { if ($node->{type} eq 'e') { ... } elsif ($node->{type} eq 't') { ... } else { ... } } }

      -- Ken

        Great, it works now! Only if I could ask one more question.. Why @$ in @$node_array_ref? Why not just @?

        And if you know about a site where could I learn more of perl accessing to data, could you please give me a link? Of course I used google and found several sites with perl tutorials even in my language, but I mean if you know any you could personally recommend.