[Purdue-pm] Perl 5's '{' .. '~' "broken"

Mark Senn mark at purdue.edu
Fri Oct 5 10:10:55 PDT 2018


#!/usr/new/bin/perl

# In Perl 5
#     my @s = ('{'..'~', 'a'..'c');
#     print "@s\n";
# prints
#     { a b c
# instead of
#     { | } ~ a b c
#
# _Modern Perl: 2011--2012_ edition at
#     http://modernperlbooks.com/books/modern_perl/chapter_04.html
# states
#     The infix range operator (..) produces a list of items in list context:
#         my @cards = ( 2 .. 10, 'J', 'Q', 'K', 'A' );
#     It can produce simple, incrementing ranges (both as integers or strings),
# but it cannot intuit patterns or more complex ranges.
#
# Apparently '{'..'~' is a range that Perl 5 does not understand.
#

# I needed a way to get the ordinal character values (a is 65, b is 66, etc.)
# for some character ranges and came up with the following.  Let me know if
# you have any improvements.

use feature 'say';

sub Ranges
{
    # The return value.
    my @r = ();

    (@_ == 0)  and  die 'Ranges called with no arguments';
    
    (@_ % 2)  and  die 'Ranges called with an odd number of arguements';

    # Process a character range.
    for (my $i = 0;  $i < @_;  $i += 2)
    {
        push @r, (ord $_[$i] .. ord $_[$i+1]);
    }

    return @r;
}

my @a = Ranges qw+{ ~    a c+;
say "\@a is @a";

my @b = Ranges qw+A Z    a z+;
say "\@b is @b";

my @c = Ranges qw+! /    0 9    : @    [ `    { ~+;
say "\@c is @c";

my @d = Ranges qw+0 9    A Z    a z+;
say "\@d is @d";

# -mark


More information about the Purdue-pm mailing list