2010-10-06 5 views
2

J'ai rencontré un problème étrange avec Ruby que je ne peux pas expliquer. Je le script suivant qui prend tout le code est actuellement dans le presse-papiers, l'exécute par une coloration syntaxique, met alors la nouvelle version de nouveau dans le presse-papiers:"ruby script.rb" contre "xterm -e ruby ​​script.rb"

#!/usr/bin/ruby1.9.1 

require 'coderay' 

language = "auto"; 
if(ARGV.length > 0) 
    language = ARGV[0]; 
end 

print("Using language: #{language} \n"); 

codeToHighlight = `xsel --clipboard` 

highlightedCode = CodeRay.scan(codeToHighlight, language.intern()).div 

IO.popen("xsel --clipboard", mode='w') do |io| 
    io.write highlightedCode 
    io.flush 
end 

La partie étrange est que si je le lance directement dans un terminal, ça fonctionne bien. Si je l'exécute via "xterm -e", cela ne fonctionne pas. J'ai trouvé ce fil sur un autre site qui a posé la même question, mais la personne n'a jamais eu de réponse: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/138423

Cette personne a constaté que si, comme si ... ils ont ajouté une pause à la fin du script

10000.times do 
    puts "" 
end 

... cela fonctionne. Pourquoi est-ce? Y'a t'il un moyen d'arranger cela? J'ai essayé de réécrire le script de sorte que le popen retourne un objet IO et que je puisse appeler manuellement close, mais cela ne fait pas de différence.

+1

J'ai déterminé que, quel que soit le problème, il est dans xsel. J'ai essayé d'ajouter une ligne à la fin du fichier (sans la boucle folle puts "") qui saute juste le code en surbrillance dans un fichier, et son contenu est correct peu importe _how_ Je cours le script. J'ai essayé xclip à la place et il semble fonctionner dans plus de situations, bien que je n'ai jamais eu que le presse-papier primaire (aka, clic du milieu) pour travailler avec elle. xclip fonctionne quand il est appelé depuis un autre script où xsel ne le ferait pas, mais xclip ne fonctionne toujours pas non plus via xterm -e. – Matthew

Répondre

1

Que diriez-vous si vous l'exécutez avec gnome-terminal -e au lieu de xterm -e?

MISE À JOUR:

OK, voici ma meilleure estimation. Vous savez comment si vous envoyez un programme de terminal à l'arrière-plan (soit avec & après la commande ou avec ctl-z) et puis vous fermez le terminal, il tue le programme, non? Eh bien, xsel forks un processus fils pour écrire dans le presse-papiers, mais il doit être tué quand le script de l'encapsuleur ruby ​​se termine et que xterm se ferme. Cela expliquerait pourquoi la pause à la fin lui permet de fonctionner - cela donne juste assez de temps pour que le processus fils se termine avant que le terminal ne se ferme. Il explique également pourquoi il fonctionne lorsqu'il est exécuté manuellement - vous laissez le terminal ouvert suffisamment longtemps pour que le processus fils finisse. Essayez d'ajouter l'option -n à votre commande xsel, et je parie que cela fonctionne. -n empêche xsel de forking.

+0

Non, cela ne semble pas fonctionner non plus ... avec xclip _ou_ avec xsel. Merci quand même. J'utilise rarement ce script, donc ce n'est pas un gros problème, mais il serait bon de savoir pourquoi il le fait juste pour le savoir. – Matthew

+0

ah, shucks. Mon idée était peut-être que c'était un problème avec l'émulateur de terminal et que vous pouviez ouvrir gnome-terminal en l'exécutant manuellement. – James

+0

J'ai mis à jour ma réponse, puisque j'ai juste eu une révélation. – James