Common lisp 连接到松弛IRC网关时出错

Common lisp 连接到松弛IRC网关时出错,common-lisp,irc,slack,sbcl,Common Lisp,Irc,Slack,Sbcl,我正在使用库通过Slack提供的IRC网关连接Slack 但是,当我尝试使用读取消息循环启动消息循环时,出现以下错误: error while parsing arguments to DESTRUCTURING-BIND: invalid number of elements in ("duncan_bayne" "Welcome" "to" "Slack" "IRC" "Gateway" "server" "duncan_bayne!~duncan_bayne@1.2.

我正在使用库通过Slack提供的IRC网关连接Slack

但是,当我尝试使用
读取消息循环启动消息循环时,出现以下错误:

error while parsing arguments to DESTRUCTURING-BIND:
  invalid number of elements in
    ("duncan_bayne" "Welcome" "to" "Slack" "IRC" "Gateway"
     "server" "duncan_bayne!~duncan_bayne@1.2.3.4")
  to satisfy lambda list
    (CL-IRC:NICKNAME CL-IRC::WELCOME-MESSAGE):
  exactly 2 expected, but 8 found
   [Condition of type SB-KERNEL::ARG-COUNT-ERROR]

... 

Backtrace:
  0: ((:METHOD CL-IRC::DEFAULT-HOOK (CL-IRC:IRC-RPL_WELCOME-MESSAGE)) #<CL-IRC:IRC-RPL_WELCOME-MESSAGE irc.tinyspeck.com RPL_WELCOME {1007FC6293}>) [fast-method]
  1: ((:METHOD CL-IRC::APPLY-TO-HOOKS (T)) #<CL-IRC:IRC-RPL_WELCOME-MESSAGE irc.tinyspeck.com RPL_WELCOME {1007FC6293}>) [fast-method]
  2: ((:METHOD CL-IRC:IRC-MESSAGE-EVENT (T CL-IRC:IRC-MESSAGE)) #<unavailable argument> #<CL-IRC:IRC-RPL_WELCOME-MESSAGE irc.tinyspeck.com RPL_WELCOME {1007FC6293}>) [fast-method]
  3: ((:METHOD CL-IRC:READ-MESSAGE (CL-IRC:CONNECTION)) #<CL-IRC:CONNECTION myob.irc.slack.com {10068E8ED3}>) [fast-method]
  4: ((:METHOD CL-IRC:READ-MESSAGE-LOOP (T)) #<CL-IRC:CONNECTION myob.irc.slack.com {10068E8ED3}>) [fast-method]
  5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (CL-IRC:READ-MESSAGE-LOOP *CONN*) #<NULL-LEXENV>)
  6: (EVAL (CL-IRC:READ-MESSAGE-LOOP *CONN*))
我不确定我在这里做错了什么;我相当肯定这不是我的钩子,因为即使我禁用了所有钩子,问题仍然存在

此外,如果我不尝试启动消息循环,我也可以按预期使用连接,比如加入一个通道并发送消息


我猜Slack是在用一条意外消息响应连接?

正如@jkilski所建议的,修复方法是修改cl irc,以接受Slack的稍微不寻常(但可能是标准编译器?)响应:

(in-package #:cl-irc)
(defmethod default-hook ((message irc-rpl_welcome-message))
  (with-slots
        (connection host user arguments)
      message
    (destructuring-bind
          (nickname &rest welcome-message)
        arguments
      (setf (user connection)
            (make-user connection
                       :nickname nickname
                       :hostname host
                       :username user)))))

(in-package #:irc)
(defmethod default-hook ((message irc-rpl_namreply-message))
  (let* ((connection (connection message)))
    (destructuring-bind
          (nick chan-visibility channel &optional names)
        (arguments message)
      (declare (ignore nick))
      (let ((channel (find-channel connection channel)))
        (setf (visibility channel)
              (or (second (assoc chan-visibility
                                 '(("=" :public) ("*" :private) ("@" :secret))
                                 :test #'string=))
                  :unknown))
        (unless (has-mode-p channel 'namreply-in-progress)
          (add-mode channel 'namreply-in-progress
                    (make-instance 'list-value-mode :value-type :user)))
        (dolist (nickname (tokenize-string names))
          (let ((user (find-or-make-user connection
                                         (canonicalize-nickname connection
                                                                nickname))))
            (unless (equal user (user connection))
              (add-user connection user)
              (add-user channel user))
            (set-mode channel 'namreply-in-progress user)
            (let* ((mode-char (getf (nick-prefixes connection)
                                    (elt nickname 0)))
                   (mode-name (when mode-char
                                (mode-name-from-char connection
                                                     channel mode-char))))
              (when mode-name
                (if (has-mode-p channel mode-name)
                    (set-mode channel mode-name user)
                    (set-mode-value (add-mode channel mode-name
                                              (make-mode connection
                                                         channel mode-name))
                                    user))))))))))

我已申请加入开发人员邮件列表,不久将提交修补程序。

如果将分解绑定(在event.lisp第149行中)更改为
(昵称和rest欢迎消息)
,请查看是否有其他错误。
WELCOME-MESSAGE
似乎没有任何用途,因此可能开发人员只是忘记了&rest,而它恰好在他的测试用例中工作。如果您可以修复它并提交补丁,那就太好了。否则,上次我试着用IRC做一些事情时,我使用了它,它成功了。
(in-package #:cl-irc)
(defmethod default-hook ((message irc-rpl_welcome-message))
  (with-slots
        (connection host user arguments)
      message
    (destructuring-bind
          (nickname &rest welcome-message)
        arguments
      (setf (user connection)
            (make-user connection
                       :nickname nickname
                       :hostname host
                       :username user)))))

(in-package #:irc)
(defmethod default-hook ((message irc-rpl_namreply-message))
  (let* ((connection (connection message)))
    (destructuring-bind
          (nick chan-visibility channel &optional names)
        (arguments message)
      (declare (ignore nick))
      (let ((channel (find-channel connection channel)))
        (setf (visibility channel)
              (or (second (assoc chan-visibility
                                 '(("=" :public) ("*" :private) ("@" :secret))
                                 :test #'string=))
                  :unknown))
        (unless (has-mode-p channel 'namreply-in-progress)
          (add-mode channel 'namreply-in-progress
                    (make-instance 'list-value-mode :value-type :user)))
        (dolist (nickname (tokenize-string names))
          (let ((user (find-or-make-user connection
                                         (canonicalize-nickname connection
                                                                nickname))))
            (unless (equal user (user connection))
              (add-user connection user)
              (add-user channel user))
            (set-mode channel 'namreply-in-progress user)
            (let* ((mode-char (getf (nick-prefixes connection)
                                    (elt nickname 0)))
                   (mode-name (when mode-char
                                (mode-name-from-char connection
                                                     channel mode-char))))
              (when mode-name
                (if (has-mode-p channel mode-name)
                    (set-mode channel mode-name user)
                    (set-mode-value (add-mode channel mode-name
                                              (make-mode connection
                                                         channel mode-name))
                                    user))))))))))