0

I wrote the following program to test Perl's ability to evaluate ASCII values, and its if / elsif statements.

I want to avoid using the language's sort function.

#test ASCII values using if and elsif
$s = '4';
$j = 'a';
$k = "AS";

#1st print the variable with the lowest ASCII value
if ($s <= $j && $s <= $k) {
    say $s;
    $s = 1000;
} elsif ($j <= $s && $j <= $k) {
    say $j;
    $j = 1000;
} elsif ($k <= $j && $k <= $s) {
    say $k;
    $k = 1000;
}

#print the variable with the 2nd lowest value
if ($s <= $j && $s <= $k) {
    say $s;
    $s = 1000;
} elsif ($j <= $s && $j <= $k) {
    say $j;
    $j = 1000;
} elsif ($k <= $j && $k <= $s) {
    say $k;
    $k = 1000;
}

#print the variable with the 3nd lowest value
if ($s <= $j && $s <= $k) {
    say $s;
    $s = 1000;
} elsif ($j <= $s && $j <= $k) {
    say $j;
    $j = 1000;
} elsif ($k <= $j && $k <= $s) {
    say $k;
    $k = 1000;
}

My output is as follows:

52
97
65
a
AS
4

but the correct outcome is:

52
97
65
4
AS
a

Thank you in advance. Tips on how to improve my question writing are welcome.

Michael Albers
  • 3,721
  • 3
  • 21
  • 32
Alexander McNulty
  • 870
  • 1
  • 11
  • 19
  • 6
    Turn on strict and warnings and you'll see that you're trying to do numeric comparisons on non-numeric characters. So, "use strict;" and "use warnings;" and declare your vars as "my $s; " etc. Then when you run it you'll see the warnings. Checkout perldoc perlop for comparison operators. – jmcneirney Oct 18 '16 at 22:39
  • 4
    I'm confused. Where do `52`, `97`, and `65` come from? They are the ordinal values of the first character of your inputs `4`, `a`, and `AS`, but I don't see where you compute them. Anyway, Perl has two sets of comparison operators. `<`, `<=`, `==`, `!=`, `>`, `>=`, `<=>` for numerical comparison, and `lt`, `le`, `eq`, `ne`, `ge`, `gt`, `cmp` for lexical (string) comparison. See [`perldoc perlop`](http://metacpan.org/pod/perlop). – mob Oct 18 '16 at 22:39
  • 1
    In other words, if you wish to get ASCII (and compute with it, by using `==, <, >` operators), you need to convert the strings. You can do that with `ord` or `unpack`, for example. (And it seems that you have done that somehow since you show that in "output" -- so _show complete examples_.) While Perl does allow us to store either a number or a string in a scalar variable, when it comes to using them you can't always expect things to just work regardless. – zdim Oct 18 '16 at 22:44
  • // , You have asked a good question, Mr. McNulty. Welcome to the misery! Please consider showing us some of the research you've already done on this topic, and applying Tim Bunce's answer to a question about "linting", here, to the code example you have so helpfully provided us: http://stackoverflow.com/a/27133639/2146138 – Nathan Basanese Oct 19 '16 at 01:16
  • 1
    The code you show won't even compile, as you haven't defined `say` anywhere. Once that is fixed the output is `a`, `AS`, `4` and not the text that you show. We can't possibly help you unless you explain your problem accurately. – Borodin Oct 19 '16 at 12:35

2 Answers2

0

Always use use strict; use warnings;! The latter would have told you that you were using numerical comparison operators (e.g. <) where you should be using string comparison operators (e.g. lt).

But you could simply use the following:

say for sort $s, $j, $k;
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Yes, your are correct. Thank you, and thanks to the other folks as well. I was using numerical comparisons when I should have been using string comparisons. – Alexander McNulty Oct 21 '16 at 06:12
0

You want to use the ord function to obtain the numeric value of the first character of the argument. This is per-character, not per-byte, which means that Unicode works correctly. http://perldoc.perl.org/functions/ord.html for more information.

sjcaged
  • 649
  • 6
  • 25