7
votes

Déclarations de cas rubis avec plusieurs variables

Ruby a un cas assez puissant. Quelle est la méthode "canonique" de correspondre à des critères contre plusieurs variables sans simplement nidifier affaire ?

Envelopper plusieurs variables dans un tableau (comme [x, y] ) et correspondant à ce qu'elle n'est pas équivalente, car RUBY ne applique pas le cas magique === opérateur aux éléments de la matrice; L'opérateur est appliqué uniquement à la matrice elle-même.

Je vais aller de l'avant et répondre avec une réponse à la communauté-wiki avec un coup de poignard (vaincu) à cette question.


4 commentaires

Autant que je sache, Ruby applique === à chaque élément ... Ideone. com / ymalz


@Nakilon j'ai testé et il ne semble pas l'appliquer de manière récursive. Par exemple, ['Hello', 3] ne correspond pas à [chaîne, 3] .


AAAA ... Désolé, ma faute. Différence oubliée entre == et === .


Je soupçonne que le tableau hérite === à partir de l'objet, le comportement par défaut permet de comparer les valeurs de hachage des deux côtés du test, de ne pas tester le contenu. Si vous souhaitez un test de types et de valeurs, vous devez ajouter === au tableau et mettre en œuvre le comportement souhaité.


4 Réponses :


4
votes

Vous devez utiliser un si..elsif..elift..else et assurez-vous que les variables que vous souhaitez faire correspondre contre apparaissent sur le côté droit du === Opérateur (qui est ce que cas est essentiellement).

Par exemple, si vous souhaitez correspondre à x et y contre certains critères : xxx


0 commentaires

2
votes

Si ce modèle est suffisamment courant dans votre code pour garantir une expression économique, vous pouvez le faire vous-même:

class BiPartite
  attr_reader :x, :y

  def self.[](x, y)
    BiPartite.new(x, y)
  end

  def initialize(x, y)
    @x, @y = x, y
  end

  def ===(other)
    x === other.x && y === other.y
  end
end

....

case BiPartite[x, y]
when BiPartite[SomeType, 1..10]
  puts "some_value"
when BiPartite[:some_symbol, 11..20]
  puts "some_other_value"
end


1 commentaires

+1 Y a-t-il un moyen non dégoûtant de faire ce travail avec un nombre arbitraire de paramètres? En fait, les idées m'appartiennent à l'esprit et n'invimentent pas la modification de la classe de la classe ...



3
votes

Ceci est un moyen simpliste d'ajouter === : xxx


5 commentaires

+1 Ceci est définitivement plus propre que ma deuxième réponse, mais ne modifie pas quelque peu les classes intégrées découragées? C'est une véritable question; Je suis nouveau à Ruby.


En outre, pourquoi faites-vous une copie de autre ? shift affectera le tableau passé comme paramètre sinon? Je suppose que je vais mettre à jour mon exemple pour refléter cela (j'ai déjà volé array.all? , que je ne savais pas ...


Je pense que c'est une matrice de modification sûre de cette façon, puisque le tableau ne met pas en œuvre === . Vous entrez dans des eaux potentiellement dangereuses lorsque vous remplacez une classe de base d'une manière qui enfreint le comportement attendu.


Je suis allé de l'avant et j'ai supprimé ma deuxième réponse. Pour ceux qui étaient curieux, c'était une catégorie correspondant qui implémentée Opérateur === . Un tableau pourrait être transmis à son constructeur avec match.new ([chaîne, 1..10]) , il pourrait donc être utilisé après quand .


NE PAS LES CLASSES COTE DE SINGEY PATCH POUR "COMPIENCEMENT" comme celui-ci, c'est une mauvaise pratique. Au mieux, il est confus aux gens de lire votre code. Au pire, === peut être ajouté à l'avenir, ou quelqu'un d'autre le remplace d'un comportement différent. Si vous voulez vraiment faire cela, enveloppez vos tableaux dans une classe personnalisée qui implémente === (tel que la classe bipartite ci-dessous).



2
votes

Depuis Ruby's Quand Le mot clé prend en charge une liste de valeurs séparées par des virgules, vous pouvez utiliser l'opérateur SPLAT * . Ceci est bien sûr en supposant que vous parlez d'un ensemble de valeurs discrètes dans ou pourrait devenir une matrice.

L'opérateur de splat convertit une liste d'arguments en une matrice, aussi fréquemment observée dans xxx

moins bien connu est le fait qu'il effectue également l'opération inverse - transformant un tableau dans une liste d'arguments.

donc dans ce cas, vous pourriez faire quelque chose comme xxx


1 commentaires

Après avoir réaffecté ceci, je me suis peut-être mave mal lire la question initiale - je pensais que la comparaison était entre une variable et une éventuelle de valeurs correspondantes possibles pour cela.