Lisp网络故事:如何修复blogdemo示例(第4章)? [英] Lisp web tales: How to fix the blogdemo example (Chapter 4)?
问题描述
我遇到了Pavel的教程,其中涉及使用CL和 RESTAS 作为框架。虽然简单的 Hello,World!
示例有效。我无法从第4章的运行中获取博客示例。
使用(restas:debug-mode-on)
我最终得到以下回溯:
无效的参数数量:0
[SB-类型的条件INT:简单程序错误]
重新启动:
0:[中止]中止线程(#< THREAD hunchentoot-worker-127.0.0.1:59876正在运行{1009975FD3}> ;)
回溯:
0:(BLOGDEMO :: HTML-FRAME)[tl,external]
1:(RESTAS :: ROUTE-RENDER-METHOD#< RESTAS :ROUTE {100A16FE53}>)
2:((:METHOD RESTAS:PROCESS-ROUTE(RESTAS:ROUTE T))#< RESTAS:ROUTE {100A16FE53}> NIL)[快速方法]
3:(((FLET CALL-NEXT-METHOD:IN C:/Users/martin_b/portacle/quicklisp/dists/quicklisp/software/restas-20170124-git/src/route.lisp))
4:((:METHOD RESTAS:PROCESS-ROUTE:AROUND(ROUTES:BASE-ROUTE T))#< RESTAS:ROUTE {100A16FE53}> NIL)[快速方法]
5:(RESTAS :: RESTAS-DISPATCH-REQUEST#< RESTAS:RESTAS-ACCEPTOR(主机*,端口8080)> #< RESTAS :: RESTAS-REQUEST {1003E5B383}>)
6:((:METHOD HUNCHENTOOT:ACCEPTOR-DISPATCH-REQUEST(RESTAS:RESTAS-ACCEPTOR T))#< RESTAS:RESTAS-ACCEPTOR(主机*,端口8080)>#< RESTAS :: RESTAS-REQUEST {1003E5B383}>)[快速方法]
7:((:METHOD HUNCHENTOOT:HANDLE-REQUEST(HUNCHENTOOT:ACCEPTOR HUNCHENTOOT:REQUEST ))#< RESTAS:RESTAS-ACCEPTOR(主机*,端口8080)>#< RESTAS :: RESTAS-REQUEST {1003E5B383}>)[快速方法]
8:(((METHOD HUNCHENTOOTOT :PROCESS-REQUEST(T))#< RESTAS :: RESTAS-REQUEST {1003E5B383}>)[快速方法]
9:(((FLET CALL-NEXT-METHOD:IN C:/ Users / martin_b / portacle / quicklisp / dists / quicklisp / software / restas-20170124-git / src / hunchentoot.lisp))
10:((:METHOD HUNCHENTOOT:PROCESS-REQUEST:AROUND(RESTAS :: RESTAS-REQUEST ))#< RESTAS :: RESTAS-REQUEST {1003E5B383}>)[快速方法]
11:(((LAMBDA NIL:在HUNCHENTOOT:PROCESS-CONNECTION))
12:(HUNCHENTOOT: :增加接受方请求计数的#< RESTAS:RESTAS-ACCEPTO R(主机*,端口8080)> #<关闭(LAMBDA NIL:在HUNCHENTOOT:过程连接中){1003C3439B}>)
13:((:METHOD HUNCHENTOOT:PROCESS-CONNECTION(HUNCHENTOOT:ACCEPTOR T))#< RESTAS:RESTAS- ACCEPTOR(主机*,端口8080)>#< USOCKET:STREAM-USOCKET {1009971333}>)[快速方法]
14:(((FLET CALL-NEXT-METHOD:IN C:/ Users /martin_b/portacle/quicklisp/dists/quicklisp/software/hunchentoot-1.2.35/acceptor.lisp))
15:((:: METHOD HUNCHENTOOT:PROCESS-CONNECTION:AROUND(HUNCHENTOOT:ACCEPTOR T))# < RESTAS:RESTAS-ACCEPTOR(主机*,端口8080)>#< USOCKET:STREAM-USOCKET {1009971333}>)[快速方法]
16:(([FLET HUNCHENTOOT :: PROCESS-CONNECTION %:IN HUNCHENTOOT :: HANDLE-INCOMING-CONNECTION%)#< RESTAS:RESTAS-ACCEPTOR(主机*,端口8080)>#< USOCKET:STREAM-USOCKET {1009971333}>)
17: ((:METHOD HUNCHENTOOT :: HANDLE-INCOMING-CONNECTION%(HUNCHENTOOT:一次连接每个任务的任务))#< HUNCHENTOOT:一次连接每个任务的任务{10081F24C3}>#< USOCKET:STREA M-USOCKET {1009 ..
18:((LAMBDA NIL:在HUNCHENTOOT:CREATE-REQUEST-HANDLER-THREAD))
19:((LAMBDA NIL:在BORDEAUX-THREADS :: BINDING-DEFAULT -特价))
20:((FLET#:WITHOUT-INTERRUPTS-BODY-1169:在SB-螺纹:: INITIAL-THREAD-功能-蹦床))
21:((FLET SB-THREAD :: WITH-MUTEX-THUNK:在SB-螺纹中:: INITIAL-THREAD-FUNCTION-TRAMPOLINE))
22:(((Flet#:WITHOUT-INTERRUPTS-BODY-359:在SB-螺纹中:: CALL- WITH-MUTEX))
23:(SB-螺纹::打电话至MUTEX#<关闭(Flet SB-螺纹:: WITH-MUTEX-THUNK:在SB-螺纹:: INITIAL-THREAD-FUNCTION -TRAMPOLINE){6DAFB4B}> #< SB-THREAD:MUTEX线程结果锁定所有者:#< SB-THREAD:THREAD ..
24:(SB-THREAD :: INITIAL-THREAD-FUNCTION-TRAMPOLINE#< SB-螺纹:螺纹 hunchentoot-worker-127.0.0.1:59876正在运行{1009975FD3}> NIL#<关闭(LAMBDA NIL:在BORDEAUX-THREADS :: BINDING-DEFAULT-SPECIALS中){..
25: (外部功能:#x42BEFC)
26 :(外部功能:#x4038C1)
27 :(外部功能:#x447080)
显然,函数 html-frame
期望的参数数量与使用渲染方法
调用它的编号。我检查了源代码和RESTAS文档(它们似乎已经过时了),但不知道要更改什么。 / p>
有人在使用RESTAS吗?是否有其他最新的现实生活示例可供人们学习学习?我的印象 是因为有服务器网络框架,但我发现很难看到实际使用和维护的。
我通过改回来解决了这个问题他的:
(defun start-blogdemo(& optional(port 8080))
(开始'#:blogdemo:port port:render-method'html-frame))
到:
(defun start-blogdemo(& optional(port 8080))
(开始'#:blogdemo:port port))
在 util.lisp中
。
然后,您需要在 blogdemo.lisp
中读取每条路线不像这样:
(定义路线回家()
(列表: title Blogdemo
:body(mapcar#'render-post * posts *))))
但是像这样:
(定义路线首页()
(html框架
(列表:title Blogdemo
:body(mapcar#'render-post * posts *))))
此解决方案的起源是我不完全理解他所做的抽象的正确性(并在p37上进行了很多讨论,他还讨论了此处),所以我撤消了
请注意,路线添加
应该如下所示(具有:requirement
的表单必须位于html框架之前,后者是最后一个形式,因此是返回值)。
(定义路由添加( add)
(:requirement#'logged-on-p)
(html框架
(列表:标题添加博客帖子
:body(添加帖子的形式))))b $ b
同样,:sift-variables
ms还应该排在 author
& 发布
路线,就像:需求
一样。然后整个应用程序将为您工作。
I came across Pavel's tutorial about writing a web app using CL and RESTAS as a frame work. While simple Hello, World!
examples work. I am not able to get the blog example from chapter 4 running.
Using (restas:debug-mode-on)
I end up with the following backtrace:
invalid number of arguments: 0
[Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]
Restarts:
0: [ABORT] abort thread (#<THREAD "hunchentoot-worker-127.0.0.1:59876" RUNNING {1009975FD3}>)
Backtrace:
0: (BLOGDEMO::HTML-FRAME) [tl,external]
1: (RESTAS::ROUTE-RENDER-METHOD #<RESTAS:ROUTE {100A16FE53}>)
2: ((:METHOD RESTAS:PROCESS-ROUTE (RESTAS:ROUTE T)) #<RESTAS:ROUTE {100A16FE53}> NIL) [fast-method]
3: ((FLET CALL-NEXT-METHOD :IN "C:/Users/martin_b/portacle/quicklisp/dists/quicklisp/software/restas-20170124-git/src/route.lisp"))
4: ((:METHOD RESTAS:PROCESS-ROUTE :AROUND (ROUTES:BASE-ROUTE T)) #<RESTAS:ROUTE {100A16FE53}> NIL) [fast-method]
5: (RESTAS::RESTAS-DISPATCH-REQUEST #<RESTAS:RESTAS-ACCEPTOR (host *, port 8080)> #<RESTAS::RESTAS-REQUEST {1003E5B383}>)
6: ((:METHOD HUNCHENTOOT:ACCEPTOR-DISPATCH-REQUEST (RESTAS:RESTAS-ACCEPTOR T)) #<RESTAS:RESTAS-ACCEPTOR (host *, port 8080)> #<RESTAS::RESTAS-REQUEST {1003E5B383}>) [fast-method]
7: ((:METHOD HUNCHENTOOT:HANDLE-REQUEST (HUNCHENTOOT:ACCEPTOR HUNCHENTOOT:REQUEST)) #<RESTAS:RESTAS-ACCEPTOR (host *, port 8080)> #<RESTAS::RESTAS-REQUEST {1003E5B383}>) [fast-method]
8: ((:METHOD HUNCHENTOOT:PROCESS-REQUEST (T)) #<RESTAS::RESTAS-REQUEST {1003E5B383}>) [fast-method]
9: ((FLET CALL-NEXT-METHOD :IN "C:/Users/martin_b/portacle/quicklisp/dists/quicklisp/software/restas-20170124-git/src/hunchentoot.lisp"))
10: ((:METHOD HUNCHENTOOT:PROCESS-REQUEST :AROUND (RESTAS::RESTAS-REQUEST)) #<RESTAS::RESTAS-REQUEST {1003E5B383}>) [fast-method]
11: ((LAMBDA NIL :IN HUNCHENTOOT:PROCESS-CONNECTION))
12: (HUNCHENTOOT::DO-WITH-ACCEPTOR-REQUEST-COUNT-INCREMENTED #<RESTAS:RESTAS-ACCEPTOR (host *, port 8080)> #<CLOSURE (LAMBDA NIL :IN HUNCHENTOOT:PROCESS-CONNECTION) {1003C3439B}>)
13: ((:METHOD HUNCHENTOOT:PROCESS-CONNECTION (HUNCHENTOOT:ACCEPTOR T)) #<RESTAS:RESTAS-ACCEPTOR (host *, port 8080)> #<USOCKET:STREAM-USOCKET {1009971333}>) [fast-method]
14: ((FLET CALL-NEXT-METHOD :IN "C:/Users/martin_b/portacle/quicklisp/dists/quicklisp/software/hunchentoot-1.2.35/acceptor.lisp"))
15: ((:METHOD HUNCHENTOOT:PROCESS-CONNECTION :AROUND (HUNCHENTOOT:ACCEPTOR T)) #<RESTAS:RESTAS-ACCEPTOR (host *, port 8080)> #<USOCKET:STREAM-USOCKET {1009971333}>) [fast-method]
16: ((FLET HUNCHENTOOT::PROCESS-CONNECTION% :IN HUNCHENTOOT::HANDLE-INCOMING-CONNECTION%) #<RESTAS:RESTAS-ACCEPTOR (host *, port 8080)> #<USOCKET:STREAM-USOCKET {1009971333}>)
17: ((:METHOD HUNCHENTOOT::HANDLE-INCOMING-CONNECTION% (HUNCHENTOOT:ONE-THREAD-PER-CONNECTION-TASKMASTER T)) #<HUNCHENTOOT:ONE-THREAD-PER-CONNECTION-TASKMASTER {10081F24C3}> #<USOCKET:STREAM-USOCKET {1009..
18: ((LAMBDA NIL :IN HUNCHENTOOT:CREATE-REQUEST-HANDLER-THREAD))
19: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
20: ((FLET #:WITHOUT-INTERRUPTS-BODY-1169 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
21: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
22: ((FLET #:WITHOUT-INTERRUPTS-BODY-359 :IN SB-THREAD::CALL-WITH-MUTEX))
23: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {6DAFB4B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
24: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "hunchentoot-worker-127.0.0.1:59876" RUNNING {1009975FD3}> NIL #<CLOSURE (LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS) {..
25: ("foreign function: #x42BEFC")
26: ("foreign function: #x4038C1")
27: ("foreign function: #x447080")
Obviously, there is a problem between the number of arguments the function html-frame
is expecting and the number it is called using render-method
. I checked the source and the RESTAS docs (which seem to be slightly out-dated) but could not understand what to change.
Is someone using RESTAS? Are there other up-to-date real life examples available one could study to learn? My impressions from Cliki was that there are several web-frameworks around but I found it hard to see which are actually used and maintained.
解决方案 I fixed this by changing back his:
(defun start-blogdemo (&optional (port 8080))
(start '#:blogdemo :port port :render-method 'html-frame))
To:
(defun start-blogdemo (&optional (port 8080))
(start '#:blogdemo :port port))
in util.lisp
.
Then you need to make each of your routes in blogdemo.lisp
read not like:
(define-route home ("")
(list :title "Blogdemo"
:body (mapcar #'render-post *posts*)))
But instead like:
(define-route home ("")
(html-frame
(list :title "Blogdemo"
:body (mapcar #'render-post *posts*))))
The origin of this solution is that I didn't entirely understand the correctness of abstraction he was making (and wrangled quite a bit about on p37, which he also discusses here) so I reversed that and it worked.
Note also that the route add
should look as below (the form with :requirement
needs to come before html-frame, the latter being the last form hence the return value).
(define-route add ("add")
(:requirement #'logged-on-p)
(html-frame
(list :title "Add a blog post"
:body (add-post-form))))
Likewise, the :sift-variables
forms should also come first in author
& post
routes, just like :requirement
. Then the whole app should work for you.
这篇关于Lisp网络故事:如何修复blogdemo示例(第4章)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!