I didn't say auto-vivification was the problem. I said that using undefined references was his problem. Auto-vivification is saving his butt. He should be using a hash here. Trying to emulate a hash by using a sparse matrix is difficult, error prone and wrong.
In general the code is very poor; the OP uses map when foreach would do, he uses foreach when map or grep is called for, he iterates over an array to create a hash when he could have hashed the data to begin with, he has multiple arrays holding the same data, he uses push when a hash is called for and he uses indexing where a push would serve. Arguing over auto-vivification is akin to rearranging the deck chairs while the ship is sinking.
s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s
|-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,,
$|=1,select$,,$,,$,,1e-1;print;redo}
| [reply] [d/l] |
I'm sure I am not doing this the right way, I'm not a programmer at all, rather an information security professional. We have a need to compare the MD5 value of files to a list of known bad, and I think Perl would be a good way to do it. I'm basically taking it one piece at a time.
1.) Scan the remote system and put all of the filenames and locations into a data set (multidimensional array in this case).
2.) Take that data, and compare to the MD5 list (comma delimited file with "filename,hash value") using the intersect of the two lists of filenames.
3.) I then need to take the list of filenames and their paths (many files have multiple matches but in different directories), and get the MD5 hash of the remote file and compare it to the bad MD5.
4.) If there is a match, somehow identify this and then run a report at the end, or just spit it out to a log file during the match.
You had a nice list of things I did incorrectly, if you would like to provide an outline of how to do this correctly, I'd be happy to restart on the script (it isn't that long). I'll be completing my undergraduate degree at the end of this month and plan to focus on learning Perl and C/C++, so this would be a good learning opportunity for me.
| [reply] |
I am very sorry to dump on your code like that jbush82. I realize not everyone codes at the same level and I try to dole out the advice in digestible pieces but I let pc88mxer get under my skin and you got caught in the crossfire.
As to your code, have you implemented some of the other suggestions given to clean up your code?
Perl has powerful list operators map, grep shift, unshift, push and pop. Studying the perldocs for these would help to unleash the power of perl to you. One book that has a particularly good treatment of these is "Intermediate Perl" by Schwartz, d foy, and Phoenix. They explain list operators better that I ever could.
In general, to build and add or remove from lists use push, pop, shift and unshift. To change, diplay or copy every element of a list use map(). To create a new list with selected element of a previous list use grep(). Use foreach() if it is the side-effects of operations on the list that are important and use map() and grep() if it's the returned elements of the list that are important.
Any time, in your code, you need to search a collection of items based on a name you should be thinking hash. Perl's hash datatype provides a powerful and efficient method of storing named containers that would take at least a page of C code to emulate. See perldata and perlreftut
I wrote a similar piece of code to check the md5 hash on a list of files where I use some of the list operators. The code is written for unix and doesn't need to keep a list of matches as yours needs but I think the techniques used there would translate well to your requirements. Note particularly that no indexing variables are used.
s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s
|-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,,
$|=1,select$,,$,,$,,1e-1;print;redo}
| [reply] [d/l] |