From 51797cec094d642600e9f86c517eb5a6883f5358 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 19 Apr 2010 19:33:57 +0200 Subject: [PATCH] make-record-type slight refactor * test-suite/tests/records.test ("records"): Add tests for printers. * module/ice-9/boot-9.scm (make-record-type): Refactor the code that makes the default printer. --- module/ice-9/boot-9.scm | 55 ++++++++++++++++++----------------- test-suite/tests/records.test | 26 +++++++++++++---- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index 4beec1e64..58c6c5c51 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -649,33 +649,34 @@ If there is no handler at all, Guile prints an error and then exits." (and (struct? obj) (eq? record-type-vtable (struct-vtable obj)))) (define (make-record-type type-name fields . opt) - (let ((printer-fn (and (pair? opt) (car opt)))) - (let ((struct (make-struct record-type-vtable 0 - (make-struct-layout - (apply string-append - (map (lambda (f) "pw") fields))) - (or printer-fn - (lambda (s p) - (display "#<" p) - (display type-name p) - (let loop ((fields fields) - (off 0)) - (cond - ((not (null? fields)) - (display " " p) - (display (car fields) p) - (display ": " p) - (display (struct-ref s off) p) - (loop (cdr fields) (+ 1 off))))) - (display ">" p))) - type-name - (copy-tree fields)))) - ;; Temporary solution: Associate a name to the record type descriptor - ;; so that the object system can create a wrapper class for it. - (set-struct-vtable-name! struct (if (symbol? type-name) - type-name - (string->symbol type-name))) - struct))) + (define (default-record-printer s p) + (display "#<" p) + (display (record-type-name (record-type-descriptor s)) p) + (let loop ((fields (record-type-fields (record-type-descriptor s))) + (off 0)) + (cond + ((not (null? fields)) + (display " " p) + (display (car fields) p) + (display ": " p) + (display (struct-ref s off) p) + (loop (cdr fields) (+ 1 off))))) + (display ">" p)) + + (let ((struct (make-struct record-type-vtable 0 + (make-struct-layout + (apply string-append + (map (lambda (f) "pw") fields))) + (or (and (pair? opt) (car opt)) + default-record-printer) + type-name + (copy-tree fields)))) + ;; Temporary solution: Associate a name to the record type descriptor + ;; so that the object system can create a wrapper class for it. + (set-struct-vtable-name! struct (if (symbol? type-name) + type-name + (string->symbol type-name))) + struct)) (define (record-type-name obj) (if (record-type? obj) diff --git a/test-suite/tests/records.test b/test-suite/tests/records.test index 7f8e63621..c2ea06ed7 100644 --- a/test-suite/tests/records.test +++ b/test-suite/tests/records.test @@ -1,6 +1,6 @@ ;;;; records.test --- Test suite for Guile's records. -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2009 Free Software Foundation, Inc. +;;;; Copyright (C) 2009, 2010 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -17,10 +17,13 @@ ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-records) + #:use-module (ice-9 format) #:use-module (test-suite lib)) -;; ascii names and symbols -(define rtd-foo (make-record-type "foo" '(x y))) +;; ascii names and symbols, custom printer +(define rtd-foo (make-record-type "foo" '(x y) + (lambda (s p) + (display "#" p)))) (define make-foo (record-constructor rtd-foo)) (define foo? (record-predicate rtd-foo)) (define get-foo-x (record-accessor rtd-foo 'x)) @@ -28,7 +31,7 @@ (define set-foo-x! (record-modifier rtd-foo 'x)) (define set-foo-y! (record-modifier rtd-foo 'y)) -;; non-Latin-1 names and symbols +;; non-Latin-1 names and symbols, default printer (define rtd-fŏŏ (make-record-type "fŏŏ" '(x ȳ))) (define make-fŏŏ (record-constructor rtd-fŏŏ)) (define fŏŏ? (record-predicate rtd-fŏŏ)) @@ -71,4 +74,17 @@ (string=? "foo" (record-type-name rtd-foo))) (pass-if "fŏŏ" - (string=? "fŏŏ" (record-type-name rtd-fŏŏ))))) + (string=? "fŏŏ" (record-type-name rtd-fŏŏ)))) + + (with-test-prefix "printer" + + (pass-if "foo" + (string=? "#" + (with-output-to-string + (lambda () (display (make-foo 1 2)))))) + + (pass-if "fŏŏ" + (with-locale "en_US.utf8" + (string-prefix? "#