cobes has asked for the wisdom of the Perl Monks concerning the following question:
Well I've been learning Perl for about a year now using the cgi-lib.pl module. (Just can't quite get a good enough grip on OO yet...) For the most part I don't have too much trouble but I'm doing very basic tasks... opening, reading and writing to files, sending email and printing output to the screen. However, I need a little help with a few trouble areas.
I have been working with flat files. (I KNOW everyone recommends using the Perl DB module but I'm not ready for that yet.) I have learned some SQL to be able to do that but just not yet.
First I have a few questions: (I will include examples)
1)I read that Perl uses /t as a default delimiter in a split function. Is this a fact?
2)I can open a file, lock it & "while" it is "open" assign it to an array, read/print the contents of the array to verify its existance, unlock it & close it. No problem...
3)The problem I am having is that I'm not sure how to simply "write" to the file using the /t (tab) as the delimiter. I want the data to be split with a tab.
4)I was using the following to split with a space with
"some" success:
@line = split(/ /, $_);<p. The problem with that when writing the output to the screen caused any "textarea" data to ONLY return the first word of this field to the output field on the screen form. So I tried to split the scalars with a space before and after when writing to the log file like this:
$info=" $scalar1 "." $scalar2 "." $scalar3 \n";
When I viewed the contents of the log file, I have 2 spaces between data fields but I'm pretty sure this is a real boneheaded way to achieve this needed separation. The other problem was when it returned output to the screen form, some of the contents of one data field had found it's way over to an adjacent field... NG.
The single spaced delimiting does work if you only have ONE field when you do this and match it:
5)If I try to put the if conditional "inside" the while loop, (where "I think" it should go), so that I can break out of the loop immediately after I find a match (instead of checking EVERY remaining element, which would be an inefficient waste of time and resources) like this:*** This works but inefficient *** $item = ($input{'item'}); #input passed in from html form $found=0; #set $found to zero open(FILE, "myfile.txt") || die("$!") #open for reading while(<FILE>) { #while file is open flock(FILE, 2); @line = split(/ /, $_); #split fields with single space $itemDB = $line[0]; #assign 1st element from DB to $itemDB if ($itemDB eq $item) { $found++ #increment $found if true } #end if **DO I NEED A next, last or continue somewhere?? } #end while flock(FILE, 8); #unlock file close(FILE); #close file if ($found) { #if $found is true &Sub1(); #call this sub if true } else { &Sub2(); #call this sub if false } (html blah, blah)
Is it possible to use a foreach for this...it would seem to me that it's not too efficient to have to iterate through EACH item when technically I only need to check 1 of 3 elements on EACH line. That seems like a 66% waste of computing resources for no benefit...unless a foreach loop operates so quickly that it's not an issue. These are the things I must bring before the Monastery. I'm aware that ultimately the larger the file size the greater the impact on the benchmark time...$item = ($input{'item'}); #input passed in from form $found=0; open(FILE, "myfile.txt") || die("$!") #open for reading while(<FILE>) { #while file is open flock(FILE, 2); @line = split(/ /, $_); #split fields with single space $itemDB = $line[0]; #assign 1st element from DB to $itemDB if ($itemDB eq $item) { &Sub1(); #call this sub if true } else { #end if & start else &Sub2(); #call this sub if false } #end else } #end if } #end while flock(FILE, 8); #unlock file close(FILE); #close file (html blah, blah)
Here's the problem: It only returns the first file (number - 1000) even if you enter 1001 or 1002 into the html form field. I'm pretty sure I've tried it substituting "eq" for text matching as well as "==" for numerical matching. Should I convert the number to a string and then match it using "eq"???
Simple flat file contents I use for testing:
1000 chair good
1001 desk ok
1002 table damaged
etc, etc...
My thoughts...
Maybe I should try matching the element[0] data loaded into the @line array like so, but I must first make sure the data has been separated with a /t delimiter:
if (@lineDB eq =~/$item\/t/)
I need to figure out how to break out of the loop after finding and displaying a good matched query.
Do I also need to first define the existing database array like so: (Is this even right...??) :)) Man I'm trying!!!
@info = ("1000", "chair", "good");
($item, $name, $cond) = @info;
I'm thinking that I should be using some kind of "indexed" array or $key to access ONLY the first element $info[0] of the @info array. Is this even right or am I going nutty here...?
It's getting late...better send this. If anyone can help me out with ANY of this it would be great!
Thanks in advance for taking the time to read this... :)
cobes...
I study & study & study & still... one of these days man...
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Breaking a loop after a valid match + proper use of /t delimiter.
by dvergin (Monsignor) on Jan 13, 2002 at 11:18 UTC | |
by cobes (Initiate) on Jan 14, 2002 at 06:43 UTC | |
|
Re: Breaking a loop after a valid match + proper use of /t delimiter.
by jlongino (Parson) on Jan 13, 2002 at 11:49 UTC | |
|
Re: Breaking a loop after a valid match + proper use of /t delimiter.
by grinder (Bishop) on Jan 13, 2002 at 20:28 UTC |