2009-06-29 21 views
5

Dies ist eine neue Frage, wie ich versuche, Ruby von mir selbst zu lernen, also Entschuldigung, wenn es wie eine dumme Frage klingt!Ruby kann nicht verwendet werden

ich durch die Beispiele lese, warum (ergreifende) Einführung in Ruby und ist in Kapitel 4. Ich tippte die code_words Hash in eine Datei mit dem Namen wordlist.rb

ich eine andere Datei geöffnet und tippte die erste Zeile als require 'wordlist.rb' und den Rest des Codes, wie unten

#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 

Wenn ich diesen Code ausführen, ist es mit der folgenden Fehlermeldung fehlschlägt:

C:/MyCode/MyRubyCode/filecoder. rb: 5: undefin ed lokale Variable oder Methode `code_words' für Haupt: Object (Nameerror)

Ich verwende Windows XP und Ruby-Version Rubin 1.8.6

Ich weiß, sollte ich so etwas wie ein ClassPath, aber nicht sicher sein Einstellung wo/wie geht das?

Vielen Dank im Voraus!

Antwort

1

Ich denke, das Problem könnte sein, dass der Require den Code in einem anderen Kontext ausführt, so dass die Laufzeitvariable nach dem Require nicht mehr verfügbar ist.

Was Sie könnten versuchen, ist es eine konstante machen:

CodeWords = { :real => 'code' } 

, die überall zur Verfügung stehen wird.

Here einige Hintergrundinformationen auf variable Bereiche usw.

5

Während die Top-Level aller Dateien im selben Kontext ausgeführt werden, jede Datei einen eigenen Skript Kontext für lokale Variablen hat. Mit anderen Worten, jede Datei hat ihre eigenen lokalen Variablen, auf die in dieser Datei zugegriffen werden kann, aber nicht in anderen Dateien.

Auf der anderen Seite, Konstanten (CodeWords), globale ($ code_words) und Methoden (def code_words) würde über Dateien zugänglich sein.

Einige Lösungen:

CodeWords = {:real => "code"} 

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

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

Eine OO-Lösung, die für diesen Fall auf jeden Fall zu komplex ist:

# 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

Ein einfacher Weg wäre, verwenden Sie die Marshal.dump Funktion, um die Codewörter zu speichern .

# Save to File 
code_words = { 

'starmonkeys' => 'Phil und Pete, dieser stachelige Kanzler des Neuen Reiches', 'Katapult' => 'Chucky go-go', 'Brandbombe' => 'Wärme-Assisted Living' , 'Nigeria' => "Ny und Jerrys Chemische Reinigung (mit Donuts)", 'dem kabosh Setzen Sie auf' => 'die Kabel-Box auf' }

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

Jetzt zu Beginn der Datei würden Sie dies setzen:

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

Hier ist der einfache Weg, um sicherzustellen, sind Sie immer eine Datei, die als App im selben Verzeichnis ist, setzen Sie diese vor dem

$:.unshift File.dirname(__FILE__) 

$ statement erfordern: ist die globale Variable, die „CLASSPATH“ darstellt

1

Ich schaute nur auf das gleiche Beispiel und hatte das gleiche Problem. Was ich getan habe, war den Variablennamen in beiden Dateien von code_words zu $code_words zu ändern.

Dies würde es zu einer globalen Variable machen und somit durch beide Dateien zugänglich, oder?

Meine Frage ist: wäre das nicht eine einfachere Lösung, als es eine Konstante zu machen und CodeWords = { :real => 'code' } zu schreiben oder gibt es einen Grund, es nicht zu tun?

+0

Mein Gott, es hat funktioniert !! Ich hatte das gleiche Problem (seit ein paar Stunden) und fragte mich, ob ich Codewords zu einer globalen Variable machen könnte. Überlassen Sie es jemandem mit einer Handvoll Punkten, um die klarste, prägnanteste und verständlichste Antwort zu liefern. All dies versucht nicht, eine gegebene Antwort zu entziffern oder zu interpretieren, nur eine direkte, einfache Verwendung der Kürze des Codes. Vielen Dank! ... Hast du Warnsignale für andere Landminen von Why's Poigniant Übungen? – Padawan

+0

Um es zum Laufen zu bringen, musste ich auch 'require' auf 'require_relative' umstellen. Hier ist der Unterschied zwischen den beiden: http://stackoverflow.com/questions/3672586/what-is-the-difference-between-require-relative-and-require-in-ruby – Padawan

Verwandte Themen