the*_*bda 2 database common-lisp string-formatting
就在最近我一直在玩lisp,我正在尝试创建一个通用的本地数据库,我正在关注另一个涵盖大多数此类项目的教程,但是我决定要添加一个"简单" "功能.
我正在尝试以自定义格式生成时间戳,并将它们保存为字符串.我正在尝试将格式生成的字符串存储到使用defvar声明的变量中,方法是将变量作为第一个参数调用format,但不是保存完整输出,而是获取月份的日期.这是我的代码:
(defun date ()
(setq *SUPPRESS-SIMILAR-CONSTANT-REDEFINITION-WARNING* 1)
(defconstant *day-names*
'("Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"))
*DAY-NAMES*
(multiple-value-bind
(second minute hour date month year day-of-week dst-p tz)
(get-decoded-time)
(defvar datetime)
(format datetime "~2,'0d:~2,'0d:~2,'0d ~a ~d/~2,'0d/~d (GMT~@d)"
hour
minute
second
(nth day-of-week *day-names*)
month
date
year
(- tz)
(return-from date datetime))))
(defun make-entry (category subject idea info researched)
(defvar date (date))
(list :category category :subject subject :date date :idea idea :info info :researched researched))
Run Code Online (Sandbox Code Playgroud)
的期望值日期内补充条目应类似于二十一点28分十八秒周三2014年7月30日(GMT-7) ,但我最终只有30,而不是它的其余部分.此外,我已经测试找到返回的30的类型,它确实是一个整数,而不是char-stream(字符串)应该是.因此,我确信这与格式中的"~d"有关,但我可能错了.真的,我只是想将系统时间的格式化版本传递给make-entry.
那好吧.[Dons代码审查帽子]
首先,让我们更加一致地缩进.你确实做了比典型的lisp-newbie在缩进时做得更好的事情,但是把大部分内容冲到了一列.缩进级别可以为您提供有关程序控制流程的大量提示.一旦你习惯了,我的意思是.
(defun date ()
(setq *SUPPRESS-SIMILAR-CONSTANT-REDEFINITION-WARNING* 1)
(defconstant *day-names*
'("Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"))
*DAY-NAMES*
(multiple-value-bind
(second minute hour date month year day-of-week dst-p tz)
(get-decoded-time)
(defvar datetime)
(format datetime "~2,'0d:~2,'0d:~2,'0d ~a ~d/~2,'0d/~d (GMT~@d)"
hour minute second
(nth day-of-week *day-names*)
month date year
(- tz)
(return-from date datetime))))
(defun make-entry (category subject idea info researched)
(defvar date (date))
(list :category category :subject subject :date date :idea idea :info info :researched researched))
Run Code Online (Sandbox Code Playgroud)
你可以,但不应该使用defconstant和defvar本地.要么制作那些顶级表单,要么使用它们使它们成为本地定义let.在你的情况下,constant作为一个全局有意义,而var应该是一个局部变量(但稍后更多).此外,既然您没有在每个函数调用上重新定义常量,则不需要压制该重定义警告.
(defconstant *day-names* '("Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"))
(defun date ()
*DAY-NAMES*
(multiple-value-bind
(second minute hour date month year day-of-week dst-p tz)
(get-decoded-time)
(let ((datetime))
(format datetime "~2,'0d:~2,'0d:~2,'0d ~a ~d/~2,'0d/~d (GMT~@d)"
hour minute second
(nth day-of-week *day-names*)
month date year
(- tz)
(return-from date datetime)))))
Run Code Online (Sandbox Code Playgroud)
Lisp表单自动返回它计算的最后一个值,但任何早期的表单只会产生副作用而不是值.*DAY-NAMES*一开始没什么特别的date.此外,由于你似乎试图返回datetime从date,你不需要调用return-from.相反,只是评估datetime.
(defun date ()
(multiple-value-bind
(second minute hour date month year day-of-week dst-p tz)
(get-decoded-time)
(let ((datetime))
(format datetime "~2,'0d:~2,'0d:~2,'0d ~a ~d/~2,'0d/~d (GMT~@d)"
hour minute second
(nth day-of-week *day-names*)
month date year
(- tz))
datetime)))
Run Code Online (Sandbox Code Playgroud)
format将流作为其第一个参数.而变量不是流(虽然它可能包含一个;你的不包含).你似乎想要做的是将当前时间作为字符串返回,根据你的format指令格式化.要做到这一点,你根本不需要中间值.只需NIL作为第一个参数传递format,它将自动创建一个包含内容的新字符串,然后返回它.
(defun date ()
(multiple-value-bind
(second minute hour date month year day-of-week dst-p tz)
(get-decoded-time)
(format nil "~2,'0d:~2,'0d:~2,'0d ~a ~d/~2,'0d/~d (GMT~@d)"
hour minute second
(nth day-of-week *day-names*)
month date year
(- tz))))
Run Code Online (Sandbox Code Playgroud)
在这一点上,date似乎做了一些有意义的事情.
cl-user> (date)
"15:39:12 Thursday 7/31/2014 (GMT-5)"
cl-user>
Run Code Online (Sandbox Code Playgroud)
因为你只是试图把一些值的列表,你也不需要创建一个局部变量来保存的结果(date)在make-entry.
(defun make-entry (category subject idea info researched)
(list :category category :subject subject :date (date) :idea idea :info info :researched researched))
Run Code Online (Sandbox Code Playgroud)
此时,make-entry返回plist其:DATE值为适当格式化字符串的a date.
cl-user> (make-entry "something" "something else" "blah" "bleeh" "stop using side effects")
(:CATEGORY "something" :SUBJECT "something else" :DATE
"15:41:57 Thursday 7/31/2014 (GMT-5)" :IDEA "blah" :INFO "bleeh" :RESEARCHED
"stop using side effects")
cl-user>
Run Code Online (Sandbox Code Playgroud)
(defconstant *day-names* '("Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"))
(defun date ()
(multiple-value-bind
(second minute hour date month year day-of-week dst-p tz)
(get-decoded-time)
(format nil "~2,'0d:~2,'0d:~2,'0d ~a ~d/~2,'0d/~d (GMT~@d)"
hour minute second
(nth day-of-week *day-names*)
month date year
(- tz))))
(defun make-entry (category subject idea info researched)
(list :category category :subject subject :date (date) :idea idea :info info :researched researched))
Run Code Online (Sandbox Code Playgroud)
如果您正在关注PCL数据库章节,请记住,在您阅读数据库时,需要再次解码以这种方式格式化的日期,假设您计划执行除字符串比较之外的任何其他操作用它.因此,根据您的具体用例,实际存储原始输出可能更有意义(get-universal-time).