halecommarachel has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
This line of code isn't working for me:
print "$_ could not be restored!\n" unless (exists $found{$_}) foreach (@files);
This is the error:
syntax error at /home/fisusr/bin/monitor_ssh.pl line 108, near ") foreach "
Is this not valid code? Thanks in advance.

Replies are listed 'Best First'.
Re: foreach loop on one line
by Kenosis (Priest) on Dec 03, 2013 at 00:49 UTC

    Is this not valid code?

    Very close, but no, it's not. You need a code block with that foreach, as it is:

    do { print "$_ could not be restored!\n" unless ( exists $found{$_} ) +} foreach (@files);

    or (more commonly)

    foreach (@files) { print "$_ could not be restored!\n" unless ( exists $found{$_} ); }

    or you could

    exists $found{$_} or print "$_ could not be restored!\n" foreach @file +s;

    Why does this last one work? An (inclusive) or statement is true iff one of its disjuncts is true. If exists $found{$_} is true, there's no need to evaluate the 'expression' on the other side of the or, because the entire or statement is true. However, if exists $found{$_} is not true, then the other side of the or will be evaluated, viz., print "$_ could not be restored!\n".

    Hope this helps!

Re: foreach loop on one line
by BrowserUk (Patriarch) on Dec 03, 2013 at 00:54 UTC

    I'd code that this way:

    exists $found{$_} or print "$_ could not be restored!\n" for @files;

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: foreach loop on one line
by KurtZ (Friar) on Dec 03, 2013 at 01:20 UTC
    unfortunately post-fix statements cant be nested w/o do-blocks.

    I'd suggest:

    print "$_ could not be restored!\n" for grep { not exists $found{$_} } @files;
    or even
    print map {"$_ could not be restored!\n" } grep { not exists $found{$_} } @files;
Re: foreach loop on one line
by toolic (Bishop) on Dec 03, 2013 at 00:50 UTC
    perlsyn
    foreach (@files) { print "$_ could not be restored!\n" unless exists $found{$_}; }
Re: foreach loop on one line
by tobyink (Canon) on Dec 03, 2013 at 09:25 UTC

    The very first line of the documentation for Statement Modifiers (i.e. the postfix forms of if, unless, foreach, while, etc) says:

    Any simple statement may optionally be followed by a SINGLE modifier, just before the terminating semicolon (or block ending).

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name