http://qs321.pair.com?node_id=1105757


in reply to Re^2: Novice problem: How to push a MooX Struct into a list?
in thread Novice problem: How to push a MooX Struct into a list?

Check this link: http://api.metacpan.org/source/BOFTX/Games-Dukedom-v0.1.1/lib/Games/Dukedom.pm

You will see where I use MooX::Struct and later initialize an attribute with StructName->new; in several places.

You can specify a zero-element array with my @array = ();. However, I seem to recall that if you do not provide a value for an attribute in MooX::Struct the element is not created and is in fact undef. But you are using the accessor in your push statement so that shouldn't be a problem.

If I get a break from the kids tonight I'll run your code and see what I can find. (No promises on Halloween, though.)

Update: The actual CPAN docs (which include the module source and an executable) can be found here if you're interested: Games::Dukedom

You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

Replies are listed 'Best First'.
Re^4: Novice problem: How to push a MooX Struct into a list?
by dissident (Sexton) on Oct 31, 2014 at 23:29 UTC

    Thank you Loops and boftx!

    Using the constructor for empty array as Loops showed, the script indeed ran without spewing errors.

    I have looked a bit into the long script boftx pointed me at. It really remembers me of a game I liked much on old Apple II :) Many interesting Perl details, in a well-readable script. Not one of these cryptic examples in the docs... But I'll look at it tomorrow when I am not tired as now.

    However, when trying to output the contents of the collected directory tree structures, I ran into another problem after adding a sub for this. I get an error "Global symbol "$mydir" requires explicit package name..." which I do not yet understand, as this is a my variable of a subroutine... Please excuse if I made an obvious blatant mistake :(

    use strict; use warnings; use diagnostics; use 5.014; # so push/pop/etc work on scalars (experimental) use MooX::Struct -rw, Dirnode => [ qw( $dirname @subdlist ) ]; my $dirroot = crawldir( "."); printdirs ($dirroot); sub printdirs { my $mydir = $_; # if subdirectories exist, walk them first ### vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv PROBLEM if (@($mydir->subdlist)) { # if ($mydir->subdlist) { ### ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PROBLEM foreach ($mydir->subdlist) { printdirs( $_); } } print "Dir: ", $mydir->dirname, "\n"; } sub crawldir { my $curpath = shift; my $dno = Dirnode["", []]; # my $dno = Dirnode->new(); $dno->dirname( $curpath ); opendir(DIR, $curpath); my @files = readdir(DIR); closedir(DIR); print "crawldir in directory ", $dno->dirname, "\n"; foreach (@files) { next if $_ eq '.' or $_ eq '..'; my $file_path = "$curpath/$_"; $file_path =~ s|/+|/|g; if (-d $file_path) { print "crawldir in directory ", $dno->dirname, ": calling c +rawldir( $curpath\/$_)\n"; push @{$dno->subdlist}, crawldir( "$curpath\/$_" ); } } return $dno; }

      boftx was right and spotted the problem with argument passing to your printdirs sub. You also had a problem with the dereferencing syntax:

      @($mydir->subdlist) should be @{$mydir->subdlist}

      Also, while it's not an error, the check to see if the array is empty is redundant, the for loop wont run if there are zero elements in the array. So the sub could be rewritten as:

      sub printdirs { my ($mydir) = @_; printdirs($_) for @{$mydir->subdlist}; print "Dir: ", $mydir->dirname, "\n"; }

      You probably want my $mydir = shift; or my ($mydir) = @_; from what I can see (but I'm still sober).

      You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

        My mistakes make me feel like a temple monkey trying to learn Perl :)

        Every paragraph of your explanations was helpful to me! Now it works!

        Thank you for your patience boftx and Loops :)