There are quite a few issues with your code:
Your second readdir (in the for my $i (@files) loop) doesn't read anything since the first one (@files=grep{!/^\./}readdir CWD;) already read the whole directory. You could use rewinddir first, but simply using a copy of @files (before pushing foo.txt and bar.txt) would be simpler and more efficient.
You are using != instead of ne to compare strings.
Every iteration of your loop erases the previous value of @differences since you assign it with =. Presumably push would make more sense.
The logic inside your loop is a bit flawed. grep returns the elements that satisfy the condition, but you are more interested in whether any elements satisfies it.
You should check if opendir succeeded (by adding a or die ... to the opendir line). Also, note that open my $CWD, getcwd is equivalent to the simpler open my $CWD, ".".
What you probably wanted to do is something like:
use strict;
use warnings;
opendir my $CWD, "." or die "Could not open '.': $!";
my @files = grep{!/^\./} readdir $CWD;
my @init_files = @files;
push @files, ("foo.txt", "bar.txt");
my @difference;
for my $i (@files){
push @difference, (grep { !/^\./ and $i eq $_ } @init_files) ? () : $i;
}
print "$_\n" for @difference
That's far from efficient however, and more complicated that it needs to be. I suggest instead:
my %files = map { $_ => 1 } grep {!/^\./} readdir $CWD;
my @difference;
for ("foo.txt", "bar.txt") {
push @difference, $_ if ! exists $files{$_};
}
print "$_\n" for @difference
Note that I've added use strict; use warnings; to the script. Always add them to your codes. While in that specific case, it would not have helped you find out what's wrong, it will save you countless hours in the future. Also, always use lexical file/directory handles (that is, do opendir my $CWD, "dir" rather than open CWD, "dir").