Making a dynamic hash of arrays in foreach in perl based on regex -


so i'm trying make hash of arrays based on regex inside foreach.

i'm getting file paths, , of format:

longfilepath/name.action.gz 

so there files same name diffent actions, want make hash keys of name arrays of actions. i'm apparently doing wrong keep getting error when run code:

not array reference @ ....the file i'm writing in 

which don't since i'm checking see if set, , if not declaring array. i'm still getting used perl, i'm guessing problem simple.

i should say, i've verified regex generating both 'name' , 'action' strings problem in foreach;

thanks help. :)

my code thus.

my %my_hash; $file_paths = glom("/this/is/mypath/*.*\.gz");  foreach $path (@$bdr_paths){      $path =~ m"\/([^\/\.]+)\.([^\.]+)\.gz";      print stderr "=>".dumper($1)."\n\r";     print stderr "=>".dumper($2)."\n\r";      #add entity type hash recipe key     if($my_hash{$1})     {         push($my_hash{$1}, $2);     }     else     {         $my_hash{$1} = ($2);     }  } 

it’s glob, not glom. in glob expressions, period no metacharacter. → glob '/this/is/mypath/*.gz'.

the whole reason of using alternate regex delimiters avoid unneccessary escapes. forward slash no regex metacharacter, delimiter. inside charclasses, many operators loose specialness; no need escape period. ergo m!/([^/.]+)\.([^.]+)\.gz!.

don't append \n\r output. ① dumper function appends newline. ② if on os expects crlf, use :crlf perlio layer, transforms \ns crlf. can add layers via binmode stdout, ':crlf'. ③ if doing networking, might better specify exact bytes want emit, e.g. \x0a\x0d or \012\015. (but in case, remove perlio layers).

using references first arg push doesn't work on perls older v5.14.

don't manually check whether populated slot in hash or not; if undef , used arrayref, array reference automatically created there. known autovivification. of course, requires perform dereference (and skip short form push).

in perl, parens only sort out precedence, , create list context when used on lhs of assignment. not create arrays. create anonymous array reference, use brackets: [$var]. using parens useless; $x = $y , $y = ($y) absolutely identical.

so either want

push @{ $my_hash{$1} }, $2; 

or

if ($my_hash{$1}) {   push $my_hash{$1}, $2; } else {   $my_hash{$1} = [$2]; } 

edit: 3 things overlooked.

if glob used in scalar context, turns iterator. unwanted, unless when used in while(my $path = glob(...)) { ... } fashion. otherwise more difficult make sure iterator exhausted. rather, use glob in list context matches @ once: my @paths = glob(...).

where $bdr_paths come from? inside?

always check regex matched. can avoid subtle bugs, captures $1 etc. keep value until next successful match.


Comments

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

css - Firefox for ubuntu renders wrong colors -