2

I am trying to populate a textarea with text. The text will be comments a user has made. It will be loaded from a file called comments.txt

The file template is:

 username1
 commentscomments
 commentscomments
 username2
 commentscommentscome
 comchefhjshfhhfjdjdj
 dfhfhjdijedhdjdjdjdj
 username3
 februgusyfvretgtyef

I also have a file called accounts.txt which stores the usernames.

My current code just writes the entire comments.txt file to the textarea

  my $username=(param('username')); 
  open my $FHIN, '<', "comments.txt" || die "$!";
  my @fhin = <$FHIN>;
  print textarea(-name=>"CommentArea",-default=>"@fhin",-rows=>10,-columns=>60);

I was thinking should I have a sub that returns an array of strings that are the comments of the user? And how should I structure it should I have a loop of the comment file that checks if each line eq the username and if it does it prints each line until it comes to another line that matches a line on the accounts.txt

Basically the textarea should only show:

 commentscommentscome
 comchefhjshfhhfjdjdj
 dfhfhjdijedhdjdjdjdj

if username2 is the user thats logged on.

Any help is appreciated!

3
  • Can you distinguish between a username and a comment line in your file? It will be hard to figure out when to stop reading. In general you could have a sub to read the file. You need to check if the current line contains the username. If yes, you start reading all the lines until you find the next username. But how do you know if it's a username if there is no marking? Commented Dec 4, 2013 at 20:21
  • By checking the accounts file at every line was what I was thinking? Commented Dec 4, 2013 at 20:29
  • 3
    Separate issue: use or not || in your open, as you'll not trap errors using the latter as written, since it's parsed as open(my $FHIN, '<', 'comments.txt'); Commented Dec 4, 2013 at 20:35

1 Answer 1

1

Assuming you have a list of all the user accounts and you put that into a hash, you could do it as follows.

sub get_comments {
  my ($username, $filename, $all_users) = @_; # $all_users is a hashref

  open my $FHIN, '<', $filename or die "Cannot open $filename for reading: $!";

  my @comments;
  my $found; # starts out as undef
  while (my $line = <$FHIN>) {
    chomp $line;

    if (exists $all_users->{$line}) {
      last if $found; # stop once we find another user
      if ($line eq $username) {
        $found++;
        next;
      }
    }

    push @comments, $line if $found;
  }
  return \@comments;
}

my $comments = get_comments(param('username'), 'comments.txt', $all_users);
print textarea(
  -name    => "CommentArea",
  -default => join("\n", @{ $comments }),
  -rows    => 10,
  -columns => 60,
);

It opens your file and checks for usernames. If it finds our username, it will start saving the lines after that until it finds a different username and stops. The file name is an argument so you do not have to rely on a single file and can get that from config (or use a test file for unit testing).

There is no need to close the file handle as it will go out of scope and implicitly close at the end of the sub.

It prints:

<textarea name="CommentArea"  rows="10" cols="60">commentscommentscome
comchefhjshfhhfjdjdj
dfhfhjdijedhdjdjdjdj</textarea>
Sign up to request clarification or add additional context in comments.

2 Comments

What happens if username3 on its own line is the first comment under username1 and username3 was sent to get_comments()?
It will return the remaining comments under username1s first comment username3. That of course sucks. But without a delimiter for the usernames, this is a design flaw I cannot really do something about. See also my comment on the question about that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.