Lisp网络故事:如何修复blogdemo示例(第4章)? [英] Lisp web tales: How to fix the blogdemo example (Chapter 4)?

查看:77
本文介绍了Lisp网络故事:如何修复blogdemo示例(第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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆