2009-06-29 2 views
5

Ceci est une question débutant que je tente d'apprendre Ruby par moi-même, alors excuses si cela ressemble à une question idiote!Ruby incapable d'utiliser besoin

Je lis à travers les exemples de pourquoi est guide de (poignant) à ruby ​​et je suis au chapitre 4. Je saisi l'code_words Hash dans un fichier appelé wordlist.rb

j'ai ouvert un autre fichier et tapé la première ligne comme require 'wordlist.rb' et le reste du code ci-dessous

#Get evil idea and swap in code 
print "Enter your ideas " 
idea = gets 
code_words.each do |real, code| 
    idea.gsub!(real, code) 
end 

#Save the gibberish to a new file 
print "File encoded, please enter a name to save the file" 
ideas_name = gets.strip 
File::open('idea-' + ideas_name + '.txt', 'w') do |f| 
    f << idea 
end 

Lorsque j'exécute ce code, il échoue avec le message d'erreur suivant:

C:/MyCode/MyRubyCode/filecoder. rb: 5: undefin ed variable locale ou méthode `code_words' pour principal: Object (NameError)

J'utilise la version Windows XP et Ruby 1.8.6

Je sais que je devrais installerai quelque chose comme un ClassPath, mais pas sûr où/comment le faire!

Un grand merci à l'avance!

Répondre

1

Je pense que le problème peut être que le require exécute le code dans un autre contexte, donc la variable d'exécution n'est plus disponible après le require.

Ce que vous pouvez essayer fait une constante:

CodeWords = { :real => 'code' } 

qui sera disponible partout.

Here est des renseignements généraux sur les étendues variables, etc.

5

Alors que le haut niveau de tous les fichiers sont exécutés dans le même contexte, chaque fichier a son propre contexte de script pour les variables locales. En d'autres termes, chaque fichier possède son propre ensemble de variables locales accessibles à travers ce fichier, mais pas dans d'autres fichiers. D'autre part, les constantes (CodeWords), les globals ($ code_words) et les méthodes (def code_words) seraient accessibles à travers les fichiers.

Quelques solutions:

CodeWords = {:real => "code"} 

$code_words = {:real => "code"} 

def code_words 
    {:real => "code"} 
end 

Une solution OO qui est certainement trop complexe pour ce cas:

# first file 
class CodeWords 
    DEFAULT = {:real => "code"} 

    attr_reader :words 
    def initialize(words = nil) 
    @words = words || DEFAULT 
    end 
end 

# second file 
print "Enter your ideas " 
idea = gets 
code_words = CodeWords.new 
code_words.words.each do |real, code| 
    idea.gsub!(real, code) 
end 

#Save the gibberish to a new file 
print "File encoded, please enter a name to save the file" 
ideas_name = gets.strip 
File::open('idea-' + ideas_name + '.txt', 'w') do |f| 
    f << idea 
end 
0

Une façon plus simple serait d'utiliser la fonction Marshal.dump pour enregistrer les mots de code .

# Save to File 
code_words = { 

'starmonkeys' => 'Phil et Pete, ces chanceliers piquantes du Nouveau Reich', 'catapulte' => 'Chucky go-go', 'incendiaire' => 'Living-Assisted Heat' , 'Nigeria' => "Ny et nettoyage à sec Jerry (avec Donuts)", 'Mettre le kabosh sur' => 'Mettre le décodeur sur' }

# Serialize 
f = File.open('codewords','w') 
    Marshal.dump(code_words, f) 
f.close 

maintenant au début de votre fichier que vous mettriez ceci:

# Load the Serialized Data 
code_words = Marshal.load(File.open('codewords','r')) 
0

Voici le moyen facile de vous assurer que vous pouvez toujours inclure un fichier qui se trouve dans le même répertoire que votre application, le mettre avant l'require

$:.unshift File.dirname(__FILE__) 

$: est la variable globale représentant le « CLASSPATH »

1

Je regardais juste le même exemple et j'avais le même problème. Ce que j'ai fait était de changer le nom de la variable dans les deux fichiers de code_words à $code_words.

Cela en ferait une variable globale et donc accessible par les deux fichiers?

Ma question est: ne serait-ce pas une solution plus simple que d'en faire une constante et d'avoir à écrire CodeWords = { :real => 'code' } ou y at-il une raison de ne pas le faire?

+0

Mon Dieu ça a marché !! J'étais sur le même problème (depuis quelques heures maintenant) et je me demandais la même chose, juste en faisant de code_words une variable globale. Laissez à quelqu'un avec une poignée de points de fournir la réponse la plus claire, la plus concise, la plus facile à comprendre. Rien de tout cela essayant de déchiffrer ou d'interpréter une réponse donnée, juste une utilisation simple et directe de la concision du code. Je vous remercie! ... @ raed avez-vous des signes avant-coureurs pour d'autres mines terrestres des exercices de Why's Poigniant? – Padawan

+0

Pour le faire fonctionner, j'ai aussi dû changer 'require' en 'require_relative'. Voici la différence entre les deux: http://stackoverflow.com/questions/3672586/what-is-the-difference-between-require-relative-and-require-in-ruby – Padawan

Questions connexes