Ricorsione e "stack level too deep"

Salve,

stavo cercando di scrivere una semplice funzione che ricorsivamente
stampi tutti i file presenti in una cartella e nelle sue
sottocartelle, definita nel seguente modo:

def walk_dir(dir)
Dir.foreach(dir) do |file|
if File.directory?(file)
walk_dir(file)
else
puts “file -> #{file}”
end
end
end

dir = “C:/Appoggio/ruby”
walk_dir(dir)

Ora, quando eseguo lo script, mi restituisce:

dir_walk.rb:16:in walk_dir': stack level too deep (SystemStackError) from dir_walk.rb:18:inwalk_dir’
from dir_walk.rb:16:in foreach' from dir_walk.rb:16:inwalk_dir’
from dir_walk.rb:18:in walk_dir' from dir_walk.rb:16:inforeach’
from dir_walk.rb:16:in walk_dir' from dir_walk.rb:18:inwalk_dir’
from dir_walk.rb:16:in `foreach’
… 1270 levels…

C’è qualche escamotage? Sbaglio qualcosa io?

TIA,

— Marco Dalla S. [email protected]
wrote:

Salve,

stavo cercando di scrivere una semplice funzione che
ricorsivamente
stampi tutti i file presenti in una cartella e nelle
sue
sottocartelle, definita nel seguente modo:

credo che Dir[‘**/*’] farebbe al caso tuo (globbing in
stile zsh)

dir = “C:/Appoggio/ruby”
from dir_walk.rb:16:in foreach' from dir_walk.rb:16:in walk_dir’
from dir_walk.rb:18:in walk_dir' from dir_walk.rb:16:in foreach’
… 1270 levels…

C’è qualche escamotage? Sbaglio qualcosa io?

quando hai uno stack overflow a causa di una funzione
ricorsiva l’approccio standard è srotolare la
ricorsione e gestire lo stack a mano. Quindi invece di
avere

def foo(a)
val = fai_cose(a)
foo(val)
end

la fai diventare

def foo(a)
stack=[a]
while tmp = stack.pop
stack.push( fai_cose(tmp) )
end
end

o una cosa del genere :slight_smile:
Ma nel tuo caso, ripeto, non ne hai bisogno perché
esistono già funzioni equivalenti a os.walk.

PS
e yarv ha la TCO :smiley:

  ___________________________________________________________

Yahoo! Mail is the world’s favourite email. Don’t settle for less, sign
up for
your free account today
http://uk.rd.yahoo.com/evt=44106/*http://uk.docs.yahoo.com/mail/winter07.html

Non sono pratico di windows ma direi che al 99,999999% il problema è
che tu non scarti dalla ricorsione le directory speciali . e …
Finisci in una ricorsione infinita che ti satura lo stack.

A parte questo ci sono modi migliori per fare quello che vorresti,
come ti hanno fatto notare.

2007/5/29, Marco Dalla S. [email protected]:

Il 29/05/07, gabriele renzi[email protected] ha scritto:

la fai diventare

def foo(a)
stack=[a]
while tmp = stack.pop
stack.push( fai_cose(tmp) )
end
end

o una cosa del genere :slight_smile:

Grazie della dritta, magari la userò in qualche altro contesto, perché
come dici più avanti:

Ma nel tuo caso, ripeto, non ne hai bisogno perché
esistono già funzioni equivalenti a os.walk.

Ho usato il modulo Find e funziona correttamente senza dover ricorrere
alle ricorsioni. :slight_smile:

PS
e yarv ha la TCO :smiley:

Molto interessante! Attendo in trepida attesa. :smiley:

Grazie,

Il 29/05/07, Federico G.[email protected] ha scritto:

Non sono pratico di windows ma direi che al 99,999999% il problema è
che tu non scarti dalla ricorsione le directory speciali . e …
Finisci in una ricorsione infinita che ti satura lo stack.

Hai ragione, in effetti non avevo pensato a . e …! Che pirla… :\

Grazie,

Gli errori banali sono sempre i più difficili da trovare …

Il 29/05/07, Marco Dalla S.[email protected] ha scritto: