problème de lisp
Le
Sébastien Kirche
Bonsoir,
ce soir j'ai fait du ménage dans mes archives de mail et après avoir
bataillé de longues heures, j'arrive enfin à avoir un archivage dans
Gnus des messages sortants séparé mail/news au format nnml
(1 msg = 1 fichier) et dans le répertoire de mon choix.
Rigolez pas, ça a l'air simple à dire, mais jusqu'à maintenant il avait
choisi le format nnfolder (1 fichier = 1 groupe) et je n'arrivais pas à
le changer.
Pour ceux que ça peut intéresser, ça donne le paramétrage suivant :
(setq gnus-secondary-select-methods
'(
;;
;; (autres serveurs)
;;
(nnml "archives"
(nnml-directory "/home/seki/.gnus.d/archives")
(nnml-active-file "/home/seki/.gnus.d/archives/active")
(nnml-inhibit-expiry t)
(nnml-get-new-mail nil))
))
(setq gnus-message-archive-group
'((if (message-news-p)
(concat "nnml+archives:News-sent." (format-time-string "%Y-%m"))
(concat "nnml+archives:Mail-sent." (format-time-string "%Y-%m"))
)))
Tout semble fonctionner correctement.
Seulement pendant mes essais j'ai essayé de paramétrer la valeur de
nnml-directory à (concat gnus-home-directory "/archives/active") et ça
explose au lancement de Gnus avec le backtrace suivant (excusez les
lignes trop longues) :
Debugger entered--Lisp error: (wrong-type-argument stringp (function (concat gnus-home-directory "/archives/active")))
insert-file-contents((function (concat gnus-home-directory "/archives/active")))
byte-code("bytecode supprimé" [nnmail-file-coding-system nnmail-pathname-coding-system file-name-coding-system auto-mode-alist coding-system-for-read file mm-auto-mode-alist insert-file-contents t] 3)
nnmail-find-file((function (concat gnus-home-directory "/archives/active")))
nnml-request-list("archives")
gnus-request-list((nnml "archives"))
gnus-read-active-file-1((nnml "archives") nil)
gnus-read-active-file(nil nil)
gnus-setup-news(nil nil nil)
byte-code("j'ai viré le bytecode à la citation" [dont-connect did-connect gnus-startup-file gnus-current-startup-file gnus-slave gnus-use-dribble-file gnus-group-quit gnus-run-hooks gnus-startup-hook gnus-make-newsrc-file gnus-dribble-read-file gnus-request-create-group "queue" (nndraft "") "drafts" (nndraft "") gnus-setup-news nil gnus-setup-news-hook gnus-start-draft-setup gnus-group-list-groups gnus-group-first-unread-group gnus-configure-windows group gnus-group-set-mode-line gnus-started-hook gnus-agent level] 4)
gnus-1(nil nil nil)
gnus(nil)
call-interactively(gnus)
execute-extended-command(nil)
call-interactively(execute-extended-command)
Je ne comprends pas pourquoi je ne peux pas utiliser le concat, ou
comment ça doit s'écrire si c'est possible. C'est à cause du quotage de
la liste des serveurs : il prend le tout comme une chaîne sans
interpréter ?
Un tuyau de la part de nos lisp power users ?
--
Sébastien Kirche
ce soir j'ai fait du ménage dans mes archives de mail et après avoir
bataillé de longues heures, j'arrive enfin à avoir un archivage dans
Gnus des messages sortants séparé mail/news au format nnml
(1 msg = 1 fichier) et dans le répertoire de mon choix.
Rigolez pas, ça a l'air simple à dire, mais jusqu'à maintenant il avait
choisi le format nnfolder (1 fichier = 1 groupe) et je n'arrivais pas à
le changer.
Pour ceux que ça peut intéresser, ça donne le paramétrage suivant :
(setq gnus-secondary-select-methods
'(
;;
;; (autres serveurs)
;;
(nnml "archives"
(nnml-directory "/home/seki/.gnus.d/archives")
(nnml-active-file "/home/seki/.gnus.d/archives/active")
(nnml-inhibit-expiry t)
(nnml-get-new-mail nil))
))
(setq gnus-message-archive-group
'((if (message-news-p)
(concat "nnml+archives:News-sent." (format-time-string "%Y-%m"))
(concat "nnml+archives:Mail-sent." (format-time-string "%Y-%m"))
)))
Tout semble fonctionner correctement.
Seulement pendant mes essais j'ai essayé de paramétrer la valeur de
nnml-directory à (concat gnus-home-directory "/archives/active") et ça
explose au lancement de Gnus avec le backtrace suivant (excusez les
lignes trop longues) :
Debugger entered--Lisp error: (wrong-type-argument stringp (function (concat gnus-home-directory "/archives/active")))
insert-file-contents((function (concat gnus-home-directory "/archives/active")))
byte-code("bytecode supprimé" [nnmail-file-coding-system nnmail-pathname-coding-system file-name-coding-system auto-mode-alist coding-system-for-read file mm-auto-mode-alist insert-file-contents t] 3)
nnmail-find-file((function (concat gnus-home-directory "/archives/active")))
nnml-request-list("archives")
gnus-request-list((nnml "archives"))
gnus-read-active-file-1((nnml "archives") nil)
gnus-read-active-file(nil nil)
gnus-setup-news(nil nil nil)
byte-code("j'ai viré le bytecode à la citation" [dont-connect did-connect gnus-startup-file gnus-current-startup-file gnus-slave gnus-use-dribble-file gnus-group-quit gnus-run-hooks gnus-startup-hook gnus-make-newsrc-file gnus-dribble-read-file gnus-request-create-group "queue" (nndraft "") "drafts" (nndraft "") gnus-setup-news nil gnus-setup-news-hook gnus-start-draft-setup gnus-group-list-groups gnus-group-first-unread-group gnus-configure-windows group gnus-group-set-mode-line gnus-started-hook gnus-agent level] 4)
gnus-1(nil nil nil)
gnus(nil)
call-interactively(gnus)
execute-extended-command(nil)
call-interactively(execute-extended-command)
Je ne comprends pas pourquoi je ne peux pas utiliser le concat, ou
comment ça doit s'écrire si c'est possible. C'est à cause du quotage de
la liste des serveurs : il prend le tout comme une chaîne sans
interpréter ?
Un tuyau de la part de nos lisp power users ?
--
Sébastien Kirche

Poser une question


Tu peux l'utiliser, mais tu _dois_ l'utiliser. Pas seulement le _nommer_!
En lisp, comme c'est de la programmation _symbolique_, les symboles
d'un programme peuvent être évalués, ou non. Le programmeur indique
quelles parties d'un programme doivent ne pas être évalués, c'est à
dire, doivent être considérés comme des données avec les opérateurs
spéciaux quote, ou function.
(list 1 (+ 1 1) (+ 1 1 1))
est un programme qui lorsqu'il s'exécute, appelle la fonction list, en
lui passant trois arguments: les résultats de l'évaluation des trois
expressions 1, (+ 1 1) et (+ 1 1 1), soit 1, 2 et 3; laquelle fonction
va construire une liste contenant ces arguments [en faisant: (cons 1
(cons 2 (cons 3 nil))) ] et la retourner: (1 2 3)
(quote (list 1 2 3))
est un programme qui lorsqu'il s'exécute, remarque que quote est un
opérateur spécial qui retourne son argument sans l'évaluer; il
retourne donc la donnée, la liste qui contient le symbole list, le
nombre 1, le nombre 2 et le nombre 3: (list 1 2 3)
(function sin)
(function (lambda (x) (* x x)))
sont des programmes qui lorsqu'ils s'exécutent, remarquent que
function est un opérateur spécial qui fonctionne sur emacs exactement
comme quote (sauf que si on compile ces programme, le compilateur
compilera aussi les fonctions passées en argument de function au lieu
de les traiter comme une simple donnée comme quote.
Avec un vrai language de programmation, comme Common Lisp, le langage
détecterait que:
(function (concat gnus-home-directory "/archives/active"))
est une erreur:
--> *** - FUNCTION: (CONCAT GNUS-HOME-DIRECTORY "/archives/active") is not a
function name; try using a symbol instead
Mais pour un jouet comme emacs lisp, comme function est comme quote,
(function (concat gnus-home-directory "/archives/active"))
retourne simplement la donnée, la liste:
--> (concat gnus-home-directory "/archives/active")
sans l'évaluer, comme le ferait quote.
Si tu veux obtenir le résultat de la concaténation, il ne faut pas
"quoter" avec function ton expression, ce qui de toutes façon est
invalide:
(funcall (function (concat gnus-home-directory "/archives/active")))
--> Debugger entered--Lisp error: (invalid-function (concat gnus-home-directory "/archives/active"))
(function (concat gnus-home-directory "/archives/active"))
--> (concat gnus-home-directory "/archives/active")
(concat gnus-home-directory "/archives/active")
--> "~//archives/active"
Donc enlève ce function, est ça devrait fonctionner...
--
__Pascal Bourguignon__ http://www.informatimago.com/
The mighty hunter
Returns with gifts of plump birds,
Your foot just squashed one.
C'est un peu ça. Sauf qu'il ne s'agit pas de chaînes de
caractères (pas seulement), mais de symboles, chaînes, etc.
Yep :
(setq gnus-secondary-select-methods
`((nnml "archives"
(nnml-directory ,(concat ... "..."))
(nnml-active-file "/home/seki/.gnus.d/archives/active")
(nnml-inhibit-expiry t)
(nnml-get-new-mail nil))))
Remarque que j'utilise une backquote « ` » au lieu d'une quote
normale « ' », ainsi qu'une virgule. L'explication, c'est qu'une
backquote quote comme une quote (à prononcer très vite), sauf les
élements précédés d'une virgule, qui sont eux évalués.
Dans le cas :
'(nnml (concat sym "str"))
tu obtiens une liste constituée de deux éléments. Le symbole
« nnml » et une liste. Elle-même contient trois éléments : le
symbole « concat », le symbole « sym » et la chaîne "str".
La chaîne, théoriquement, est quotée. Mais les chaînes de
caractères sont automatiquement quotées. Il n'y a pas de
différence entre une chaîne quotée ou non (je pense que
l'explication exacte est qu'une chaîne s'évalue en elle-même).
Il y a quelques autres types qui s'évaluent en eux-mêmes.
Dans le cas :
`(nnml ,(concat sym "str"))
tu obtiens une liste constituée de deux éléments. Le symbole
« nnml », toujours, et une chaîne de caractères, résultat de
l'évaluation de la concaténation (entre la valeur de la variable
« sym » et la chaîne "str").
Note que si tu enlèves la virgule, tu te retrouves exactement
dans le même cas que précédemment.
Enfin, j'espère que c'est bien la solution. Je n'ai pas
réellement investigué, et je ne sais pas d'où vient le
« function » dans le backtrace.
--drkm
Mmh. Sébastien a dit avoir tenté de fixer 'nnml-directory' à
(concat gnus-home-directory "/archives/active"). Il n'a pas
parlé de 'function'. Par 'nnml-directory', j'imagine qu'il parle
de la valeur associée à cette entrée dans une sous-liste de
'gnus-secondary-select-methods'.
Mais il est vrai que je ne m'explique pas ce 'function'. Ce
serait évidemment l'explication la plus évidente. Sébastien,
as-tu fait cette bêtise ?-).
Si je comprend bien le problème, il a essayé d'évaluer le
'concat' dans la liste au moyen de 'function', comme ceci :
(setq gnus-secondary-select-methods
'((nnml "archives"
(nnml-directory (function (concat gnus-home-directory
"/archives/active")))
(nnml-active-file "/home/seki/.gnus.d/archives/active")
(nnml-inhibit-expiry t)
(nnml-get-new-mail nil))))
quand ce qu'il veut est plutôt :
(setq gnus-secondary-select-methods
`((nnml "archives"
(nnml-directory ,(concat gnus-home-directory
"/archives/active"))
(nnml-active-file "/home/seki/.gnus.d/archives/active")
(nnml-inhibit-expiry t)
(nnml-get-new-mail nil))))
Combien je gagne ?
--drkm
Le plus probable, c'est que l'expression concat ait été saisie avec
customize-option où on a un menu où on peut sélectionner "fonction" et
taper le nom de la fonction à utiliser...
Oui, mais ça a certainement été généré automatiquement par l'interface
utilisateur "customize" dans une utilisation mal comprise.
--
__Pascal Bourguignon__ http://www.informatimago.com/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d? s++:++ a+ C+++ UL++++ P--- L+++ E+++ W++ N+++ o-- K- w---
O- M++ V PS PE++ Y++ PGP t+ 5+ X++ R !tv b+++ DI++++ D++
G e+++ h+ r-- z?
------END GEEK CODE BLOCK------
Ha, ok. Je ne connaissais pas. Je dois d'ailleurs bien avouer
que je n'utilise jamais Customize, et que je connais donc très
mal la customization (via Customize).
--drkm