2015-12-18 33 views
7

I require un secondo file dal file principale e si desidera tornare da un determinato punto nel secondo file senza uscire dall'intero processo. Il ritorno dovrebbe essere condizionale.È possibile arrestare in modo condizionale Ruby dalla valutazione di un file richiesto senza uscire dall'intero processo?

# file1.rb 
    puts "In file 1" 
    require 'file2' 
    puts "Back in file 1" 

# file2.rb 
    puts "In file 2" 
    # <= A 
    puts "Still in file 2" 

Quando si esegue file1.rb, l'uscita che voglio vedere è:

In file 1 
In file 2 
Back in file 1 

noti che Still in file 2 mai stampe e Back in file 1 fa di stampa. C'è qualcosa che posso fare al punto A per rendere ciò possibile?

non posso usare exit/exit!/abort qui perché Back in file 1 sarà mai stampare. Potrei usare raise/fail, ma per farlo dovrei rescue il fallito require. Spero di trovare un modo che non implichi la modifica di file1.rb.

UPDATE:

A "top-level ritorno" caratteristica has been added.

+0

Penso che non ci sia modo, ma di recente sono stato sorpreso di apprendere che è possibile interrompere l'iterazione del ciclo in modo pulito sollevando 'StopIteration'. Spero che ci sia un trucco simile che si nasconde da qualche parte per questo. –

+0

Potrebbe essere stato fornito un esempio semplificato per illustrare il tuo punto. Potrebbe essere se puoi dirci cosa vuoi ottenere, quindi, potrebbe essere qualcuno che può aiutare meglio. Come minimo, evita qualsiasi [problema XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) –

+0

Non ci sono X o Y qui. Sono abituato a fare in modo che Ruby faccia qualsiasi cosa, e mi sembra strano che non possa farlo. Se è possibile, mi piacerebbe sapere come. –

risposta

0

UPDATE:

Questa funzione has been added.

ORIGINALE:

Commenter matt sottolineato che Caratteristica 4840, che avrebbe fatto esattamente quello che sto chiedendo, has been in discussion since June 2011. Inoltre, la funzione era still being discussed as late as November 2015 nelle riunioni del nucleo centrale relative alle nuove funzionalità di Ruby.

Ci sono molte difficoltà nel progettare una funzione come questa; per un elenco di pro e contro, consiglio vivamente di dare un'occhiata alle discussioni.

La caratteristica proposta consentirebbe di uscire dal file richiesto, mentre utilizzando uno dei seguenti affermazioni di alto livello:

if condition 
    return 
end 

while condition 
    # ... 
    return 
end 

begin 
    # ... 
    return 
rescue 
    # ... 
    return 
ensure 
    # ... 
    return 
end 

e non sarebbe chiudere il file richiesto nelle seguenti affermazioni:

class Foo 
    return # LocalJumpError 
end 

def foo 
    return # returns from method, not from required file 
end 

proc do 
    return # LocalJumpError 
end 

x = -> { return } # returns as from lambda, not from required file 

Poiché la funzione non è stata implementata, ho assegnato la taglia a steenslag per risolvere il problema (come originariamente scritto) alla lettera, se non lo spirito.

1

Io non conosco nessun metodo ufficiale per la rottura di file necessari, soprattutto perché ci sono diversi require metodi (ad esempio, le patch bundler scimmia richiedono)

La soluzione migliore che potessi venire con stava usando rubys flusso di controllo della presa. Non sono sicuro che si sta utilizzando condizionale per determinare se l'esecuzione dovrebbe tornare presto, ma questo dovrebbe essere in grado di far fronte con maggior parte delle situazioni

# file1.rb 
puts "In file 1" 
catch(:done) do 
    require 'file2' end 
puts "Back in file 1" 

# file2.rb 
puts "In file 2" 
throw :done 
puts "Still in file 2" # Never gets called 
+0

Questo funzionerà, nello stesso modo in cui 'raise' /' rescue' funzionerà. Idealmente, tuttavia, nessuna modifica a 'file1.rb' sarebbe necessaria. –

+0

FYI, la funzione "ritorno di livello superiore" [è stata aggiunta] (https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/57132). –

6

Lines sotto __END__will not be executed.

# file2.rb 
puts "In file 2" 
__END__ 
puts "Still in file 2" # Never gets called 
+1

Sì, e anche non verrà analizzato. –

+0

Questa è tecnicamente una risposta corretta al 100% alla domanda che ho scritto, anche se dovevo chiedere un modo per uscire dal file in modo condizionale. Probabilmente assegnerò la taglia a meno che qualcuno non faccia un modo per farlo che permetta condizionali. La risposta che volevo si trova nella discussione @matt linked: https://bugs.ruby-lang.org/issues/4840. –

+0

La funzione "ritorno di livello superiore" [è stata aggiunta] (https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/57132). –

0

È possibile utilizzare un metodo? Analizzerà comunque il metodo ma non verrà eseguito. Qualcosa di simile:

#file1.rb 
    puts "In file 1" 
    require 'file2' 
    puts "Back in file 1" 
    a_method 

#file2.rb 
    puts "In file 2" 
    # <= A 

    def a_method 
    puts "Still in file 2" 
    end