# Ricorsione e "stack level too deep"

**URL:** <https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362>\
**Category:** IT\
**Created:** [May 29, 2007, 9:53am UTC](https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362 "2007-05-29T09:53:10Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![marcos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9de0a6/32.png) [@marcos](https://www.ruby-forum.com/u/marcos)\
**Post date:** [May 29, 2007, 9:53am UTC](https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362/1 "2007-05-29T09:53:10Z")

</div>

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:in`walk\_dir’  
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’  
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?

TIA,

---

<div class="post-metadata">

**Author:** ![marcos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9de0a6/32.png) [@marcos](https://www.ruby-forum.com/u/marcos)\
**Post date:** [May 29, 2007, 10:07am UTC](https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362/2 "2007-05-29T10:07:14Z")

</div>

— Marco Dalla S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
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 🙂  
Ma nel tuo caso, ripeto, non ne hai bisogno perché  
esistono già funzioni equivalenti a os.walk.

PS  
e yarv ha la TCO 😃

```
  ___________________________________________________________

```

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](http://uk.rd.yahoo.com/evt=44106/*http://uk.docs.yahoo.com/mail/winter07.html)

---

<div class="post-metadata">

**Author:** ![marcos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9de0a6/32.png) [@marcos](https://www.ruby-forum.com/u/marcos)\
**Post date:** [May 29, 2007, 10:13am UTC](https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362/3 "2007-05-29T10:13:15Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![marcos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9de0a6/32.png) [@marcos](https://www.ruby-forum.com/u/marcos)\
**Post date:** [May 29, 2007, 10:14am UTC](https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362/4 "2007-05-29T10:14:15Z")

</div>

Il 29/05/07, gabriele renzi[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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 🙂

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. 🙂

> PS  
> e yarv ha la TCO 😃

Molto interessante! Attendo in trepida attesa. 😃

Grazie,

---

<div class="post-metadata">

**Author:** ![marcos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9de0a6/32.png) [@marcos](https://www.ruby-forum.com/u/marcos)\
**Post date:** [May 29, 2007, 10:16am UTC](https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362/5 "2007-05-29T10:16:16Z")

</div>

Il 29/05/07, Federico G.[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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,

---

<div class="post-metadata">

**Author:** ![marcos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9de0a6/32.png) [@marcos](https://www.ruby-forum.com/u/marcos)\
**Post date:** [May 29, 2007, 10:21am UTC](https://www.ruby-forum.com/t/ricorsione-e-stack-level-too-deep/105362/6 "2007-05-29T10:21:16Z")

</div>

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

Il 29/05/07, Marco Dalla S.[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) ha scritto:
