2009-03-06 1 views
2

Pourquoi cette ligne affiche-t-elle "z" au lieu de "?"Pourquoi le point d'interrogation est-il interprété comme "z" dans Ruby?

$ ruby ​​-e 'met% x [echo # { "?"}]'

Supposons que l'expression dans la # {...} est une variable qui peut avoir la valeur de "?". Comment est-ce que je devrais modifier ce manuscrit de sorte que le point d'interrogation soit sorti au lieu de "z"?

(S'il vous plaît pardonnez le titre de cette question -. Je ne comprends pas encore ce qui se passe ici assez bien pour fournir un titre plus descriptif)

+0

De quel système d'exploitation s'agit-il? Je ne peux pas reproduire sur Windows, je me demande si votre shell fait quelque chose de génial. – AShelly

Répondre

1

Il ne fonctionne pas?

irb(main):001:0> puts %x[echo #{"?"}] 
? 
=> nil 

En utilisant # {} vous donnera la valeur de toutes les variables à l'intérieur - Je ne sais pas pourquoi vous l'utilisez au lieu de

puts %x[echo "?"] 

ou tout simplement

puts '?' 
7

Ce n'est pas du rubis, c'est ta coquille.

De nombreuses coques développent le? caractère pour correspondre à un seul caractère dans les arguments de ligne de commande. Il est utile, si vous avez un tas de fichiers nom Tempa, temp1, tempB, ..., temp9 que vous voulez supprimer, mais vous ne voulez pas supprimer « temple »

% rm temp? 

Alors je m devinant que vous avez un fichier ou un répertoire dans votre répertoire de travail nommé 'z', et le? correspond à cela, donc il est remplacé par le shell.

Normalement, à l'intérieur de guillemets simples (comme votre script ruby), il ne serait pas développé, mais puisque vous passez le point d'interrogation à une commande shell, il est développé ici.

% ruby -e 'puts %x[ echo ? ]' 
z 
% 

Doit vous montrer le même comportement.

De plus, si vous touchez deux autres noms de fichiers de caractère unique comme ABCD, ceux-ci devraient montrer trop:

% touch a b c 
% ruby -e 'puts %x[ echo ? ]' 
a b c z 
% 

Si vous voulez éviter cela lors de l'appel des commandes shell externes à partir de rubis, vous aurez pour échapper à toutes les cordes que vous évanouissez. Dans la plupart des cas, String#inspect devrait permettre une fuite suffisante.