At Fri, 21 Jan 2011 10:53:42 -0700, Doug Williams wrote: > What is the best way to perform actions after a sequence terminates? Here is > a simple example that is like in-lines, but takes a path instead of a port. > It works, but I was wondering if there is a better way to do it. > > (define (in-file-lines path) > (let ((port (open-input-file path #:mode 'text))) > (make-do-sequence > (lambda () > (values > (lambda (_) (read-line port 'any)) > void > (void) > void > (lambda _ (if (eof-object? (peek-byte port)) > (begin > (close-input-port port) > #f) > #t)) > void)))))
I think you mean (define (in-file-lines path) (let ((port (open-input-file path #:mode 'text))) (make-do-sequence (lambda () (values (lambda (_) (read-line port 'any)) void (void) void (lambda (v) (if (eof-object? v) ; <---------- (begin (close-input-port port) #f) #t)) void))))) so that the last line is included in the sequence. Otherwise, I don't have any better suggestions. Beware that if the sequence stops being used before you get to the end of the file, then the port won't be closed: (for ([line (in-file-lines <file>)] [elem (in-list '(1 2 3))]) ...) ; port isn't closed if it has more than 3 lines But the sequence protocol doesn't give a sequence any way to know that it isn't being used, other than GC-based finalization --- which is probably a bad idea for file ports, since you can run out of available file descriptors much faster than available memory. _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev