如何在多个文件/包中定义 caveman2 路由?

huangapple go评论53阅读模式
英文:

How to define caveman2 routes in multiple files/packages?

问题

I want to have routes defined over multiple files, not just web.lisp. What is the correct way of doing this?

我想在多个文件中定义路由,而不仅仅是在web.lisp中。正确的做法是什么?

I tried writing another file with this code and it works:

我尝试编写另一个文件,并使用以下代码,它可以正常工作:

(in-package :mywebapp.web)

;; for @route annotation
(syntax:use-syntax :annot)


(defroute "/hello" ()
  (format nil "Hello World!"))

However, what I thought was the correct approach was to have another package definition and then either import :mywebapp.web into my new package, or import my new package :mywebapp.controllers.hello into :mywebapp.web.

然而,我认为正确的方法是创建另一个包定义,然后要么将 :mywebapp.web 导入到我的新包中,要么将我的新包 :mywebapp.controllers.hello 导入到 :mywebapp.web 中。

Can you please explain to me the correct approach?

你能否向我解释正确的方法?

When I created my own package and imported :mywebapp.web I got the following error:

当我创建自己的包并导入 :mywebapp.web 时,我收到以下错误消息:

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION (COMMON-LISP:SETF NINGLE/APP:ROUTE) (1)>
when called with arguments
  (#<FUNCTION (LAMBDA (#:PARAMS1141)
                :IN
                "/project/src/controllers/hello.lisp") {53CE5F6B}>
   NIL "/hello").
See also:
  The ANSI Standard, Section 7.6.6

However I had imported into the new packages all the same imports as in the .web package...

但是,我已经将与.web包中相同的导入内容导入到新包中...

Note that I redacted the path...

请注意,我已经删除了路径...

Thanks!

谢谢!

英文:

I want to have routes defined over multiple files, not just web.lisp. What is the correct way of doing this?

I tried writing another file with this code and it works:

(in-package :mywebapp.web)

;; for @route annotation
(syntax:use-syntax :annot)


(defroute &quot;/hello&quot; ()
  (format nil &quot;Hello World!&quot;))

However, what I thought was the correct approach was to have another package definition and then either import :mywebapp.web into my new package, or import my new package :mywebapp.controllers.hello into :mywebapp.web.

Can you please explain to me the correct approach?

When I created my own package and imported :mywebapp.web I got the following error:


There is no applicable method for the generic function
#&lt;STANDARD-GENERIC-FUNCTION (COMMON-LISP:SETF NINGLE/APP:ROUTE) (1)&gt;
when called with arguments
(#&lt;FUNCTION (LAMBDA (#:PARAMS1141)
:IN
&quot;/project/src/controllers/hello.lisp&quot;) {53CE5F6B}&gt;
NIL &quot;/hello&quot;).
See also:
The ANSI Standard, Section 7.6.6

However I had imported into the new packages all the same imports as in the .web package...

Note that I redacted the path...

Thanks!

答案1

得分: 2

在CL-USER包中(在REPL中),我编写了以下表达式,并请求Emacs/Slime对其进行宏展开:

(caveman2:defroute "/hello" ())

结果如下:

(SETF (APPLY #'NINGLE/APP:ROUTE
             (CONS
              (CAVEMAN2.APP:FIND-PACKAGE-APP #<PACKAGE "COMMON-LISP-USER">)
              (LIST "/hello")))
        (LAMBDA (#:PARAMS1721) (DECLARE (IGNORABLE #:PARAMS1721))))

这对应于您的错误,因为最终在将apply(cons ...)表达式结合时,代码将调用route,传递find-package-app"/hello"的结果。

但在您的情况下,find-package-app的结果是NIL,表示未找到这样的应用程序。我可能预期在这里会有更好的错误消息,但无论如何,解决方法是明确指定应用程序:

(caveman2:defroute (other-package:*app* "/hello") ())

这个宏展开为:

(SETF (APPLY #'NINGLE/APP:ROUTE (LIST OTHER-PACKAGE:*APP* "/hello"))
        (LAMBDA (#:PARAMS1723) (DECLARE (IGNORABLE #:PARAMS1723))))

然而,关于这个问题的文档很少,我不得不查看源代码。

基本上,当应用程序被实例化时,*package*的当前值被捕获并关联到应用程序实例的哈希表中。

英文:

So, in package CL-USER (in the REPL) I wrote the following form and asked Emacs/Slime for its macroexpansion:

(caveman2:defroute &quot;/hello&quot; ())

The result is:

(SETF (APPLY #&#39;NINGLE/APP:ROUTE
             (CONS
              (CAVEMAN2.APP:FIND-PACKAGE-APP #&lt;PACKAGE &quot;COMMON-LISP-USER&quot;&gt;)
              (LIST &quot;/hello&quot;)))
        (LAMBDA (#:PARAMS1721) (DECLARE (IGNORABLE #:PARAMS1721))))

This corresponds to your error, because ultimately when combining apply with the (cons ...) forms, the code will be calling route with the result of find-package-app and &quot;/hello&quot;.

But in your case, the result of find-package-app is NIL, meaning no such app was found. I probably would have expected a better error message here, but anyway the solution is to explicitly specify the application:

(caveman2:defroute (other-package:*app* &quot;/hello&quot;) ())

This macroexpands as:

(SETF (APPLY #&#39;NINGLE/APP:ROUTE (LIST OTHER-PACKAGE:*APP* &quot;/hello&quot;))
        (LAMBDA (#:PARAMS1723) (DECLARE (IGNORABLE #:PARAMS1723))))

There is however little documentation about that, I had to look at the source code.

Basically when an application is instantiated, the current value of *package* is captured and associated in a hash-table to the application instance.

huangapple
  • 本文由 发表于 2023年5月25日 17:33:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76330818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定