I’m making my own object-copy macro (just like struct-copy, but for objects), 
and I am getting this weird error:
. %: identifier used out of context in: %

What am I doing wrong?  And is there another way to do it that doesn’t involve 
an eval-syntax (I suspect that’s part of the problem)?  

And also, is there another version of field-names that takes a class instead of 
an object, because I think that will create another problem when I get to the 
last test (with not-really-chum).  

Here’s the code:
#lang racket/base (require (for-syntax racket/base))

(provide object-copy)

(require racket/class
         (for-syntax
          syntax/parse))

(module+ test
  (require rackunit))

(define-syntax object-copy
  (lambda (stx)
    (syntax-parse stx
      [(object-copy %-expr obj-expr
                    [field-id:id expr:expr]
                    ...)
       #:declare %-expr (expr/c #'class? #:name "class")
       #:declare obj-expr (expr/c #'(is-a?/c %-expr) #:name "object")
       (with-syntax ([ooo '...])
         #'(let* ([% %-expr.c]
                  [obj obj-expr.c]
                  [all-field-syms (field-names obj)]
                  [remaining-field-syms (remove* '(field-id ...) 
all-field-syms)])
             (with-syntax ([(remaining-field-id ooo) remaining-field-syms])
               (eval-syntax
                #'(new %
                       [field-id expr] ...
                       [remaining-field-id (get-field remaining-field-id obj)] 
ooo
                       )))))]
      )))

(module+ test
  (define fish%
    (class object% (init-field color weight)
      (super-new) (inspect #f)))
  
  (define marlin (new fish% [color 'orange-and-white] [weight 11]))
  
  (define dory (object-copy fish% marlin
                            [color 'blue]))
  
  (check-equal? dory (new fish% [color 'blue] [weight 11]))
  
  (define shark%
    (class fish% (init-field weeks-since-eating-fish)
      (super-new) (inspect #f)))
  
  (define bruce (new shark% [color 'grey] [weight 110] [weeks-since-eating-fish 
3]))
  
  (define chum (object-copy shark% bruce
                            [weight 90]
                            [weeks-since-eating-fish 0]))
  
  (check-equal? chum (new shark% [color 'grey] [weight 90] 
[weeks-since-eating-fish 0]))
  
  (define not-really-chum
    (object-copy fish% bruce
                 [weight 90]))
  
  (check-equal? not-really-chum (new fish% [color 'grey] [weight 90]))
  
  )


____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to