3

In perl, for numerical comparison, we have +/- inf as numbers that are greater/less than every other number. Are there also strings that are gt/lt any other string?

The reason I ask is that I'd like to tack one or the other on the end of a list of strings to ensure that a loop will terminate before the end of the list.

Ryan C. Thompson
  • 40,856
  • 28
  • 97
  • 159
  • 1
    See http://stackoverflow.com/questions/3258248/ – Jon Purdy Aug 30 '10 at 04:28
  • Based on the answers in that link, I suppose I could write a module that overloads the comparison functions to do what I want when compared with any string. But in practice, I realized the only thing I'm comparing are date strings of the form `YYYYMMDD`, so my "infinite" string is `"99999999"`. I kind of want to write the module now, though. – Ryan C. Thompson Aug 30 '10 at 04:38
  • 1
    Apparently infinity is equal to 99999999. Who knew? – Jon Purdy Aug 30 '10 at 04:41
  • Well, no. I just have to stop using my script in a few thousand years. It's a Y10K bug. – Ryan C. Thompson Aug 30 '10 at 04:47
  • Well, it's another day, and I finally figured out how to rewrite the entire offending block of code in 1/3 the length and 3 times the clarity. Not surprisingly, the newer, shorter, simpler code doesn't require an infinite string or any other silliness. It's a little less efficient (O(n^2) instead of O(n)), but it still does what I need faster than I can start and stop a stopwatch, so who cares? – Ryan C. Thompson Aug 31 '10 at 02:44
  • possible duplicate of [How do I create or test for NaN or infinity in Perl?](http://stackoverflow.com/questions/1185822/how-do-i-create-or-test-for-nan-or-infinity-in-perl) – Ether Oct 04 '10 at 16:20
  • This is not a duplicate of that question. This has nothing do do with numbers. – Ryan C. Thompson Oct 06 '10 at 06:39

3 Answers3

4

No. But "" will be less than or equal to any other string, and chr(~0) repeated sufficient times will be greater than or equal to any string of that length or less. (Assuming you aren't using locale-based collation via 'use locale'.)

(chr(~0) will require no warnings 'utf8', since it's not in the ranges of defined utf8 characters.)

ysth
  • 96,171
  • 6
  • 121
  • 214
  • @Ryan Thompson: ~0 is the one's compliment of 0, the largest integer (and hence the ordinal value of the largest character) perl will use. On 32-bit perls, it will be chr(4294967295), on 64-bit perls, chr(18446744073709551615). – ysth Aug 30 '10 at 05:34
  • You shouldn't need to repeat `chr(~0)` at all. Since it's not a valid codepoint, it shouldn't appear in any real data string in your program. – cjm Aug 30 '10 at 05:51
  • @cjm: it seems a little hypocritical to say "string x is greater than any string in this program" when string x is in the program :) – ysth Aug 30 '10 at 06:28
3

Here's a complete implementation with tests for an overloaded string that's greater than any other string. Its a pretty simple overload, why screw around with approximations?

package String::Infinity;

use overload
    '""'  => sub {
        return "Infinity"
    },
    'cmp' => sub {
        my($left, $right, $reverse) = @_;
        return 0 if ref $right && $right->isa("String::Infinity");
        return $reverse ? -1 : 1;
    },
    fallback => 1
;

sub new {
    my $class = shift;
    return bless \Inf, $class;
}


use Test::More;

my $inf = String::Infinity->new;
is "$inf", "Infinity",  "stringification";
ok $inf eq $inf,        "equals itself"; 
ok $inf ne "foo",       "  doesn't equal anything else";
ok $inf ne "Infinity",  "  even what it stringifies to";
ok $inf gt "lfkdlk",    "  greater than";
ok !$inf lt "lkafj",    "  not less than";
is $inf cmp "lkjd", 1,  "  cmp";
is "ldfjal;kjd" cmp $inf, -1,   "  cmp reversed";

done_testing;
Schwern
  • 153,029
  • 25
  • 195
  • 336
  • Why? Because I'm not (yet) enough of a perl guru to have experience writing classes that overload operators. That's pretty neat, though. – Ryan C. Thompson Aug 31 '10 at 02:45
2

The empty string or undef is less than every other string.

There is no finite string that is greater than every other string. But if you can make certain assumptions like all of the strings in your loop are ASCII strings, you could specify a string like "\x80" (ASCII value 128) that would be greater than all of your strings.

mob
  • 117,087
  • 18
  • 149
  • 283