Okay.
$first_digit = $1 if $x =~ /^(\d)\d*$/;
could also be written like this, which may make it
clearer:
if ($x =~ m/^(\d)\d*$/) {
$first_digit = $1;
}
The "=~" is like "equals" but is used in pattern matching
instead of the "==" (numeric) or "eq" (string) comparison
operators. I've used "m" (for match) here before the pattern, but Perl just assumes this is what you mean if it's
left out. The "/"'s around the pattern just open and close
the pattern; it's like quoting. The "^" means "at the
beginning of the field" and "$" means "at the end of the
field". Since we're using "^" and "$" to anchor the pattern, $x must consist entirely of numeric characters
(which means that it wouldn't work on numbers with decimal
points or negative numbers, actually). "\d" means "a single
digit" and "\d*" means "zero or more digits".
$1 is the part of the pattern that matched what's inside
the parentheses. You can have multiple parentheses. The
first parenthesized match is stored in $1, the second in
$2, and so on. For example:
$phone_number = "212-244-5555";
($area_code, $exchange, $last4) = ($1, $2, $3)
if $phone_number =~ /^(\d+)-(\d+)-(\d+)$/;
In Perl you can put a condition test AFTER a single statement to execute if the condition is true, as I did in
the above example. This has the advantage that you can
omit the parentheses around the condition and the curly
braces around the statement that depends on it, which are
required otherwise.
As for dividing a number repeatedly by 10 as long as it's
greater than 10, I guess that would be the strategy for
extracting the first digit from a number if Perl didn't
have pattern matching. How about this:
$x = 12345;
$x /=10 while $x >= 10;
print "$x\n";
The second line says "divide $x by 10 and store the result
back into $x as long as $x >= 10". There are a couple
problems with this, though. We lose the original value of
$x, if we cared about it, and also when we print out $x at
the end, we don't get the "1" we had hoped for, but 1.2345,
because division in Perl is a floating-point operation.
We can get around that this way:
$x = 12345;
$q = $x; # so original value of $x isn't lost
while ($q >= 10) {
$q = $q / 10;
}
$q = sprintf "%d", $q;
print "$q\n";
Here we just stored $x into another variable $q before we
start dividing. I also wrote the loop and the division in
a more traditional, less "perlish" way. After the loop,
I use the sprintf() function with a "%d" (digit) specification, to truncate $q to integer and then store the
result back into $q. This gives us the "1" we were hoping
for. The "\n" in the print statement just prints a newline
after $q so the cursor goes to the next line.