Después de una respuesta a otra pregunta sobre el nuevo sistema de consejos :
En el estilo antiguo advice.el
, era posible manipular miembros individuales de la lista de argumentos de una función recomendada, sin hacer ninguna afirmación con respecto a aquellos miembros no tan manipulados. Por ejemplo, el siguiente consejo:
(defadvice ansi-term (around prompt-for-name last)
(let ((name (read-from-minibuffer "Tag: ")))
(and (not (string= name ""))
(ad-set-arg 1 (concat "Term: " name)))
ad-do-it))
permite la provisión (opcional) de un argumento de nombre de búfer para una ansi-term
llamada, mientras ansi-term
que todavía obtendrá su primer argumento al solicitar de acuerdo con su propia forma interactiva.
(Para referencia posterior, ansi-term
la firma de es (PROGRAM &optional BUFFER-NAME)
, y su forma interactiva solicita PROGRAMA con varios valores predeterminados posibles, pero no hace nada con respecto a BUFFER-NAME).
No estoy seguro de si esto es posible o no en nadvice.el
. Si es así, no estoy seguro de cómo se puede hacer. He encontrado un par de formas de reemplazar la lista de argumentos de una función recomendada.
Por ejemplo, de * info * (elisp) Combinadores de consejos :
`:filter-args' Call FUNCTION first and use the result (which should be a list) as the new arguments to pass to the old function. More specifically, the composition of the two functions behaves like: (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))
Otros combinadores proporcionan capacidades similares, y el hilo común entre ellos es que, si bien la lista de argumentos de una función puede ser reemplazada, truncada, extendida, etc., no hay una forma aparente para que el consejo de la función modifique el argumento en una posición dada en la lista sin afirmando cualquier cosa sobre el resto .
En el caso en discusión, parece imposible que el autor del consejo pase ansi-term
solo un nombre de búfer, porque no es posible construir una lista que tenga un valor en la posición 1 pero nada, ni siquiera nil
, en la posición 0. En el caso general, Parece imposible para el autor del consejo modificar arbitrariamente los argumentos más allá de la posición 0.
Esto parece desafortunado porque, para producir un efecto similar, es necesario copiar y pegar el código: específicamente, o puedo copiar ansi-term
el formulario interactivo y extenderlo a mi gusto, o puedo copiarlo por ansi-term
completo y extenderlo de la misma manera. En cualquier caso, ahora debo redefinir parte de la distribución Emacs Lisp en mi archivo init, lo que me parece indeseable en términos de durabilidad y estética.
Mi pregunta, entonces, es: ¿se puede hacer este tipo de lista de argumentos nadvice.el
? ¿Si es así, cómo?
Respuestas:
Por el contrario, creo que sería una buena idea copiar y pegar la forma interactiva de la función recomendada, aunque en realidad no tiene que hacerlo aquí.
Leí tu pregunta de arriba a abajo. Cuando llegué al bloque de código, supuse que su consejo probablemente está cambiando el nombre del búfer. Pero no lo supe hasta que luego proporcionaste la firma como comentario.
De hecho, nada es menos nada que nada. :-) Pero eso no es relevante aquí.
Como puede ver en la documentación que citó, el valor devuelto por el aviso se utiliza como argumento para la función recomendada. El valor de retorno debe ser una lista de todos los argumentos, no solo los que han cambiado.
Manteniéndose lo más cerca posible del viejo consejo, esto es lo que tendría que hacer usando
nadvice
:Pero le recomiendo que defina los consejos de esta manera:
Esta variante en realidad se explica por sí misma.
fuente
args
lista en caso de una llamada como(ansi-term "foo")
, de lo contrario,(setf (nth 1 args)...
generaría un error.buffer-name
es obligatorio.:filter-args
consejo obtiene un único argumento que es una lista de argumentos para la función recomendada, por lo que la primera variante debería caer&rest
y la segunda variante tendría que usar algún tipo de construcción de desestructuración para obtener buenos nombres.Así es como lo haría:
mientras yo fui quien presentó
:filter-args
, personalmente encuentro que rara vez es conveniente.fuente