Challenge 2: Count Lines Matching a Pattern — Possible Solution ==================================================================== use strict; use warnings; use feature 'say'; sub count_matching { my ($filename, $pattern) = @_; my $count = 0; open(my $fh, '<', $filename) or die "Can't open $filename: $!"; while (my $line = <$fh>) { $count++ if $line =~ $pattern; } close($fh); return $count; } my $errors = count_matching('app.log', qr/ERROR/); say $errors; WHY THIS WORKS AS AN ANSWER ------------------------------ my ($filename, $pattern) = @_; reuses Chapter 7's own argument- unpacking idiom, taking both the file to search and the pattern to search for as separate parameters, rather than hardcoding either one. open(my $fh, '<', $filename) or die "..."; reuses this chapter's own 3-argument open with error checking, applied to whichever filename was passed in. $count++ if $line =~ $pattern; combines two things directly from earlier chapters: Chapter 5's postfix conditional style (the increment only happens if the condition is true, in one line) and Chapter 6's =~ binding operator — but here $pattern is a variable holding a precompiled regex (built with qr/ERROR/, Perl's "quote regex" operator for storing a pattern in a scalar) rather than a literal /pattern/ written directly in the code, which is what makes the subroutine reusable for ANY pattern the caller wants to search for, not just one hardcoded into count_matching itself. return $count; reuses ordinary explicit return (Chapter 7) to hand back the running total once every line has been read — the same accumulator-variable pattern used throughout this course's earlier loop examples, just counting regex matches instead of something else.