2009-06-29 22 views
5

Jest to pytanie początkujących, ponieważ próbuję nauczyć się Ruby przez siebie, więc przepraszam, jeśli brzmi to jak głupie pytanie!Nie można użyć Ruby

Czytam poprzez przykłady, dlaczego to (przejmujący) Podręcznik do Ruby i jestem w rozdziale 4. Wpisałem code_words Hash do pliku o nazwie wordlist.rb

I otworzył kolejny plik i wpisany jako pierwszy wiersz require 'wordlist.rb' i reszta kodu jak poniżej

#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 

Kiedy wykonać ten kod, to nie z następującym komunikatem o błędzie:

C:/MyCode/MyRubyCode/filecoder. rb: 5: undefin ed zmiennej lokalnej lub metody `code_words' dla głównego: Object (NameError)

używam Windows XP i Ruby Ruby Version 1.8.6

Wiem, że powinienem być ustawienie coś jak ścieżki klasy, ale nie jestem pewien gdzie/jak to zrobić!

Wielkie dzięki z góry!

Odpowiedz

1

Myślę, że problem może polegać na tym, że request wykonuje kod w innym kontekście, więc zmienna środowiska wykonawczego nie jest już dostępna po wymaganiu.

Co można spróbować robi mu Constant:

CodeWords = { :real => 'code' } 

który będzie dostępny wszędzie.

Here pewne tło na zmiennych zakresów itp

5

Chociaż najwyższego poziomu wszystkich plików są wykonywane w tym samym kontekście, każdy plik ma swój własny kontekst skryptu dla zmiennych lokalnych. Innymi słowy, każdy plik ma własny zestaw zmiennych lokalnych, do których można uzyskać dostęp w całym pliku, ale nie w innych plikach.

Z drugiej strony, stałe (CodeWords), globals ($ code_words) i metody (def code_words) będą dostępne dla różnych plików.

Niektóre rozwiązania:

CodeWords = {:real => "code"} 

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

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

Rozwiązanie OO że jest zdecydowanie zbyt skomplikowane dla tego przypadku:

# 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

Prostszym sposobem byłoby użyć funkcji Marshal.dump do zapisania słów kodowych .

# Save to File 
code_words = { 

'starmonkeys' => 'Phil i Pete te kolczaste kanclerze Nowej Rzeszy', 'katapulta' => 'Chucky Go-Go', 'Firebomb' => 'Heat-Assisted Living' , 'Nigeria' => "Ny i Jerry pralnia chemiczna (z Donuts)" 'Włóż kabosh na' => 'Put dekodera na' }

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

teraz na początku listy plik można umieścić to:

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

Oto prosty sposób, aby upewnić się, że zawsze można dołączyć plik, który znajduje się w tym samym katalogu, co plik aplikacji, umieścić to przed stwierdzeniem wymagają

$:.unshift File.dirname(__FILE__) 

$: jest zmienna globalna reprezentujący „CLASSPATH”

1

Właśnie patrzyłem na ten sam przykład i miałem ten sam problem. Zmieniłem nazwę zmiennej w obu plikach z code_words na $code_words.

Czy zmienna globalna byłaby dostępna w obu plikach?

Moje pytanie brzmi: czy nie byłoby to prostsze rozwiązanie niż uczynienie go stałym i konieczności pisania CodeWords = { :real => 'code' }, czy jest jakiś powód, aby tego nie robić?

+0

Mój Boże, zadziałało !! Byłem w tym samym problemie (od kilku godzin) i zastanawiałem się nad tym samym, po prostu czyniąc z code_words zmienną globalną. Zostaw to komuś, kto ma garść punktów, aby zapewnić najwyraźniejszą, najbardziej zwięzłą i najłatwiejszą do zrozumienia odpowiedź. Nic z tego nie próbuje odszyfrować lub zinterpretować danej odpowiedzi, tylko proste, proste użycie zwięzłości kodu. Dziękuję Ci! ... @ raed czy masz jakieś znaki ostrzegawcze dla innych min lądowych ćwiczeń Why's Poigniant? – Padawan

+0

Aby go uruchomić, musiałem również zmienić "require" na "require_relative". Oto różnica między tymi dwoma: http://stackoverflow.com/questions/3672586/what-is-the-difference-between-require-relative-and-require-ruby – Padawan

Powiązane problemy