2009-06-29 10 views
5

Questa è una domanda newbie, come sto cercando di imparare rubino da solo, quindi mi scuso se suona come una domanda stupida!Rubino in grado di utilizzare richiedere

sto leggendo attraverso gli esempi del perché c'è (toccante) guida di Ruby e sono nel capitolo 4. ho digitato le code_words hash in un file chiamato wordlist.rb

ho aperto un altro file e digitare la prima riga come require 'wordlist.rb' e il resto del codice come di seguito

#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 

Quando eseguo questo codice, non riesce con il seguente messaggio di errore:

C:/mycode/MyRubyCode/filecoder. rb: 5: undefin cato variabile locale o metodo `code_words' per main: Object (NameError)

Io uso Windows XP e Ruby versione ruby ​​1.8.6

So che dovrei essere la creazione qualcosa di simile a un percorso di classe, ma non è sicuro dove/come farlo!

Molte grazie in anticipo!

risposta

1

Credo che il problema potrebbe essere che la richiedono esegue il codice in un altro contesto, quindi la variabile di runtime non è più disponibile dopo la richiedono.

Cosa si potrebbe provare sta rendendo una costante:

CodeWords = { :real => 'code' } 

che sarà disponibile in tutto il mondo.

Here alcuni retroscena sulla validità delle variabili ecc

5

Mentre il primo livello di tutti i file vengono eseguiti nello stesso contesto, ogni file ha un proprio contesto di script per le variabili locali. In altre parole, ogni file ha il proprio insieme di variabili locali a cui è possibile accedere in tutto il file, ma non in altri file.

D'altra parte, costanti (parole di codice), globali ($ code_words) e metodi (DEF code_words) sarebbero accessibili attraverso i file.

Alcune soluzioni:

CodeWords = {:real => "code"} 

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

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

Una soluzione OO che è sicuramente troppo complessa per questo caso:

# 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

Un modo più semplice sarebbe quella di utilizzare la funzione Marshal.dump per salvare le parole in codice .

# Save to File 
code_words = { 

'starmonkeys' => 'Phil e Pete, i cancellieri pungenti del nuovo Reich', 'catapulta' => 'Chucky go-go', 'bomba incendiaria' => 'Living Heat-Assisted' , 'Nigeria' => "Ny e Jerry lavaggio a secco (con ciambelle)", 'Mettere il kabosh su' => 'Mettere il decoder su' }

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

Ora, all'inizio del file si metterebbe questo:

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

Ecco il modo più semplice per assicurarsi che si può sempre includere un file che si trova nella stessa directory di vostra applicazione, mettere questa prima dell'istruzione richiedere

$:.unshift File.dirname(__FILE__) 

$: è la variabile globale che rappresenta il "percorso di classe"

1

Stavo solo guardando lo stesso esempio e stavo avendo lo stesso problema. Quello che ho fatto è stato modificare il nome della variabile in entrambi i file da code_words a $code_words.

Ciò renderebbe una variabile globale e quindi accessibile da entrambi i file, giusto?

La mia domanda è: non sarebbe una soluzione più semplice che renderla una costante e dover scrivere CodeWords = { :real => 'code' } o c'è un motivo per non farlo?

+0

Mio Dio ha funzionato !! Ero sullo stesso problema (da un paio d'ore a questa parte) e mi stavo chiedendo la stessa cosa, solo facendo di code_words una variabile globale. Lascia fare a qualcuno con una manciata di punti per fornire la risposta più chiara, concisa e facile da capire. Niente di tutto questo cerca di decifrare o interpretare una determinata risposta, solo un uso semplice e lineare della brevità del codice. Grazie! ... @ raed hai qualche segnale di avvertimento per altre mine terrestri degli esercizi di Why's Poigniant? – Padawan

+0

Per farlo funzionare, ho anche dovuto cambiare 'require' a 'require_relative'. Ecco la differenza tra i due: http://stackoverflow.com/questions/3672586/what-is-the-difference-tra between-require-relative-and-require-in-ruby – Padawan