2010-12-07 23 views
0

Voici le code:Pourquoi l'erreur "L'erreur s'est-elle produite lors de l'évaluation de <=>" lors de l'utilisation de sort_by?

xml = REXML::Document.new(data) 
    @contacts = Array.new 
    xml.elements.each('//entry') do |entry| 
    person = {} 
    person['name'] = entry.elements['title'].text 

    gd_email = entry.elements['gd:email'] 
    person['email'] = gd_email.attributes['address'] if gd_email 

    @contacts << person 
    end 

    @contacts.sort_by { |k| k['name'] } if @contacts[0].size > 0 

l'erreur:

You have a nil object when you didn't expect it! 
You might have expected an instance of Array. 
The error occurred while evaluating nil.<=> 

Répondre

3

Essayez d'utiliser:

person['name'] = entry.elements['title'].text || '' 

au lieu de:

person['name'] = entry.elements['title'].text 
+0

Erreur résolue mais non triée – rtacconi

+0

@rtacconi '# sort_by' ne classe pas le tableau, mais retourne un nouveau tableau trié. Peut-être que vous vouliez dire '@contacts = @ contacts.sort_by ...' – Phrogz

+0

Oui, vous devez, en général, suffixer [array methods] (http://ruby-doc.org/core/classes/Array.html#M002185) avec un '!' pour eux de modifier le tableau actuel. – david4dev

3

pas Si la dernière ligne est

@contacts.sort_by { |k| k['name'] } if @contacts.size > 0 

pas @contacts[0].size?

Également, essayez d'ajouter un @contacts.compact! avant le tri pour vous assurer que vous n'avez aucune valeur nil dans le tableau.

0

Je pense que vous pouvez rationaliser votre code un peu:

@contacts = Array.new 
xml = REXML::Document.new(data) 
xml.elements.each('//entry') do |entry| 
    gd_email = entry.elements['gd:email'] 

    @contacts << { 
    'name' => entry.elements['title'].text, 
    'email' => (gd_email) ? gd_email.attributes['address'] : '' 
    } 
end 

@contacts.sort_by! { |k| k['name'] } 

Je n'ai pas des échantillons de votre XML pour le tester, mais il semble que cela devrait fonctionner. Si le element['title'] est null, vous obtiendrez l'erreur que vous voyez donc vous voudrez soit sauter ces éléments ou utiliser une valeur par défaut pour le champ de nom, comme "inconnu".