Je suis désolé de poser une question aussi fondamentale, mais j'ai cherché une solution et je ne semble pas pouvoir en trouver une qui ait du sens.

Essentiellement, j'essaie d'écrire une méthode Ruby qui renvoie la dernière valeur d'une liste (chaîne ou tableau). Voici mon code:

def last(x)
x[-1]
end

Il produit en fait les résultats que je souhaite, mais me donne l'erreur suivante:

`last': wrong number of arguments (given 5, expected 1) (ArgumentError)

J'ai essayé d'ajouter simplement un caractère générique à mon argument attendu, comme ceci:

def last(*x)
x[-1]
end

Cela génère simplement toutes les valeurs au lieu de la dernière. Quelqu'un a des idées où je me trompe? Encore une fois, désolé pour la question de base.

0
Freddy 25 janv. 2017 à 08:11

4 réponses

Meilleure réponse

Lorsque vous appelez votre méthode, vous devez lui transmettre un seul tableau. Je suppose que vous lui passez plusieurs éléments à la place.

>> last(1,2,3,4,5)
ArgumentError: wrong number of arguments (5 for 1)
>> last([1,2,3,4,5])
=> 5
1
moveson 25 janv. 2017 à 06:26

Il semble que vous souhaitiez pouvoir utiliser ces deux manières différentes:

last(:a, :b, :c)
last(my_list_type)

Le moyen le plus simple d'y parvenir serait de "splater" les arguments, puis de vérifier le nombre d'éléments qui vous ont été fournis. Par exemple:

def last(*args)
  return args[-1] if args.length > 1
  return args[0][-1] if args.length == 1 && args[0].respond_to?(:length)
  args[0] # because we have been given nothing, or a single, non-list-type item
end

Notez les utilisations suivantes - cela peut être ou non ce que vous vouliez, mais cela devrait vous donner un bon point de départ:

last 1,2,3          #=> 3
last [4,5,6]        #=> 6
last 1              #=> 1
last "1"            #=> "1"
last "123"          #=> "3"
last "123", "456"   #=> "456"
last                #=> nil
last []             #=> nil
0
user208769 25 janv. 2017 à 12:32

La documentation pertinente est ici.

Le "joker" est appelé "opérateur splat".

J'espère que ce code le rend plus clair:

def last_element_in_array(array) # <-- There must be exactly one parameter
  array[-1]
end

def last_parameter(*parameters) # <-- Any number of parameters
  parameters[-1]
end

p last_element_in_array([1, 2, 3, 4, 5])
#=> 5
p last_parameter(1, 2, 3, 4, 5)
#=> 5
p last_parameter
#=> nil
p last_parameter([1, 2, 3, 4, 5]) # <-- Only one parameter : an array with 5 elements
#=> [1, 2, 3, 4, 5]
p last_element_in_array(1, 2, 3, 4, 5) # <-- Too many parameters. There should be only 1, and it should be an Array.
#=> in `last_element_in_array': wrong number of arguments (given 5, expected 1) (ArgumentError)
0
Eric Duminil 25 janv. 2017 à 09:29

Le .last allready est une méthode pour les collections comme un Array. Mais je pense que je vois ce que vous voulez, une méthode générique pour Array et String. et il doit être capable d'accepter à la fois un certain nombre d'arguments (tableau d'arguments) ainsi qu'un tableau lui-même.

Si vous étudiez les résultats ci-dessous, vous voyez ce qui ne va pas avec les différentes versions. Vous devrez ajouter la méthode .last à String mais vous rencontrez toujours des problèmes lorsque vous passez un tableau, alors jetez un œil à la dernière solution. Il aplatit d'abord tous les tableaux et donne l'élément .last, puis il regarde la classe du dernier élément, au cas où il s'agirait d'une chaîne, il [-1] renvoie le dernier caractère, sinon juste le nombre Arguments autres que String ou Array qui ne 't support .last donnera toujours une erreur. J'exécute ceci depuis mon éditeur, pas irb donc j'utilise p ici pour faire un débogage simple. Pourquoi p au lieu de met? Parce qu'il inspecte un objet et imprime des tableaux sur une seule ligne.

La construction [__LINE__] consiste à imprimer le numéro de ligne pour voir les résultats que vous voyez Je les ai laissés en place pour que vous puissiez essayer cette technique de débogage simple.

Vous feriez mieux d'appeler cette méthode autrement (par exemple last_of) pour éviter les confusions avec la méthode .last dans certaines classes.

p [__LINE__,[1, 2, 3].last] # 3

def last(x)
  x[-1]
end

p [__LINE__,last([1, 2, 3])] # 3
#p last(1, 2, 3) # wrong number of arguments (3 for 1) (ArgumentError)
p [__LINE__, last("a string")] # g

def last(*x)
    p [__LINE__, x] 
  x[-1]
end

p [__LINE__, last([1, 2, 3])] # [1, 2, 3]
p [__LINE__, last(1, 2, 3)] # 3
p [__LINE__, last("a string")] # "a string"

def last *x
    e = x.flatten.last # flatten any Arrays 
    case e
      when String 
        e[-1]
      when Fixnum
        e
    end
end

p [__LINE__, last([1, 2, 3])] # 3
p [__LINE__, last(1, 2, 3)] # 3
p [__LINE__, last("a string")] # "g"
p [__LINE__, last(["a string"])] # "g"
0
peter 25 janv. 2017 à 09:51