Странное поведение рода - PullRequest
7 голосов
/ 09 июля 2010

У меня есть этот фрагмент скрипта:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @arr = (
    {
        name  => 'foo',
        value => 123,
    },
    {
        name  => 'bar',
        value => 'nan',
    },
    {
        name  => 'foobar',
        value => 456,
    },
);

@arr = sort {$a->{value} <=> $b->{value} } @arr;

print Dumper(\@arr);

У меня нет проблем под Windows XP / Strawberry Perl 5.10.1

либо Linux 2.6.12-1 i386 /Perl v5.8.5, созданный для i386-linux-thread-multi,

, но под Linux 2.6.18-53 / Perl v5.8.8, созданный для x86_64-linux-thread-multi, я получил сообщение об ошибке:

Sort subroutine didn't return a numeric value at testsort.pl line 21.

Что не так и как я могу это исправить?

Ответы [ 2 ]

6 голосов
/ 09 июля 2010

В некоторых сборках 'nan' приводится к номеру 0 для сравнения <=>, и сортировка завершается успешно.В других сборках nan обрабатывается как «не число», а возвращаемое значение из <=> не определено.

Для максимальной переносимости, проверьте значение на предмет того, является ли оно хорошим числом не:

(isnan подпрограмма из Как создать или проверить NaN или бесконечность в Perl? ):

sub isnan { ! defined( $_[0] <=> 9**9**9 ) }

@arr = sort { isnan($a->{value}) ? 0 : $a->{value}
                         <=>  
              isnan($b->{value}) ? 0 : $b->{value} }  @arr;
4 голосов
/ 09 июля 2010

2 решения

  1. mobrule решение:

    sub isnan { ! defined( $_[0] <=> 9**9**9 ) }
    @arr = sort { isnan($a->{value}) ? 0 : $a->{value}
                                  <=>  
                  isnan($b->{value}) ? 0 : $b->{value} }  @arr;
    
  2. Решение Perldoc :

    @result = sort { $a <=> $b } grep { $_ == $_ } @input;
    

  1. Дает значение NaN a 0, которое должно подтолкнуть его к началу списка.
  2. Использует преимущество NaN != NaN, чтобы исключить любые NaN s из списка ввода.

Как указано mobrule , это вызвано сравнением NaN между сборками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...