Based on the discussion Re^2: curious behavior: why does it do this?, I reported bug #133695, where I just posted some patches. One of them explains the behavior in Perls up to v5.30 of the range operator when its operands are strings:
The range operator in list context can make use of the magical auto-increment algorithm if both operands are strings, subject to the following rules:
With one exception (below), if both strings look like numbers to Perl, the magic increment will not be applied, and the strings will be treated as numbers (more specifically, integers) instead.
For example, "-2".."2" is the same as -2..2, "1".."-1" is the same as 1..-1 (producing the empty list), and "2.18".."3.14" produces 2, 3.
The exception to the above rule is when the left-hand string begins with 0, including the string "0" itself. In this case, the magic increment will be applied, even though strings like "01" would normally look like a number to Perl.
For example, "01".."04" produces "01", "02", "03", "04", and "0".."-1" produces "0" through "99" - this may seem surprising, but see the following rules for why it works this way. To get dates with leading zeros, you can say:
@z2 = ("01" .. "31"); print $z2[$mday];If you want to force strings to be interpreted as numbers, you could say
@numbers = ( 0+$first .. 0+$last );If the initial value specified isn't part of a magical increment sequence (that is, a non-empty string matching /^[a-zA-Z]*[0-9]*\z/), only the initial value will be returned.
For example, "ax".."az" produces "ax", "ay", "az", but "*x".."az" produces only "*x".
For other initial values that are strings that do follow the rules of the magical increment, the corresponding sequence will be returned.
For example, you can say
@alphabet = ("A" .. "Z");to get all normal letters of the English alphabet, or
$hexdigit = (0 .. 9, "a" .. "f")[$num & 15];to get a hexadecimal digit.
If the final value specified is not in the sequence that the magical increment would produce, the sequence goes until the next value would be longer than the final value specified. If the length of the final string is shorter than the first, the empty list is returned.
For example, "a".."--" is the same as "a".."zz", "0".."xx" produces "0" through "99", and "aaa".."--" returns the empty list.
However, in case one of my patches gets accepted, it would change "0".."-1" from returning "0".."99" to returning the empty list, which would be consistent with 0..-1. In any case, the patches include the corresponding documentation, so hopefully perlop will get an update.
Update 2019-08-27: As of Perl 5.32, the behavior has changed to the following (changes underlined):
The range operator in list context can make use of the magical auto-increment algorithm if both operands are strings, subject to the following rules:
With one exception (below), if both strings look like numbers to Perl, the magic increment will not be applied, and the strings will be treated as numbers (more specifically, integers) instead.
For example, "-2".."2" is the same as -2..2, and "2.18".."3.14" produces 2, 3.
The exception to the above rule is when the left-hand string begins with 0 and is longer than one character, in this case the magic increment will be applied, even though strings like "01" would normally look like a number to Perl.
For example, "01".."04" produces "01", "02", "03", "04", and "00".."-1" produces "00" through "99" - this may seem surprising, but see the following rules for why it works this way. To get dates with leading zeros, you can say:
@z2 = ("01" .. "31"); print $z2[$mday];If you want to force strings to be interpreted as numbers, you could say
@numbers = ( 0+$first .. 0+$last );If the initial value specified isn't part of a magical increment sequence (that is, a non-empty string matching /^[a-zA-Z]*[0-9]*\z/), only the initial value will be returned.
For example, "ax".."az" produces "ax", "ay", "az", but "*x".."az" produces only "*x".
For other initial values that are strings that do follow the rules of the magical increment, the corresponding sequence will be returned.
For example, you can say
@alphabet = ("A" .. "Z");to get all normal letters of the English alphabet, or
$hexdigit = (0 .. 9, "a" .. "f")[$num & 15];to get a hexadecimal digit.
If the final value specified is not in the sequence that the magical increment would produce, the sequence goes until the next value would be longer than the final value specified. If the length of the final string is shorter than the first, the empty list is returned.
For example, "a".."--" is the same as "a".."zz", "0".."xx" produces "0" through "99", and "aaa".."--" returns the empty list.
In reply to Re: curious behavior: why does it do this? (updated!)
by haukex
in thread curious behavior: why does it do this?
by perl-diddler
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |