2009-08-12 11 views
1

connexes/double possible: Why do I get "uninitialized value" warnings when I use Date::Manip's sortByLength?Pourquoi est-ce que j'obtiens des avertissements de "valeur non initialisée" quand j'utilise UnixDate de Date :: Manip dans un bloc de tri?

Ce bloc de code:

my @sorted_models = sort { 
    UnixDate($a->{'year'}, "%o") <=> 
    UnixDate($b->{'year'}, "%o") 
} values %{$args{car_models}}; 

gardé générer l'avertissement d'erreur suivante:

 
Use of uninitialized value in length at /.../Date/Manip.pm line 244. 

Date::Manip est un module CPAN. Et la ligne 244 de Date :: Manip se trouve dans le bloc de code suivant:

# Get rid of a problem with old versions of perl 
no strict "vars"; 
# This sorts from longest to shortest element 
sub sortByLength { 
    return (length $b <=> length $a); 
} 
use strict "vars"; 

Mais y compris cette (impression de la valeur de date Unix réelle à la console dans l'enregistreur) avant que le bloc de code pour trier les valeurs:

foreach (values %{$args{car_models}}) { 
    $g_logger->info(UnixDate($_->{'year'},"%o")); 
} 

enlevé les avertissements des erreurs entièrement. Pourquoi? Et qu'est-ce qu'une bonne solution au lieu de faire toutes ces déclarations de journalisation? REMARQUE: Aucune des valeurs triées n'est indéfinie car lorsque je les ai imprimées dans l'enregistreur, je pouvais voir que chacune d'entre elles avait une valeur numérique.

+0

Pouvez-vous mettre votre instruction de journalisation dans le bloc de tri pour voir les valeurs réelles de $ a et $ b? – zakovyrya

+0

Comment je fais ça? – Kys

+0

Aussi je ne voudrais pas toucher n'importe quel code dans le module CPAN – Kys

Répondre

-3

J'ajouté cette ligne de code pour vider mes données:

my @sorted_models = sort { $g_logger->info(Dumper{a=>$a,b=>$b}); 
         UnixDate($a->{'year'}, "%o") <=> 
         UnixDate($b->{'year'}, "%o"); } 
         values %{$args{car_models}}; 

j'ai pu vider $ a et $ b UNE FOIS, alors je suis l'erreur comme> 50 fois, suivie d'une décharge de $ a et $ b pendant environ 20 fois (j'ai 10 éléments dans mon tableau)

+0

Attendez, ce n'est pas une réponse. Je voulais l'écrire comme commentaire. – Kys

-2

Quelque chose ne va pas avec Date :: Manip dans la façon dont il localise les variables spéciales. Essayez d'appeler Date_Init() avant de trier. Il semble résoudre le problème:

use strict; 
use warnings; 

use Data::Dumper; 
use Date::Manip qw(UnixDate Date_Init); 
my $cars_ref = { 
    mazda => {model => 'mazda', year => '2008' }, 
    toyota => {model => 'toyota', year => '2001' }, 
    mitsu => {model => 'mitsu', year => '2005' } 
}; 

Date_Init(); # Initialize Date::Manip first! 

my @models = 
    sort { 
    UnixDate($a->{year}, '%o') <=> UnixDate($b->{year}, '%o'); 
    } values %$cars_ref; 
print Dumper \@models; 

Sortie:

$VAR1 = [ 
      { 
      'model' => 'toyota', 
      'year' => '2001' 
      }, 
      { 
      'model' => 'mitsu', 
      'year' => '2005' 
      }, 
      { 
      'model' => 'mazda', 
      'year' => '2008' 
      } 
     ]; 
+3

Une vraie question est pourquoi quelqu'un voudrait cartographier les années ci-dessus à travers 'UnixDate' pour trier. –

+1

En outre, l'omission de l'appel 'Date_Init()' ci-dessus ne donne pas lieu à des avertissements de valeur non initialisés. Sous Windows, il vomit car il n'arrive pas à comprendre le fuseau horaire. La définition de 'TZ' dans le shell corrige cela. Sous Linux, le code ci-dessus fonctionne correctement sans le 'Date_Init()'. Donc, votre réponse ne semble pas être liée au problème du PO. –

+0

Pourquoi personne ne voudrait cartographier les années ci-dessus à travers UnixDate pour trier? – Kys

1

Je vais essayer une dernière fois de répondre aussi clairement que possible.

Tout d'abord, si tous les horodatages comme 2008-08-07T22:31:06Z, il n'y a pas besoin de les cartographier à travers UnixDate comme sort standard en utilisant cmp les classera correctement.

#!/usr/bin/perl 

use strict; 
use warnings; 

use Data::Dumper; 
use Date::Manip; 

my %args = (
    car_models => { 
     a => { year => '2009-08-07T22:31:06Z' }, 
     b => { year => '2008-08-07T23:31:06Z' }, 
     c => { year => '2008-08-07T21:31:06Z' }, 
    }, 
); 

my @sorted_cmp = sort { 
    $a->{year} cmp $b->{year} 
} values %{ $args{car_models}}; 

print "Sorted *without* using UnixDate:\n"; 
print Dumper \@sorted_cmp; 

my @sorted_dm = sort { 
    UnixDate($a->{year}, '%o') <=> UnixDate($b->{year}, '%o') 
} values %{ $args{car_models}}; 

print "Sorted using UnixDate:\n"; 
print Dumper \@sorted_dm; 

sortie (après la mise en TZcmd pour amadouer Date::Manip):

 
C:\Temp> cars 
Sorted *without* using UnixDate: 
$VAR1 = [ 
      { 
      'year' => '2008-08-07T21:31:06Z' 
      }, 
      { 
      'year' => '2008-08-07T23:31:06Z' 
      }, 
      { 
      'year' => '2009-08-07T22:31:06Z' 
      } 
     ]; 
Sorted using UnixDate: 
$VAR1 = [ 
      { 
      'year' => '2008-08-07T21:31:06Z' 
      }, 
      { 
      'year' => '2008-08-07T23:31:06Z' 
      }, 
      { 
      'year' => '2009-08-07T22:31:06Z' 
      } 
     ]; 

Aucun avertissement, aucune erreur ... Ergo, tout ce que vous avez mis sur cette page un grand désordre d'un hareng rouge. En outre, cela n'explique toujours pas d'où vient le 1249998666 en your other question.

+0

H-ha, c'est facile.Il a mis un horodatage unix (produit de UnixDate) dans un tableau de références supposées de hachage de données automobiles et plus tard il a essayé de les utiliser comme s'il s'agissait de références de hachage: push (@not_sorted_models, UnixDate ($ _-> {'year'} , "% o")); d'où l'erreur Impossible d'utiliser chaîne ("1249998666") comme un HASH ref – zakovyrya

+1

@zakovyrya précisément pourquoi j'ai demandé à l'OP de montrer les structures de données réelles et le code qu'il utilise et d'essayer de décourager les autres d'aller sur un sauvage goose poursuite avec les fragments qu'il a postés dans trois questions distinctes jusqu'à présent. –

+0

@Sinan Ünür: Parfois, ça ajoute à l'amusement :) N'est-ce pas le but de ce site? – zakovyrya