in reply to Counting matches.

/g in scalar context (as imposed by >=) only returns the next match. This allows people to do something like

while (/a/g) { ... }

Since the result of a list assignment in scalar context is the number of elements in the assigned list, the trick is to assign the result of the match to a list, even an empty one, and place that assignment in scalar context.

my $count = () = 'baa baa black sheep' =~ /a/g;

Or as it applies here,

print( ( () = 'baa baa black sheep' =~ /a/g ) >= 3 ? 'more' : 'less' ) +;

Replies are listed 'Best First'.
Re^2: Counting matches. (scalar list assign)
by ikegami (Patriarch) on Dec 07, 2007 at 08:25 UTC

    If anyone is interested in more uses of list assignments in scalar context, consider functions that need to be able to return any scalar while also able to signal some special condition.

    In C++, you might very well do something like

    bool next(Type& arg) { if (...) { return false; } else { arg = ...; return true; } } while (i->next(arg)) { ... }

    You could do the same in Perl

    sub next { my $self = $_[0]; our $arg; local *arg = \$_[1]; if (...) { return 0; } else { $arg = ...; return 1; } } while ($i->next($arg)) { ... }

    But another solution is to return either 1 scalar or 0 scalars.

    sub next { my ($self) = @_; if (...) { return; } else { return ...; } } while (my ($arg) = $i->next()) { ... }

    One might be tempted to do the following, but it won't work if the function can return a false value (such as 0, "0", "", undef, etc).

    while (my $arg = $i->next()) { ... }