¿Y para qué se pueden usar?
(interactive "p")
toma un argumento numérico de la universal argument
derecha? Y el argumento universal es solo un int de cualquier manera, entonces, ¿qué hace el capital (interactive "P")
?
fuente
¿Y para qué se pueden usar?
(interactive "p")
toma un argumento numérico de la universal argument
derecha? Y el argumento universal es solo un int de cualquier manera, entonces, ¿qué hace el capital (interactive "P")
?
Es difícil de creer que la gente describió esto aquí sin darle enlaces a las propias descripciones de Emacs sobre esto:
En el manual de Emacs, argumentos de nodo .
En el manual de Elisp, Argumentos de comando de prefijo de nodo .
"Haz Emacs!": C-h i
, Elegir un manuali prefix argument RET
.
En pocas palabras, aunque otras respuestas aquí lo dicen bastante bien, y se describe en detalle en el manual:
El argumento de prefijo "en bruto" proporciona valores Lisp de diferentes tipos, y en particular distingue si el usuario realmente utilizó un argumento de prefijo (de cualquier tipo).
Al usarlo, un programa puede distinguir si el usuario utiliza uno de { -
, M--
, C--
} o uno de { M-- 1
, C-- 1
, C-u -1
} (ambos de los cuales tienen el mismo valor prefijo numérico de -1
), y distinguir si s? Lo utilizan C-u C-u
o uno de { M-16
, C-16
, C-u 16
} (ambos tienen un valor numérico 16), entre muchas otras distinciones.
Pero la distinción más importante es nil
vs no nil
: muchos comandos actúan de manera diferente dependiendo de si el usuario utiliza un prefijo arg.
El prefijo arg "numérico" es realmente el valor que la función prefix-numeric-value
devuelve cuando se aplica al prefijo raw arg. IOW, es mejor considerarlo como un mapeo desde la interacción real del usuario sin procesar a un entero.
No se puede decir si el usuario utiliza realmente un argumento prefijo, ya que el valor por defecto sin argumento prefijo se asigna al número entero 1, tal como lo hace el uso de C-u 1
, M-1
o C-1
.
Cuando se usa el Código interactivo de prefijo sin formato "P"
, el argumento se pasa tal cual mientras que "p"
convierte el argumento en un número.
Después de evaluar el elisp a continuación, pruebe C-u M-x my/fn-with-num-arg
y luego C-u M-x my/fn-with-raw-arg
vea la diferencia porque C-u
pasa un argumento de lista (4)
.
(defun my/debug-fn (arg)
(let ((msg))
(if (numberp arg)
(setq msg (format "Argument is number %s. " (pp arg)))
(setq msg "Argument is not a number. "))
(if (listp arg)
(setq msg (concat msg (format "Arg is %s." (pp arg))))
(setq msg (concat msg "Argument is not a list.")))
(message msg)))
(defun my/fn-with-num-arg (arg)
(interactive "p")
(my/debug-fn arg))
;; Result of C-u M-x my/fn-with-num-arg :
;; Argument is number 4. Argument is not a list.
(defun my/fn-with-raw-arg (arg)
(interactive "P")
(my/debug-fn arg))
;; Result of C-u M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is (4)
;; .
También el argumento predeterminado es 1
para argumento numérico ( "p"
) pero predeterminado para nil
o ()
para argumento sin formato ( "P"
).
Mis pocos centavos: a veces, el factor decisivo para usar "p"
o no "P"
es si desea que el argumento predeterminado sea 1
o nil
.
;; Result of M-x my/fn-with-num-arg :
;; Argument is number 1. Argument is not a list.
;; Result of M-x my/fn-with-raw-arg :
;; Argument is not a number. Arg is nil.
nil
que1
, pero nunca que tener un envoltorioint
es preferible a uno sin envolverint
. (No puedo votar hasta que obtenga 15 puntos, por cierto).nil
o no).Solo para agregar un poco más de detalle a la respuesta de @ kaushalmodi (y un caso de prueba útil):
El argumento sin formato le permite distinguir entre argumentos provistos con
universal-argument
ydigit-argument
.Con un prefijo numérico arg no hay forma de distinguir el argumento universal
C-u
de un prefijo arg de 4 (es decirC-4
). Con el argumento prima éstos son diferentes:(4)
vs4
.Lo mismo se aplica con
negative-argument
. Como argumento en bruto puedes distinguir entreC--
yC-- 1
: el primero te dará-
mientras que el segundo-1
. Cuando se convierte a un argumento numérico, ambos lo serán-1
.Entonces, el beneficio de usar un argumento en bruto es que le da más valores posibles. Puede escribir comandos que se comporten de manera diferente dependiendo de cómo se especifique el argumento.
Como ejemplo, eche un vistazo a la cadena de documentación para
yank
. Este comando trataC-u
y de maneraC-4
diferente:fuente