2016-09-25 2 views
0

J'ai un ensemble de noms dans un fichier. J'ai besoin de mettre en place un générateur qui les traverse continuellement. Cependant, le code est suspendu indéfiniment à if (iter.hasNext) après le premier passage.Générateurs circulaires suspendus indéfiniment

Code Gen

var asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt") 

var source: BufferedSource = Source.fromInputStream(asStream) 
var iter: Iterator[String] = Iterator.continually(source.getLines()).flatten 

val genLastName: Gen[String] = { 
    genCannedData 
} 

def genCannedData: Gen[String] = { 
    println("Generating names: " + iter) 
    Gen.delay { 
     if (iter.hasNext) { 
     println("In if") 
     Gen.const(iter.next) 
     } 
     else { 
     println("In else") 
     Gen.const(iter.next) 
     } 
    } 
} 

échantillon d'essai de propriété

property("FirstNames") = { 
    forAll(genLastName) { 
     a => { 
     println(a) 
     a == a 
     } 
    } 
    } 

contenu du fichier en_US_sample.txt

Abbie 
Abby 
Abigail 
Ada 
Adah 

EDIT- Code de travail temporaire

Le code suivant fonctionne si je recréais l'itérateur mais je me demandais pourquoi Iterator.continually est suspendu?

def genCannedData: Gen[String] = { 
    Gen.delay { 
     if (iter.hasNext) { 
     Gen.const(iter.next) 
     } 
     else { 
     asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt") 
     source = Source.fromInputStream(asStream) 
     iter = source.getLines() 
     Gen.const(iter.next) 
     } 
    } 
    } 

Répondre

1

Après la première itération, un itérateur retourné par source.getLines() fausses déclarations pour hasNext, ce qui signifie un itérateur vide. Iterator.continually() d'évaluer continuellement source.getLines() en attendant un prochain itérateur, mais il continue de renvoyer un itérateur vide. Ensuite, il forme une boucle infinie.

+0

Existe-t-il un meilleur moyen de l'écrire au lieu de réinitialiser le flux comme je l'ai montré dans le code de travail? –

+1

Créer une liste d'éléments entiers (par 'source.getLines(). ToList') puis' Iterator.continually (theList) .flatten'. Cette façon ne peut être utilisée que si elle s'inscrit dans la mémoire. Sinon, ré-initialiser le flux est le chemin à parcourir. – kawty