首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在球拍类函数中使用点符号

在球拍类函数中使用点符号
EN

Stack Overflow用户
提问于 2016-08-30 18:20:54
回答 1查看 330关注 0票数 2

我有以下类,它工作得很好:

代码语言:javascript
复制
(define myob%
  (class object%
    (super-new)
    (init-field val)
    (define/public (getval) val)
    (define/public (setval v) (set! val v))   ))

(define ob1 (make-object myob% 5))

(send ob1 getval)
(send ob1 setval 10)
(send ob1 getval)

输出:

代码语言:javascript
复制
5
10

下面的正则表达式也可以很好地工作:

代码语言:javascript
复制
(define sl (regexp-match #px"^(.+)[.]([^.]+)$" "ob1.getval"))
sl

输出:

代码语言:javascript
复制
'("ob1.getval" "ob1" "getval")

我正在尝试做一个fn foo,它应该像'send‘一样工作,但以(foo ob1.getval)(foo ob1.setval 10)的形式接受参数。以下宏不起作用:

代码语言:javascript
复制
(define-syntax foo
    (syntax-rules ()
      ((_ sstr ...)
       (define sl (regexp-match #px"^(.+)[.]([^.]+)$"
                                (symbol->string sstr)))
       (send (string->symbol(list-ref sl 1))
             (string->symbol(list-ref sl 2))
             ...))))

(foo ob1.getval)

错误是:

代码语言:javascript
复制
syntax-rules: bad syntax in: (syntax-rules () ((_ sstr ...) (define sl (regexp-match #px"^(.+)[.]([^.]+)$" (symbol->string sstr))) (send (list-ref sl 1) (list-ref sl 2) ...)))

错误在哪里?如何纠正这个错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-30 22:17:01

要使用这样的点表示法,您需要定义一种新的#lang语言,该语言具有自己的阅读器。有几个工具可以帮助实现这一点,我将使用其中一个工具syntax/module-reader来定义#lang send-dot,一旦定义,它就可以像这样使用:

代码语言:javascript
复制
#lang send-dot

(define o
  (new (class object% (super-new)
         (define/public (f x) x))))

(o.f "hellooo")

在球拍的latest snapshot version中,可以使用read-cdot选项。请确保您使用的是最新的快照版本,因为在6.6中,它完全崩溃了。

定义#lang的一种方法是声明一个reader子模块。创建一个名为send-dot的目录,并添加一个名为main.rkt的文件。这个文件应该提供球拍中的所有内容。

代码语言:javascript
复制
#lang racket

(provide (all-from-out racket))

这还没有定义#lang。但要尝试它,您可以转到DrRacket的文件菜单,单击包管理器,并在包源字段中输入send-dot目录的路径。一旦你这样做了,你应该能够在另一个文件中使用#lang s-exp send-dot,就像使用#lang racket一样。

要定义该语言的阅读器并使其成为真正的#lang语言,可以添加一个使用syntax/module-reader作为其语言的reader子模块。

代码语言:javascript
复制
#lang racket

(provide (all-from-out racket))

;; This submodule defines the reader for the language
(module reader syntax/module-reader
  send-dot)

现在您应该能够像使用#lang racket一样使用#lang send-dot了。

现在,您还需要做两件事。首先,启用read-cdot选项,以便将(o.method args ...)转换为((#%dot o method) args ...);其次,定义#%dot宏,使((#%dot o method) args ...)等效于(send o method args ...)

首先,您可以使用#:wrapper1选项,使用parameterize打开read-cdot

代码语言:javascript
复制
#lang racket

(provide (all-from-out racket))

;; This submodule defines the reader for the language
(module reader syntax/module-reader
  send-dot
  #:wrapper1 (lambda (thunk)
               ;; turns on the read-cdot option,
               ;; which will turn o.method into (#%dot o method),
               ;; and (o.method args ...) into ((#%dot o method) args ...)
               (parameterize ([read-cdot #true])
                 (thunk))))

对于第二件事,您需要定义一个#%dot宏。o.method(#%dot o method)需要是调用该方法的函数,所以您可以使用(lambda args (send/apply o method args))

代码语言:javascript
复制
#lang racket

(provide #%dot (all-from-out racket))

;; transforms (#%dot o method) into a function that calls the method
;; so that ((#%dot o method) args ...) will be roughly equivalent to
;; (send o method args ...)
(define-syntax-rule (#%dot obj-expr method-id)
  (let ([obj obj-expr])
    (lambda args (send/apply obj method-id args))))

;; This submodule defines the reader for the language
(module reader syntax/module-reader
  send-dot
  #:wrapper1 (lambda (thunk)
               ;; turns on the read-cdot option,
               ;; which will turn o.method into (#%dot o method),
               ;; and (o.method args ...) into ((#%dot o method) args ...)
               (parameterize ([read-cdot #true])
                 (thunk))))

现在,您应该能够像这样使用#lang send-dot

代码语言:javascript
复制
#lang send-dot

(define o
  (new (class object% (super-new)
         (define/public (f x) x))))

(o.f "hellooo")
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39224842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档