diff options
| author | David Arroyo Menéndez <davidam@gmail.com> | 2026-03-02 14:25:07 +0100 |
|---|---|---|
| committer | David Arroyo Menéndez <davidam@gmail.com> | 2026-03-02 14:25:07 +0100 |
| commit | 159790f1daaaa9bbea67f38ab837d8d689f6c304 (patch) | |
| tree | fecd3340e0748cb06aa739e37d0aebc9737c57f5 | |
| parent | 8f0d7537e1ffe91d6d96083aa613b81b1171f0aa (diff) | |
deleting object files: emacs-lisp-intro-es.pdf emacs-lisp-intro-es.html
| -rw-r--r-- | emacs-lisp-intro-es.html | 26359 | ||||
| -rw-r--r-- | emacs-lisp-intro-es.pdf | bin | 1031086 -> 0 bytes |
2 files changed, 0 insertions, 26359 deletions
diff --git a/emacs-lisp-intro-es.html b/emacs-lisp-intro-es.html deleted file mode 100644 index d441658..0000000 --- a/emacs-lisp-intro-es.html +++ /dev/null @@ -1,26359 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<!-- Esto es una Introduccio'n a la Programacio'n en Emacs Lisp, -para personas que no son programadoras. -Traducido desde la edicio'n 3.10. -Copyright (C) 2015 Libremanuals. - - -Publicado por el: - - -Libremanuals, http://www.libremanuals.net/ - - - -ISBN: 978-84-608-5935-2 - -Permission is granted to copy, distribute and/or modify this document under -the terms of the GNU Free Documentation License, Version 1.3 or any later -version published by the Free Software Foundation; there being no Invariant -Section, with the Front-Cover Texts being "A GNU Manual", and with the -Back-Cover Texts as in (a) below. A copy of the license is included in the -section entitled "GNU Free Documentation License". - -(a) The FSF's Back-Cover Text is: "You have the freedom to copy and modify -this GNU manual. Buying copies from the FSF supports it in developing GNU -and promoting software freedom." - --> -<!-- Created on el 28 febrero 2026 by texi2html 5.0 -texi2html was written by: - Lionel Cons <Lionel.Cons@cern.ch> (original author) - Karl Berry <karl@freefriends.org> - Olaf Bachmann <obachman@mathematik.uni-kl.de> - and many others. -Maintained by: Many creative people. -Send bugs and suggestions to <texi2html-bug@nongnu.org> ---> -<head> -<title>Programación en Emacs Lisp</title> - -<meta name="description" content="Programación en Emacs Lisp"> -<meta name="keywords" content="Programación en Emacs Lisp"> -<meta name="resource-type" content="document"> -<meta name="distribution" content="global"> -<meta name="Generator" content="texi2html 5.0"> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<style type="text/css"> -<!-- -a.summary-letter {text-decoration: none} -blockquote.smallquotation {font-size: smaller} -div.display {margin-left: 3.2em} -div.example {margin-left: 3.2em} -div.lisp {margin-left: 3.2em} -div.smalldisplay {margin-left: 3.2em} -div.smallexample {margin-left: 3.2em} -div.smalllisp {margin-left: 3.2em} -pre.display {font-family: serif} -pre.format {font-family: serif} -pre.menu-comment {font-family: serif} -pre.menu-preformatted {font-family: serif} -pre.smalldisplay {font-family: serif; font-size: smaller} -pre.smallexample {font-size: smaller} -pre.smallformat {font-family: serif; font-size: smaller} -pre.smalllisp {font-size: smaller} -span.nocodebreak {white-space:pre} -span.nolinebreak {white-space:pre} -span.roman {font-family:serif; font-weight:normal} -span.sansserif {font-family:sans-serif; font-weight:normal} -ul.no-bullet {list-style: none} ---> -</style> - - -</head> - -<body lang="es" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"> - -<br> -<br> -<br> -<br> -<br> -<br> -<h1 class="titlefont">Una Introducción a la</h1> -<br> -<br> -<h1 class="titlefont">Programación en Emacs Lisp</h1> -<br> -<br> -<p align="center">Revisada la tercera edición -</p><br> -<br> -<br> -<br> -<p align="center">Escrito por Robert J. Chassell. Traducido por David Arroyo Menéndez. -</p> - -<p>Esto es una <cite>Introducción a la Programación en Emacs Lisp</cite>, -para personas que no son programadoras. -</p><br> -<p>Traducido desde la edición 3.10. -</p><br> -<p>Copyright © 2015 Libremanuals. -</p><br> - - -<p>Publicado por el: -</p> -<div class="example"> -<pre class="example">Libremanuals, @hfill <a href="http://www.libremanuals.net/">http://www.libremanuals.net/</a> - -</pre></div> - -<br> -<p>ISBN: 978-84-608-5935-2 -</p> -<p>Permission is granted to copy, distribute and/or modify this document under -the terms of the GNU Free Documentation License, Version 1.3 or any later -version published by the Free Software Foundation; there being no Invariant -Section, with the Front-Cover Texts being “A GNU Manual”, and with the -Back-Cover Texts as in (a) below. A copy of the license is included in the -section entitled “GNU Free Documentation License”. -</p> -<p>(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify -this GNU manual. Buying copies from the FSF supports it in developing GNU -and promoting software freedom.” -</p><hr> -<a name="Top"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[ < ]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-Introduccion-a-la-Programacion-en-Emacs-Lisp"></a> -<h1 class="top">Una Introducción a la Programación en Emacs Lisp</h1> - -<p>Esto es una <cite>Introducción a la Programación en Emacs Lisp</cite>, -para personas que no son programadoras. -</p><br> -<p>Traducido desde la edición 3.10. -</p><br> -<p>Copyright © 2015 Libremanuals. -</p><br> - - -<p>Publicado por el: -</p> -<div class="example"> -<pre class="example">Libremanuals, @hfill <a href="http://www.libremanuals.net/">http://www.libremanuals.net/</a> - -</pre></div> - -<br> -<p>ISBN: 978-84-608-5935-2 -</p> -<p>Permission is granted to copy, distribute and/or modify this document under -the terms of the GNU Free Documentation License, Version 1.3 or any later -version published by the Free Software Foundation; there being no Invariant -Section, with the Front-Cover Texts being “A GNU Manual”, and with the -Back-Cover Texts as in (a) below. A copy of the license is included in the -section entitled “GNU Free Documentation License”. -</p> -<p>(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify -this GNU manual. Buying copies from the FSF supports it in developing GNU -and promoting software freedom.” -</p> -<p>Este menú maestro primero lista cada capítulo e -indexa; entonces lista cada nodo en cada capítulo. -</p> - - - - -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Prefacio">Prefacio</a></td><td> </td><td align="left" valign="top"> Qué buscas -</td></tr> -<tr><td align="left" valign="top"><a href="#Procesamiento-de-listas">1 Procesamiento de listas</a></td><td> </td><td align="left" valign="top"> ¿Qué es Lisp? -</td></tr> -<tr><td align="left" valign="top"><a href="#Practicando-evaluaci_00f3n">2 Practicando evaluación</a></td><td> </td><td align="left" valign="top"> Ejecutando varios programas. -</td></tr> -<tr><td align="left" valign="top"><a href="#Escribiendo-funciones">3 Cómo escribir definiciones de funciones</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers">4 Unas pocas funciones de buffer relacionadas</a></td><td> </td><td align="left" valign="top"> Explorando unas pocas funciones - relacionadas con los búffers. -</td></tr> -<tr><td align="left" valign="top"><a href="#M_00e1s-complejidad">5 Unas pocas funciones más complejas</a></td><td> </td><td align="left" valign="top"> Unas pocas, incluso más complejas funciones. -</td></tr> -<tr><td align="left" valign="top"><a href="#Encogiendo-y-extendiendo">6 Encogiendo y extendiendo</a></td><td> </td><td align="left" valign="top"> Restringiéndote a tí y a Emacs a una - región. -</td></tr> -<tr><td align="left" valign="top"><a href="#Car-cdr-y-cons">7 <code>car</code>, <code>cdr</code>, <code>cons</code>: Funciones fundamentales</a></td><td> </td><td align="left" valign="top"> Funciones fundamentales en Lisp. -</td></tr> -<tr><td align="left" valign="top"><a href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></td><td> </td><td align="left" valign="top"> Eliminando texto y guardándolo. -</td></tr> -<tr><td align="left" valign="top"><a href="#Implementaci_00f3n-de-listas">9 Cómo las listas se implementan</a></td><td> </td><td align="left" valign="top"> Cómo las listas se implementan en el - ordenador -</td></tr> -<tr><td align="left" valign="top"><a href="#Pegando">10 Pegando texto</a></td><td> </td><td align="left" valign="top"> Pegando texto almacenado. -</td></tr> -<tr><td align="left" valign="top"><a href="#Bucles-y-recursi_00f3n">11 Bucles y recursión</a></td><td> </td><td align="left" valign="top"> Cómo repetir un proceso. -</td></tr> -<tr><td align="left" valign="top"><a href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Contando-palabras">13 Contando: repetición y regexps</a></td><td> </td><td align="left" valign="top"> Una revisión de repetición y regexps. -</td></tr> -<tr><td align="left" valign="top"><a href="#Palabras-en-una-funci_00f3n">14 Contando palabras en una <code>defun</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Leyendo-un-grafo">15 Leyendo un grafo</a></td><td> </td><td align="left" valign="top"> Un grafo prototipo imprimiendo una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#Inicializaci_00f3n-de-Emacs">16 Tu fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td align="left" valign="top"> Cómo escribir un fichero ‘<tt>.emacs</tt>’. -</td></tr> -<tr><td align="left" valign="top"><a href="#Depurando">17 Depurando</a></td><td> </td><td align="left" valign="top"> Cómo ejecutar los depuradores de Emacs Lisp. -</td></tr> -<tr><td align="left" valign="top"><a href="#Conclusi_00f3n">18 Conclusión</a></td><td> </td><td align="left" valign="top"> Ahora tienes las bases. -</td></tr> -<tr><td align="left" valign="top"><a href="#the_002dthe">Appendix A La función <code>the-the</code></a></td><td> </td><td align="left" valign="top"> Un apéndice: cómo encontrar palabras - reduplicadas. -</td></tr> -<tr><td align="left" valign="top"><a href="#Kill-Ring">Appendix B Manejando el anillo de la muerte</a></td><td> </td><td align="left" valign="top"> Un apéndice: cómo el kill ring funciona. -</td></tr> -<tr><td align="left" valign="top"><a href="#Grafo-completo">Appendix C Un grafo con ejes etiquetados</a></td><td> </td><td align="left" valign="top"> Cómo crear un grafo con ejes etiquetados. -</td></tr> -<tr><td align="left" valign="top"><a href="#Software-Libre-y-Manuales-Libres">Appendix D Software Libre y Manuales Libres</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#GNU-Free-Documentation-License">Appendix E GNU Free Documentation License</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#g_t_00cdndice">Índice</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Acerca-del-Autor">Acerca del Autor</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> — El Listado Detallado de Nodos — - - - -Prefacio - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Por-qu_00e9">¿Por qué estudiar Emacs Lisp?</a></td><td> </td><td align="left" valign="top"> ¿Por qué aprender Emacs Lisp? -</td></tr> -<tr><td align="left" valign="top"><a href="#Leyendo-este-texto">Leyendo este texto</a></td><td> </td><td align="left" valign="top"> Leer, ganar familiaridad, coger hábitos... -</td></tr> -<tr><td align="left" valign="top"><a href="#Quien-eres">Para quien está esto escrito</a></td><td> </td><td align="left" valign="top"> Para quien es este escrito. -</td></tr> -<tr><td align="left" valign="top"><a href="#Historia-de-Lisp">Historia de Lisp</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Nota-para-principiantes">Una nota para principiantes</a></td><td> </td><td align="left" valign="top"> Tu puedes leer esto como un novato -</td></tr> -<tr><td align="left" valign="top"><a href="#Se-agradece">Se agradece</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Procesamiento de listas - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Listas-Lisp">1.1 Listas Lisp</a></td><td> </td><td align="left" valign="top"> ¿Qué son listas? -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></td><td> </td><td align="left" valign="top"> Cualquier lista en Lisp es un programa listo - para ejecutarse. -</td></tr> -<tr><td align="left" valign="top"><a href="#Creando-errores">1.3 Generar un mensaje de error</a></td><td> </td><td align="left" valign="top"> Generando un mensaje de error. -</td></tr> -<tr><td align="left" valign="top"><a href="#Nombres-y-definiciones">1.4 Nombres de símbolos y definiciones de funciones</a></td><td> </td><td align="left" valign="top"> Nombres de símbolos y - definiciones de función. -</td></tr> -<tr><td align="left" valign="top"><a href="#Interpr_00e9te-Lisp">1.5 El intérprete Lisp</a></td><td> </td><td align="left" valign="top"> Qué hace el intérprete Lisp. -</td></tr> -<tr><td align="left" valign="top"><a href="#Evaluaci_00f3n">1.6 Evaluación</a></td><td> </td><td align="left" valign="top"> Ejecutando un programa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Variables">1.7 Variables</a></td><td> </td><td align="left" valign="top"> Devolviendo un valor desde una variable. -</td></tr> -<tr><td align="left" valign="top"><a href="#Argumentos">1.8 Argumentos</a></td><td> </td><td align="left" valign="top"> Pasando información a una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#set-y-setq">1.9 Configurando el valor de una variable</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Resumen">1.10 Resumen</a></td><td> </td><td align="left" valign="top"> Los mayores puntos. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-de-mensajes-de-error">1.11 Ejercicios</a></td><td> </td><td align="left" valign="top"> Ejercicios de mensajes de error -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Listas Lisp - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Listas-de-n_00fameros">Números, listas dentro de listas</a></td><td> </td><td align="left" valign="top"> Lista tener números, otras listas, en ellas. -</td></tr> -<tr><td align="left" valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td><td> </td><td align="left" valign="top"> Entidades Elementales. -</td></tr> -<tr><td align="left" valign="top"><a href="#Espacios-en-blanco-en-listas">1.1.2 Espacios en blanco en listas</a></td><td> </td><td align="left" valign="top"> Formatenado listas para ser legibles. -</td></tr> -<tr><td align="left" valign="top"><a href="#Escribiendo-listas">1.1.3 GNU Emacs te ayuda a escribir listas</a></td><td> </td><td align="left" valign="top"> Cómo GNU Emacs te ayuda a escribir listas. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -El intérprete Lisp - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Complicaciones">Complicaciones</a></td><td> </td><td align="left" valign="top"> Variables, formas especiales, Listas. -</td></tr> -<tr><td align="left" valign="top"><a href="#Compilaci_00f3n-de-bytes">1.5.1 Compilación de bytes</a></td><td> </td><td align="left" valign="top"> Especialmente procesando código por la - velocidad. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Evaluación - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#C_00f3mo-el-int_00e9rprete-act_00faa">Cómo el intérprete actúa</a></td><td> </td><td align="left" valign="top"> Devolver y Efectos Colaterales... -</td></tr> -<tr><td align="left" valign="top"><a href="#Evaluando-listas-propias">1.6.1 Evaluando listas propias</a></td><td> </td><td align="left" valign="top"> Listas con listas... -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Variables - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Ejemplo-de-rellenar-columna"><code>fill-column</code>, un ejemplo de variable</a></td><td> </td><td align="left" valign="top"> Ejemplo de rellenar columna -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-vac_00eda">1.7.1 Mensaje de error de un símbolo sin una función</a></td><td> </td><td align="left" valign="top"> El mensaje de error para un - símbolo sin una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#Variable-vac_00eda">1.7.2 Mensaje de error de un símbolo sin un valor</a></td><td> </td><td align="left" valign="top"> El mensaje de error para un - símbolo sin un valor. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Argumentos - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Tipos-de-datos">1.8.1 Tipos de argumentos de datos</a></td><td> </td><td align="left" valign="top"> Tipos de datos pasados a una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#Argumentos-como-variables-o-listas">1.8.2 Un argumento como el valor de una variable o lista</a></td><td> </td><td align="left" valign="top"> Un argumento puede ser el valor de - una variable o lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#N_00famero-de-variables-de-argumentos">1.8.3 Número de variables de argumentos</a></td><td> </td><td align="left" valign="top"> Algunas funciones pueden tomar un - número variable de argumentos. -</td></tr> -<tr><td align="left" valign="top"><a href="#Tipo-incorrecto-de-argumento">1.8.4 Usando el tipo incorrecto de objeto como un argumento</a></td><td> </td><td align="left" valign="top"> Pasando un argumento del tipo incorrecto a - una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#message">1.8.5 La función <code>message</code></a></td><td> </td><td align="left" valign="top"> Una función útil para enviar mensajes. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Configurando el valor de una variable - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Usando-set">1.9.1 Usando <code>set</code></a></td><td> </td><td align="left" valign="top"> Configurando valores. -</td></tr> -<tr><td align="left" valign="top"><a href="#Usando-setq">1.9.2 Usando <code>setq</code></a></td><td> </td><td align="left" valign="top"> Configurando un valor citado. -</td></tr> -<tr><td align="left" valign="top"><a href="#Contando">1.9.3 Contando</a></td><td> </td><td align="left" valign="top"> Usando <code>setq</code> para contar. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Practicando evaluación - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#C_00f3mo-evaluar">Cómo evaluar</a></td><td> </td><td align="left" valign="top"> Escribiendo comandos de edición o con - <kbd>C-x C-e</kbd>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Nombres-de-b_00faffer">2.1 Nombres de búffer</a></td><td> </td><td align="left" valign="top"> Buffers y ficheros son diferentes. -</td></tr> -<tr><td align="left" valign="top"><a href="#Obteniendo-b_00faffers">2.2 Obteniendo búffers</a></td><td> </td><td align="left" valign="top"> Obteniendo un buffer por sí - mismo, no solamente su nombre. -</td></tr> -<tr><td align="left" valign="top"><a href="#Cambiando-b_00faffers">2.3 Cambiando búffers</a></td><td> </td><td align="left" valign="top"> Cómo cambiar a otro buffer. -</td></tr> -<tr><td align="left" valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td><td> </td><td align="left" valign="top"> Dónde el punto está - localizado y el tamaño del - buffer. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-evaluaci_00f3n">2.5 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio de evaluación -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Cómo escribir definiciones de funciones - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Funciones-primitivas">Una vía acerca de funciones primitivas</a></td><td> </td><td align="left" valign="top"> Funciones primitivas -</td></tr> -<tr><td align="left" valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Instalar">3.2 Instalar una definición de función</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Interactive">3.3 Crear una función interactive</a></td><td> </td><td align="left" valign="top"> Creando una función interactive. -</td></tr> -<tr><td align="left" valign="top"><a href="#Opciones-de-interactive_002e">3.4 Diferentes opciones para <code>interactive</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Instalaci_00f3n-Permanente">3.5 Instalar código permanentemente</a></td><td> </td><td align="left" valign="top"> Instalando código permanentemente. -</td></tr> -<tr><td align="left" valign="top"><a href="#let">3.6 <code>let</code></a></td><td> </td><td align="left" valign="top"> Creando e inicializando variables locales. -</td></tr> -<tr><td align="left" valign="top"><a href="#if">3.7 La forma especial <code>if</code></a></td><td> </td><td align="left" valign="top"> ¿Y qué si? -</td></tr> -<tr><td align="left" valign="top"><a href="#else">3.8 Expresiones if–then–else</a></td><td> </td><td align="left" valign="top"> Expresiones If–then–else. -</td></tr> -<tr><td align="left" valign="top"><a href="#Verdad-y-falsedad">3.9 Verdad y falsedad en Emacs Lisp</a></td><td> </td><td align="left" valign="top"> Que considera Lisp falso y cierto. -</td></tr> -<tr><td align="left" valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td><td> </td><td align="left" valign="top"> Guardando la traza del punto, la marca, y el - buffer. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisar">3.11 Revisar</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-defun">3.12 Ejercicios</a></td><td> </td><td align="left" valign="top"> Ejercicios defun -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Instalar una definición de función - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Efecto-de-instalaci_00f3n">El efecto de instalación</a></td><td> </td><td align="left" valign="top"> Efecto de instalación -</td></tr> -<tr><td align="left" valign="top"><a href="#Cambiar-un-defun">3.2.1 Cambiar una definición de función</a></td><td> </td><td align="left" valign="top"> Cómo cambiar una definición de función -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Crear una función interactive - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#multiply_002dby_002dseven-interactivo">Un <code>multiply-by-seven</code> interactivo, Un resumen</a></td><td> </td><td align="left" valign="top"> Un resumen -</td></tr> -<tr><td align="left" valign="top"><a href="#multiply_002dby_002dseven-en-detalle">3.3.1 <code>multiplicar-por-siente</code> interactivo</a></td><td> </td><td align="left" valign="top"> La versión interactive. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>let</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Prevenir-confusi_00f3n"><code>let</code> evita confusiones</a></td><td> </td><td align="left" valign="top"> Prevenir confusión -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-de-la-expresi_00f3n-let">3.6.1 Las partes de una expresión <code>let</code></a></td><td> </td><td align="left" valign="top"> Partes de la expresión let -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-de-expresi_00f3n-let">3.6.2 Ejemplo de Expresión <code>let</code></a></td><td> </td><td align="left" valign="top"> Ejemplo de expresión let -</td></tr> -<tr><td align="left" valign="top"><a href="#Variables-let-inicializadas">3.6.3 Variables sin inicializar en un sentencia <code>let</code></a></td><td> </td><td align="left" valign="top"> Variables let inicializadas -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La forma especial <code>if</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#if-en-m_00e1s-detalle"><code>if</code> en más detalle</a></td><td> </td><td align="left" valign="top"> if en más detalle -</td></tr> -<tr><td align="left" valign="top"><a href="#tipo_002dde_002danimal-en-detalle">3.7.1 La función <code>tipo-de-animal</code> en detalle</a></td><td> </td><td align="left" valign="top"> Un ejemplo de una expresión <code>if</code>. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Verdad y falsedad en Emacs Lisp - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#nil-explicado">Una explicación de <code>nil</code></a></td><td> </td><td align="left" valign="top"> <code>nil</code> tiene dos significados. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>save-excursion</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Punto-y-marca">Punto y Marca</a></td><td> </td><td align="left" valign="top"> Una revisión de varias localizaciones. -</td></tr> -<tr><td align="left" valign="top"><a href="#Plantilla-para-save_002dexcursion">3.10.1 Plantilla para una expresión <code>save-excursion</code></a></td><td> </td><td align="left" valign="top"> Plantilla para save-excursion -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Unas pocas funciones de buffer relacionadas - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td><td> </td><td align="left" valign="top"> Cómo encontrar más información. -</td></tr> -<tr><td align="left" valign="top"><a href="#simplified_002dbeginning_002dof_002dbuffer">4.2 Una definición simplificada de <code>beginning-of-buffer</code></a></td><td> </td><td align="left" valign="top"> Muestra <code>goto-char</code>, - <code>point-min</code>, y <code>push-mark</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#mark_002dwhole_002dbuffer">4.3 La definición de <code>mark-whole-buffer</code></a></td><td> </td><td align="left" valign="top"> Casi lo mismo que <code>beginning-of-buffer</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#append_002dto_002dbuffer">4.4 La definición de <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Usa <code>save-excursion</code> y - <code>insert-buffer-substring</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisa-lo-relacionado-con-el-b_00faffer">4.5 Revisar</a></td><td> </td><td align="left" valign="top"> Revisa -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-de-b_00faffer">4.6 Ejercicios</a></td><td> </td><td align="left" valign="top"> Ejercicios de búffer -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La definición de <code>mark-whole-buffer</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#resumen-de-mark_002dwhole_002dbuffer">Un resumen de <code>mark-whole-buffer</code></a></td><td> </td><td align="left" valign="top"> resumen de mark-whole-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#Cuerpo-de-mark_002dwhole_002dbuffer">4.3.1 Cuerpo de <code>mark-whole-buffer</code></a></td><td> </td><td align="left" valign="top"> Solo tres líneas de código. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La definición de <code>append-to-buffer</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#resumen-de-append_002dto_002dbuffer">Un resumen de <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> resumen de append-to-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#append-interactivo">4.4.1 La expresión interactiva <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Una expresión interactiva de dos partes. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-append_002dto_002dbuffer">4.4.2 El cuerpo de <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Incorpora una expresión <code>let</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#append-save_002dexcursion">4.4.3 <code>save-excursion</code> en <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Cómo <code>save-excursion</code> trabaja. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Unas pocas funciones más complejas - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#copy_002dto_002dbuffer">5.1 La definición de <code>copy-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Con <code>set-buffer</code>, - <code>get-buffer-create</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#insert_002dbuffer">5.2 La definición de <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Solo lectura, y con <code>or</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#beginning_002dof_002dbuffer">5.3 Definición completa de <code>beginning-of-buffer</code></a></td><td> </td><td align="left" valign="top"> Muestra <code>goto-char</code>, <code>point-min</code>, y - <code>push-mark</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisar-el-segundo-b_00faffer-relacionado">5.4 Revisar</a></td><td> </td><td align="left" valign="top"> Revisar el segundo búffer - relacionado -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-opcional">5.5 Ejercicio de argumento <code>opcional</code></a></td><td> </td><td align="left" valign="top"> Ejercicio opcional -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La definición de <code>insert-buffer</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#c_00f3digo-insert_002dbuffer">El código para <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> código insert-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#insert_002dbuffer-interactivo">5.2.1 La expresión interactiva en <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Cuando tu puedes leer, pero no escribir. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-insert_002dbuffer">5.2.2 El cuerpo de la función <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> El cuerpo tiene un <code>or</code> y un <code>let</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#si-y-o">5.2.3 <code>insert-buffer</code> con un <code>if</code> en vez de un <code>or</code></a></td><td> </td><td align="left" valign="top"> Usando un <code>if</code> en vez de un <code>or</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Insertar-o">5.2.4 El <code>or</code> en el cuerpo</a></td><td> </td><td align="left" valign="top"> Cómo la expresión <code>or</code> funciona. -</td></tr> -<tr><td align="left" valign="top"><a href="#Insertar-let">5.2.5 La expresión <code>let</code> en <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Dos expresiones <code>save-excursion</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Nuevo-insert_002dbuffer">5.2.6 Nuevo cuerpo para <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Nuevo insert-buffer -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La expresión interactiva en <code>insert-buffer</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#B_00faffer-solo-lectura">Un búffer de solo lectura</a></td><td> </td><td align="left" valign="top"> Cuando un buffer no puede ser modificado. -</td></tr> -<tr><td align="left" valign="top"><a href="#b-para-interactivo">‘<samp>b</samp>’ en una expresión interactiva</a></td><td> </td><td align="left" valign="top"> Un buffer existe o además su nombre. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Definición completa de <code>beginning-of-buffer</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Argumentos-opcionales">5.3.1 Argumentos opcionales</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#beginning_002dof_002dbuffer-opt-arg">5.3.2 <code>beginning-of-buffer</code> con un argumento</a></td><td> </td><td align="left" valign="top"> Ejemplo con argumento opcional. -</td></tr> -<tr><td align="left" valign="top"><a href="#Completo-beginning_002dof_002dbuffer">5.3.3 El <code>beginning-of-buffer</code> completo</a></td><td> </td><td align="left" valign="top"> Completo beginning-of-buffer -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>beginning-of-buffer</code> con un argumento - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Desenmara_00f1ar-beginning_002dof_002dbuffer">Desenmarañar <code>beginning-of-buffer</code></a></td><td> </td><td align="left" valign="top"> Desenmarañar beginning-of-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#El-caso-del-buffer-largo">Qué ocurre en un búffer largo</a></td><td> </td><td align="left" valign="top"> El caso del buffer largo -</td></tr> -<tr><td align="left" valign="top"><a href="#Peque_00f1o-caso-de-b_00faffer">Qué ocurre en un búffer pequeño</a></td><td> </td><td align="left" valign="top"> Pequeño caso de búffer -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Encogiendo y extendiendo - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Ventajas-de-encoger">Las ventajas de encoger</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#save_002drestriction">6.1 La forma especial <code>save-restriction</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#what_002dline">6.2 <code>what-line</code></a></td><td> </td><td align="left" valign="top"> El número de la línea que - apunta está activa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-narrow">6.3 Ejercicio de encoger</a></td><td> </td><td align="left" valign="top"> Ejercicio narrow -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>car</code>, <code>cdr</code>, <code>cons</code>: Funciones fundamentales - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Nombres-extra_00f1os">Nombres extraños</a></td><td> </td><td align="left" valign="top"> Un lado histórico: ¿por qué - los nombres extraños? -</td></tr> -<tr><td align="left" valign="top"><a href="#car-y-cdr">7.1 <code>car</code> y <code>cdr</code></a></td><td> </td><td align="left" valign="top"> Funciones para extraer parte de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#cons">7.2 <code>cons</code></a></td><td> </td><td align="left" valign="top"> Construyendo una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#nthcdr">7.3 <code>nthcdr</code></a></td><td> </td><td align="left" valign="top"> Llamando <code>cdr</code> repetidamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#nth">7.4 <code>nth</code></a></td><td> </td><td align="left" valign="top"> nth -</td></tr> -<tr><td align="left" valign="top"><a href="#setcar">7.5 <code>setcar</code></a></td><td> </td><td align="left" valign="top"> Cambiando el primer elemento de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#setcdr">7.6 <code>setcdr</code></a></td><td> </td><td align="left" valign="top"> Cambiando el resto de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-cons">7.7 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio cons -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>cons</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Construir-una-lista">Construir una lista</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#length">7.2.1 Encuentra el tamaño de una lista: <code>length</code></a></td><td> </td><td align="left" valign="top"> Cómo encontrar el tamaño de una lista. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Cortando y almacenando texto - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Almacenando-Texto">Almacenando texto en una lista</a></td><td> </td><td align="left" valign="top"> El texto está almacenado en una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#zap_002dto_002dchar">8.1 <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> Cortando texto a un carácter. -</td></tr> -<tr><td align="left" valign="top"><a href="#kill_002dregion">8.2 <code>kill-region</code></a></td><td> </td><td align="left" valign="top"> Cortando texto de una región. -</td></tr> -<tr><td align="left" valign="top"><a href="#copy_002dregion_002das_002dkill">8.3 <code>copy-region-as-kill</code></a></td><td> </td><td align="left" valign="top"> Una definición para copiar texto. -</td></tr> -<tr><td align="left" valign="top"><a href="#Disgresi_00f3n-dentro-de-C">8.4 Disgresión dentro de C</a></td><td> </td><td align="left" valign="top"> Nota menor en macros del lenguaje de - programación C. -</td></tr> -<tr><td align="left" valign="top"><a href="#defvar">8.5 Inicializando una variable con <code>defvar</code></a></td><td> </td><td align="left" valign="top"> Cómo dar a una variable un valor inicial. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisi_00f3n-de-cons-y-search_002dfwd">8.6 Revisar</a></td><td> </td><td align="left" valign="top"> Revisión de cons y search-fwd -</td></tr> -<tr><td align="left" valign="top"><a href="#Buscar-ejercicios">8.7 Buscando ejercicios</a></td><td> </td><td align="left" valign="top"> Buscar ejercicios -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>zap-to-char</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Completar-zap_002dto_002dchar">La implementación completa <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> La implementación completa. -</td></tr> -<tr><td align="left" valign="top"><a href="#zap_002dto_002dchar-interactivo">8.1.1 La expresión <code>interactive</code></a></td><td> </td><td align="left" valign="top"> Una expresión interactiva de tres partes. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-zap_002dto_002dchar">8.1.2 El cuerpo de <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> Un resumen corto -</td></tr> -<tr><td align="left" valign="top"><a href="#search_002dforward">8.1.3 La función <code>search-forward</code></a></td><td> </td><td align="left" valign="top"> Cómo buscar una cadena. -</td></tr> -<tr><td align="left" valign="top"><a href="#progn">8.1.4 La forma especial <code>progn</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Resumiendo-zap_002dto_002dchar">8.1.5 Resumiendo <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> Usando <code>point</code> y <code>search-forward</code>. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>kill-region</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Completa-kill_002dregion">La definición completa <code>kill-region</code></a></td><td> </td><td align="left" valign="top"> La definición de función. -</td></tr> -<tr><td align="left" valign="top"><a href="#condition_002dcase">8.2.1 <code>condition-case</code></a></td><td> </td><td align="left" valign="top"> Tratando con un problema. -</td></tr> -<tr><td align="left" valign="top"><a href="#Macro-Lisp">8.2.2 Macro Lisp</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>copy-region-as-kill</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Completar-copy_002dregion_002das_002dkill">La definición de la función completa <code>copy-region-as-kill</code>.</a></td><td> </td><td align="left" valign="top"> La definición completa de función. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-copy_002dregion_002das_002dkill">8.3.1 El cuerpo de <code>copy-region-as-kill</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -El cuerpo de <code>copy-region-as-kill</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#last_002dcommand-_0026-this_002dcommand"><code>last-command</code> y <code>this-command</code></a></td><td> </td><td align="left" valign="top"> last-command & this-command -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-kill_002dappend">La función <code>kill-append</code></a></td><td> </td><td align="left" valign="top"> Función kill-append -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></td><td> </td><td align="left" valign="top"> Función kill-new -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Inicializando una variable con <code>defvar</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Mira-el-valor-actual-de-la-variable">Mirando el actual valor de una variable</a></td><td> </td><td align="left" valign="top"> Mira el valor actual de la variable -</td></tr> -<tr><td align="left" valign="top"><a href="#defvar-y-asterisk">8.5.1 <code>defvar</code> y un asterisco</a></td><td> </td><td align="left" valign="top"> defvar y asterisk -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Cómo las listas se implementan - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Listas-diagramadas">Listas diagramadas</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#S_00edmbolos-como-cajas">9.1 Símbolos como una caja con cajones</a></td><td> </td><td align="left" valign="top"> Explorando una metáfora poderosa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-Lista">9.2 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio Lista -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Pegando texto - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Resumen-del-anillo-de-la-muerte">10.1 Resumen del anillo de la muerte</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#kill_002dring_002dyank_002dpointer">10.2 La variable <code>kill-ring-yank-pointer</code></a></td><td> </td><td align="left" valign="top"> El anillo de la muerte es una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#pegar-Ejercicio-nthcdr">10.3 Ejercicios con <code>yank</code> y <code>nthcdr</code></a></td><td> </td><td align="left" valign="top"> La variable <code>kill-ring-yank-pointer</code>. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Bucles y recursión - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#while">11.1 <code>while</code></a></td><td> </td><td align="left" valign="top"> Causando un cierto código para repetir. -</td></tr> -<tr><td align="left" valign="top"><a href="#Dolist-y-dotimes">11.2 Ahorra tiempo: <code>dolist</code> y <code>dotimes</code></a></td><td> </td><td align="left" valign="top"> Dolist y dotimes -</td></tr> -<tr><td align="left" valign="top"><a href="#Recursi_00f3n">11.3 Recursión</a></td><td> </td><td align="left" valign="top"> Causando que una función se llame a - sí misma. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-Bucle">11.4 Ejercicio de bucles</a></td><td> </td><td align="left" valign="top"> Ejercicio de Bucle -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>while</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Bucles-while">Bucles con <code>while</code></a></td><td> </td><td align="left" valign="top"> Repetir tantas veces como el test devuelva - verdadero. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-de-bucle">11.1.1 Un bucle <code>while</code> y una lista</a></td><td> </td><td align="left" valign="top"> Un bucle <code>while</code> que usa una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002delements_002dof_002dlist">11.1.2 Un ejemplo: <code>imprimir-elementos-de-la-lista</code></a></td><td> </td><td align="left" valign="top"> Usos <code>while</code>, <code>car</code>, <code>cdr</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Incrementando-el-Bucle">11.1.3 Un bucle con un contaje incremental</a></td><td> </td><td align="left" valign="top"> Un bucle con un contador de incremento. -</td></tr> -<tr><td align="left" valign="top"><a href="#Incrementando-los-detalles-de-los-bucles">Detalles de un bucle que se incrementa</a></td><td> </td><td align="left" valign="top"> Incrementando los detalles de - los bucles -</td></tr> -<tr><td align="left" valign="top"><a href="#Bucle-que-se-decrementa">11.1.4 Bucle que decrementa</a></td><td> </td><td align="left" valign="top"> Un bucle con un decrementando contador. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Detalles de un bucle que se incrementa - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Ejemplo-de-Incremento">Ejemplo con contador incremental</a></td><td> </td><td align="left" valign="top"> Contando esquinas en un triángulo. -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-Inc-de-Ejemplo">Las partes de la definición de función</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-Inc-junto">Poniendo la definición de la función junta</a></td><td> </td><td align="left" valign="top"> Poniendo la definición de función junta. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Bucle que decrementa - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Ejemplo-de-Decremento">Ejemplo con el contador que se decrementa</a></td><td> </td><td align="left" valign="top"> Más piedras en la playa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-de-Ejemplo-Dec">Las partes de la definición de función</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-Dec-junto">Poniendo la definición de la función junta</a></td><td> </td><td align="left" valign="top"> Poniendo la definición de función junta. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Ahorra tiempo: <code>dolist</code> y <code>dotimes</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#dolist">La macro <code>dolist</code></a></td><td> </td><td align="left" valign="top"> dolist -</td></tr> -<tr><td align="left" valign="top"><a href="#dotimes">La macro <code>dotimes</code></a></td><td> </td><td align="left" valign="top"> dotimes -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Recursión - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Construyendo-robots">11.3.1 Construyendo robots: Extendiendo la metáfora</a></td><td> </td><td align="left" valign="top"> Mismo modelo, diferente número serie ... -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-de-definici_00f3n-recursiva">11.3.2 Las partes de una definición recursiva</a></td><td> </td><td align="left" valign="top"> Paseo hasta que tu pares ... -</td></tr> -<tr><td align="left" valign="top"><a href="#Recursi_00f3n-con-lista">11.3.3 Recursión con una lista</a></td><td> </td><td align="left" valign="top"> Usando una lista con el test si para recurso. -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-recursiva-tri_00e1ngulo">11.3.4 Recursión en lugar de un contador</a></td><td> </td><td align="left" valign="top"> Función recursiva triángulo -</td></tr> -<tr><td align="left" valign="top"><a href="#Recursi_00f3n-con-cond">11.3.5 Ejemplo de recursión usando <code>cond</code></a></td><td> </td><td align="left" valign="top"> Recursión con cond -</td></tr> -<tr><td align="left" valign="top"><a href="#Patrones-recursivos">11.3.6 Patrones recursivos</a></td><td> </td><td align="left" valign="top"> Plantillas usadas con frecuencia. -</td></tr> -<tr><td align="left" valign="top"><a href="#Sin-Aplazar">11.3.7 Recursión sin diferir</a></td><td> </td><td align="left" valign="top"> No almacenar trabajo ... -</td></tr> -<tr><td align="left" valign="top"><a href="#No-aplazar-la-soluci_00f3n">11.3.8 No hay solución pospuesta</a></td><td> </td><td align="left" valign="top"> No aplazar la solución -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Recursión en lugar de un contador - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Ejemplo-recursivo-y-argumento-con-valor-1-o-2">Un argumento de 1 o 2</a></td><td> </td><td align="left" valign="top"> Ejemplo recursivo y - argumento con valor 1 o 2 -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-Recursivo-de-3-o-4-argumentos">Un argumento de 3 o 4</a></td><td> </td><td align="left" valign="top"> Ejemplo Recursivo de 3 o 4 - argumentos -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Patrones recursivos - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Cada">Patrón recursivo: <em>every</em></a></td><td> </td><td align="left" valign="top"> Cada -</td></tr> -<tr><td align="left" valign="top"><a href="#Acumular">Patrón recursivo: <em>accumulate</em></a></td><td> </td><td align="left" valign="top"> Acumular -</td></tr> -<tr><td align="left" valign="top"><a href="#Guardar">Patrón recursivo: <em>keep</em></a></td><td> </td><td align="left" valign="top"> Guardar -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Búsquedas de expresiones regulares - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#sentence_002dend">12.1 La expresión regular para <code>sentence-end</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#re_002dsearch_002dforward">12.2 La función <code>re-search-forward</code></a></td><td> </td><td align="left" valign="top"> Muy similar a <code>search-forward</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#forward_002dsentence">12.3 <code>forward-sentence</code></a></td><td> </td><td align="left" valign="top"> Un ejemplo sencillo de búsqueda con - expresiones regulares. -</td></tr> -<tr><td align="left" valign="top"><a href="#forward_002dparagraph">12.4 <code>forward-paragraph</code>: una mina de oro de funciones</a></td><td> </td><td align="left" valign="top"> Un ejemplo complejo de alguna cosa. -</td></tr> -<tr><td align="left" valign="top"><a href="#etags">12.5 Crea tu propio fichero ‘<tt>TAGS</tt>’</a></td><td> </td><td align="left" valign="top"> Cómo crear tu propia tabla ‘<tt>TAGS</tt>’. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisar-regexp">12.6 Revisar</a></td><td> </td><td align="left" valign="top"> Revisar regexp -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-re_002dsearch">12.7 Ejercicios con <code>re-search-forward</code></a></td><td> </td><td align="left" valign="top"> Ejercicios re-search -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>forward-sentence</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Completa-forward_002dsentence">Completa la definición <code>forward-sentence</code></a></td><td> </td><td align="left" valign="top"> Completa forward-sentence -</td></tr> -<tr><td align="left" valign="top"><a href="#Bucles-while-fwd_002dsentence">Los bucles <code>while</code></a></td><td> </td><td align="left" valign="top"> Dos bucles <code>while</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Volver-a-buscar-la-frase-en-sentido-directo">La búsqueda de expresiones regulares</a></td><td> </td><td align="left" valign="top"> Una búsqueda de - expresión regular. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>forward-paragraph</code>: una mina de oro de funciones - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#forward_002dparagraph-en-breve">Definición de función <code>forward-paragraph</code></a></td><td> </td><td align="left" valign="top"> Partes clave de la definición de la - función. -</td></tr> -<tr><td align="left" valign="top"><a href="#fwd_002dpara-let">La expresión <code>let*</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#fwd_002dpara-while">El bucle <code>while</code> hacia adelante</a></td><td> </td><td align="left" valign="top"> El bucle <code>while</code> con modo hacia adelante. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Contando: repetición y regexps - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Por-qu_00e9-Contar-Palabras">Contando palabras</a></td><td> </td><td align="left" valign="top"> Por qué Contar Palabras -</td></tr> -<tr><td align="left" valign="top"><a href="#count_002dwords_002dexample">13.1 La función <code>count-words-example</code></a></td><td> </td><td align="left" valign="top"> Usa un regexp, pero encuentra un problema. -</td></tr> -<tr><td align="left" valign="top"><a href="#recursive_002dcount_002dwords">13.2 Cuenta palabras recursivamente</a></td><td> </td><td align="left" valign="top"> Empezar en caso de que no haya palabras en la - región. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-Contar">13.3 Ejercicio: contando puntuación</a></td><td> </td><td align="left" valign="top"> Ejercicio de Contar -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La función <code>count-words-example</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Dise_00f1ar-count_002dwords_002dexample">Diseñando <code>count-words-example</code></a></td><td> </td><td align="left" valign="top"> La definición usando un bucle - <code>while</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Error-de-espacio-en-blanco">13.1.1 El error de espacio en blanco en <code>count-words-example</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Contando palabras en una <code>defun</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Divide-y-vencer_00e1s">Divide y vencerás</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Palabras-y-S_00edmbolos">14.1 ¿Qué contar?</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Sintaxis">14.2 ¿Qué constituye una palabra o símbolo?</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#count_002dwords_002din_002ddefun">14.3 La función <code>count-words-in-defun</code></a></td><td> </td><td align="left" valign="top"> Similar a <code>count-words-example</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Varias-funciones">14.4 Contar varias <code>defuns</code> en un fichero</a></td><td> </td><td align="left" valign="top"> Contando varias funciones en un fichero. -</td></tr> -<tr><td align="left" valign="top"><a href="#Encontrar-un-fichero">14.5 Encontrar un fichero</a></td><td> </td><td align="left" valign="top"> ¿Quieres buscar en un fichero? -</td></tr> -<tr><td align="left" valign="top"><a href="#lengths_002dlist_002dfile">14.6 <code>lengths-list-file</code> en detalle</a></td><td> </td><td align="left" valign="top"> Una lista de los tamaños de muchas - definiciones. -</td></tr> -<tr><td align="left" valign="top"><a href="#Varios-ficheros">14.7 Contar palabras en <code>defuns</code> en diferentes ficheros</a></td><td> </td><td align="left" valign="top"> Contando en definiciones en diferentes - ficheros. -</td></tr> -<tr><td align="left" valign="top"><a href="#Varios-ficheros-recursivamente">14.8 Recursivamente cuenta palabras en diferentes ficheros</a></td><td> </td><td align="left" valign="top"> Recursivamente contando en diferentes - ficheros. -</td></tr> -<tr><td align="left" valign="top"><a href="#Preparar-los-datos">14.9 Preparar los datos para mostrarlos en un grafo</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Contar palabras en <code>defuns</code> en diferentes ficheros - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#lengths_002dlist_002dmany_002dfiles">Determina las longitudes de <code>defuns</code></a></td><td> </td><td align="left" valign="top"> Devolver una lista de tamaños de funciones. -</td></tr> -<tr><td align="left" valign="top"><a href="#append">14.7.1 La función <code>append</code></a></td><td> </td><td align="left" valign="top"> Adjuntar una lista a otra. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Preparar los datos para mostrarlos en un grafo - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Datos-para-mostrar-en-detalle">El dato para mostrar en detalle</a></td><td> </td><td align="left" valign="top"> Datos para mostrar en detalle -</td></tr> -<tr><td align="left" valign="top"><a href="#Ordenando">14.9.1 Ordenando listas</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Listar-ficheros">14.9.2 Creando una lista de ficheros</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Contando-definiciones-de-funci_00f3n">14.9.3 Contando definiciones de función</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Leyendo un grafo - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Columnas-de-un-grafo">Imprimiendo las columnas de un grafo</a></td><td> </td><td align="left" valign="top"> Columnas de un grafo -</td></tr> -<tr><td align="left" valign="top"><a href="#graph_002dbody_002dprint">15.1 La función <code>graph-body-print</code></a></td><td> </td><td align="left" valign="top"> Cómo imprimir el cuerpo de un grafo. -</td></tr> -<tr><td align="left" valign="top"><a href="#recursive_002dgraph_002dbody_002dprint">15.2 La función <code>recursive-graph-body-print</code></a></td><td> </td><td align="left" valign="top"> recursive-graph-body-print -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejes-Impresos">15.3 Necesidad para ejes impresos</a></td><td> </td><td align="left" valign="top"> Ejes Impresos -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-L_00ednea-de-Grafo">15.4 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio de - Línea de Grafo -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Tu fichero ‘<tt>.emacs</tt>’ - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Configuraci_00f3n-por-defecto">Configuración por defecto de Emacs</a></td><td> </td><td align="left" valign="top"> Configuración por defecto -</td></tr> -<tr><td align="left" valign="top"><a href="#Site_002dwide-Init">16.1 Fichero de inicialización site-wide</a></td><td> </td><td align="left" valign="top"> Se puede escribir site-wide ficheros init. -</td></tr> -<tr><td align="left" valign="top"><a href="#defcustom">16.2 Especificar variables usando <code>defcustom</code></a></td><td> </td><td align="left" valign="top"> Emacs escribirá código para ti. -</td></tr> -<tr><td align="left" valign="top"><a href="#Empezando-un-fichero-_002eemacs">16.3 Empieza por un fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td align="left" valign="top"> Cómo escribir un <code>fichero .emacs</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td><td> </td><td align="left" valign="top"> Corta líneas automáticamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#Alias-de-correo">16.5 Alias de correo</a></td><td> </td><td align="left" valign="top"> Usar abreviaciones para direcciones de correo - electrónico. -</td></tr> -<tr><td align="left" valign="top"><a href="#Indentar-modo-de-tabulaciones">16.6 Indentar modo de tabulaciones</a></td><td> </td><td align="left" valign="top"> No usar tabulaciones con TeX -</td></tr> -<tr><td align="left" valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td><td> </td><td align="left" valign="top"> Crear algunos atajos de teclado personales. -</td></tr> -<tr><td align="left" valign="top"><a href="#Mapas-de-teclado">16.8 Mapas de teclado</a></td><td> </td><td align="left" valign="top"> Más acerca de atajos de teclado. -</td></tr> -<tr><td align="left" valign="top"><a href="#Cargando-ficheros">16.9 Cargando ficheros</a></td><td> </td><td align="left" valign="top"> Cargar (por ej. evaluar) ficheros - automáticamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#Autocarga">16.10 Autoloading</a></td><td> </td><td align="left" valign="top"> Crear funciones disponibles. -</td></tr> -<tr><td align="left" valign="top"><a href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></td><td> </td><td align="left" valign="top"> Definir una función; enlazarla a una tecla. -</td></tr> -<tr><td align="left" valign="top"><a href="#Colores-X11">16.12 Colores X11</a></td><td> </td><td align="left" valign="top"> Colores en X. -</td></tr> -<tr><td align="left" valign="top"><a href="#Miscel_00e1nea">16.13 Configuraciones misceláneas para un fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td align="left" valign="top"> Miscelánea -</td></tr> -<tr><td align="left" valign="top"><a href="#Mode-Line">16.14 Una línea modificada</a></td><td> </td><td align="left" valign="top"> Cómo personalizar tu mode line. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Depurando - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#depurar">17.1 <code>depurar</code></a></td><td> </td><td align="left" valign="top"> Cómo usar el depurador construido. -</td></tr> -<tr><td align="left" valign="top"><a href="#debug_002don_002dentry">17.2 <code>debug-on-entry</code></a></td><td> </td><td align="left" valign="top"> Empezar depurando cuando se llama a una - función. -</td></tr> -<tr><td align="left" valign="top"><a href="#debug_002don_002dquit">17.3 <code>debug-on-quit</code> y <code>(debug)</code></a></td><td> </td><td align="left" valign="top"> Empezar depurando cuando se sale con <kbd>C-g</kbd>. -</td></tr> -<tr><td align="left" valign="top"><a href="#edebug">17.4 El depurador de nivel de fuentes <code>edebug</code></a></td><td> </td><td align="left" valign="top"> Cómo usar Edebug, un depurador a nivel de - fuentes. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-de-depuraci_00f3n">17.5 Ejercicios de depuración</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Manejando el anillo de la muerte - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Qu_00e9-hace-el-anillo-de-la-muerte">Qué hace el anillo de la muerte</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#current_002dkill">B.1 La función <code>current-kill</code></a></td><td> </td><td align="left" valign="top"> current-kill -</td></tr> -<tr><td align="left" valign="top"><a href="#pegar">B.2 <code>pegar</code></a></td><td> </td><td align="left" valign="top"> Pegar una copia de un elemento ya cortado. -</td></tr> -<tr><td align="left" valign="top"><a href="#yank_002dpop">B.3 <code>yank-pop</code></a></td><td> </td><td align="left" valign="top"> Insertar elemento apuntado. -</td></tr> -<tr><td align="left" valign="top"><a href="#fichero-anillo">B.4 El fichero ‘<tt>ring.el</tt>’</a></td><td> </td><td align="left" valign="top"> fichero anillo -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La función <code>current-kill</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#C_00f3digo-para-current_002dkill">El código <code>current-kill</code></a></td><td> </td><td align="left" valign="top"> Código para current-kill -</td></tr> -<tr><td align="left" valign="top"><a href="#Comprendiendo-current_002dkill"><code>current-kill</code> en outline</a></td><td> </td><td align="left" valign="top"> Comprendiendo current-kill -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -<code>current-kill</code> en outline - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Cuerpo-de-current_002dkill">El cuerpo de <code>current-kill</code></a></td><td> </td><td align="left" valign="top"> Cuerpo de current-kill -</td></tr> -<tr><td align="left" valign="top"><a href="#Disgresi_00f3n-concerniente-de-error">Disgresión acerca de la palabra ‘error’</a></td><td> </td><td align="left" valign="top"> Cómo confundir humanos, pero no - ordenadores. -</td></tr> -<tr><td align="left" valign="top"><a href="#Determinando-el-elemento">Determinando el elemento</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Un grafo con ejes etiquetados - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Ejemplo-etiquetado">Grafo de ejemplo etiquetado</a></td><td> </td><td align="left" valign="top"> Ejemplo etiquetado -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002dgraph-Varlist">C.1 La varlist <code>print-graph</code></a></td><td> </td><td align="left" valign="top"> Expresión <code>let</code> en <code>print-graph</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002dY_002daxis">C.2 La función <code>print-Y-axis</code></a></td><td> </td><td align="left" valign="top"> Imprimir una etiqueta para los ejes verticales. -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002dX_002daxis">C.3 La función <code>print-X-axis</code></a></td><td> </td><td align="left" valign="top"> Imprimir una etiqueta horizontal. -</td></tr> -<tr><td align="left" valign="top"><a href="#Imprimir-Grafo-Entero">C.4 Imprimiendo el grafo completo</a></td><td> </td><td align="left" valign="top"> La función para imprimir un grafo completo. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La función <code>print-Y-axis</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#print_002dY_002daxis-en-Detalle">La función <code>print-Y-axis</code> en detalle</a></td><td> </td><td align="left" valign="top"> print-Y-axis en Detalle -</td></tr> -<tr><td align="left" valign="top"><a href="#Altura-de-etiqueta">¿A qué altura se debería etiquetar?</a></td><td> </td><td align="left" valign="top"> ¿Qué altura para el eje Y? -</td></tr> -<tr><td align="left" valign="top"><a href="#Calcular-un-resto">C.2.1 Viaje lateral: Calcula un resto</a></td><td> </td><td align="left" valign="top"> Cómo calcular el resto de una división. -</td></tr> -<tr><td align="left" valign="top"><a href="#Elemento-del-Eje-Y">C.2.2 Construye un elemento del eje Y</a></td><td> </td><td align="left" valign="top"> Construir una línea para el eje - Y. -</td></tr> -<tr><td align="left" valign="top"><a href="#Y_002daxis_002dcolumn">C.2.3 Crea un eje de la columna Y</a></td><td> </td><td align="left" valign="top"> Generar una lista de etiquetas del eje Y. -</td></tr> -<tr><td align="left" valign="top"><a href="#Pen_00faltimo-print_002dY_002daxis">C.2.4 La versión no demasiado final de <code>print-Y-axis</code></a></td><td> </td><td align="left" valign="top"> Una versión no muy final. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -La función <code>print-X-axis</code> - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#Diferencias-similares">Similaridades y diferencias</a></td><td> </td><td align="left" valign="top"> Mucho como <code>print-Y-axis</code>, pero no - exactamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#Eje-X-marca-tic">C.3.1 Eje X marca tic</a></td><td> </td><td align="left" valign="top"> Crear marcas de tic para los ejes horizontales. -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -Imprimiendo el grafo completo - - - -</pre></th></tr><tr><td align="left" valign="top"><a href="#La-versi_00f3n-final">Cambios para la versión final</a></td><td> </td><td align="left" valign="top"> Unos pocos cambios -</td></tr> -<tr><td align="left" valign="top"><a href="#Testear-print_002dgraph">C.4.1 Testeando <code>print-graph</code></a></td><td> </td><td align="left" valign="top"> Ejecutar un rápido test. -</td></tr> -<tr><td align="left" valign="top"><a href="#Graficar-palabras-en-funciones">C.4.2 Creando gráficas de números de palabras y símbolos</a></td><td> </td><td align="left" valign="top"> Ejecutando el código final. -</td></tr> -<tr><td align="left" valign="top"><a href="#lambda">C.4.3 Una expresión <code>lambda</code>: Anonimicidad útil</a></td><td> </td><td align="left" valign="top"> Cómo escribir una función anónima. -</td></tr> -<tr><td align="left" valign="top"><a href="#mapcar">C.4.4 La función <code>mapcar</code></a></td><td> </td><td align="left" valign="top"> Aplicar una función a elementos de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#Otro-Error">C.4.5 Otro error … más insidioso</a></td><td> </td><td align="left" valign="top"> Todavía otro error … más - insidioso. -</td></tr> -<tr><td align="left" valign="top"><a href="#Grafo-impreso-final">C.4.6 El gráfico impreso</a></td><td> </td><td align="left" valign="top"> ¡El grafo en sí! -</td></tr> -<tr><th colspan="3" align="left" valign="top"><pre class="menu-comment"> -</pre></th></tr></table> - -<hr size="6"> -<a name="Prefacio"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Top" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Por-qu_00e9" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Prefacio-1"></a> -<h1 class="unnumbered">Prefacio</h1> - -<p>La mayoría del entorno integrado GNU Emacs está -escrito en el lenguaje de programación llamado Emacs Lisp. El -código escrito en este lenguaje de programación es el -software—el conjunto de instrucciones—que cuenta al ordenador qué -hacer cuando tu le das comandos. Emacs está diseñado -de forma que se puede escribir nuevo código en Emacs Lisp -y fácilmente instalarlo como una extensión al editor. -</p> -<p>(GNU Emacs se define muchas veces como un “editor extensible”, pero -hace mucho más que proporcionar capacidad de edición. Es mejor -referirse a Emacs como un “entorno de computación extensible”. Sin -embargo, esta frase es un poco pretenciosa. Es más fácil referirse -a Emacs simplemente como un editor. De hecho, cada cosa que se hace en -Emacs—encontrar la fecha Maya y fases de la luna, simplificar -polinomios, depurar código, administrar ficheros, leer cartas, -escribir libros—todas estas actividades son maneras de editar en un -sentido amplio de la palabra.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Por-qu_00e9">¿Por qué estudiar Emacs Lisp?</a></td><td> </td><td align="left" valign="top"> ¿Por qué aprender Emacs Lisp? -</td></tr> -<tr><td align="left" valign="top"><a href="#Leyendo-este-texto">Leyendo este texto</a></td><td> </td><td align="left" valign="top"> Leer, ganar familiaridad, coger hábitos... -</td></tr> -<tr><td align="left" valign="top"><a href="#Quien-eres">Para quien está esto escrito</a></td><td> </td><td align="left" valign="top"> Para quien es este escrito. -</td></tr> -<tr><td align="left" valign="top"><a href="#Historia-de-Lisp">Historia de Lisp</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Nota-para-principiantes">Una nota para principiantes</a></td><td> </td><td align="left" valign="top"> Tu puedes leer esto como un novato -</td></tr> -<tr><td align="left" valign="top"><a href="#Se-agradece">Se agradece</a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="Por-qu_00e9"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Prefacio" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-este-texto" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="g_t_00bfPor-que-estudiar-Emacs-Lisp_003f"></a> -<h2 class="unnumberedsec">¿Por qué estudiar Emacs Lisp?</h2> - -<p>Aunque Emacs Lisp normalmente se asocia solo con Emacs, es un lenguaje -de programación completo. Se puede usar Emacs Lisp del mismo modo -que con cualquier otro lenguaje de programación. -</p> -<p>Quizás se quiere comprender la programación; quizás se quiere -extender Emacs; o quizás se quiere llegar a ser un programador. Esta -introducción a Emacs Lisp está diseñada para ayudar a empezar en -todo esto: para guiarse en el aprendizaje de los fundamentos de -programación, y de manera más importante, para enseñar como uno -mismo puede ir más allá. -</p> -<hr> -<a name="Leyendo-este-texto"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Prefacio" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Por-qu_00e9" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Quien-eres" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Leyendo-este-texto-1"></a> -<h2 class="unnumberedsec">Leyendo este texto</h2> - -<p>A través de este libro, se verán pequeños programas de ejemplo -que se pueden ejecutar dentro de Emacs. Si se lee este documento en -Info dentro de GNU Emacs, se pueden ejecutar los programas tal y como -aparecen. (Esto es fácil de hacer y se explica cuando los ejemplos -se presentan). Alternativamente, se puede leer esta introducción -como un libro impreso mientras se está sentando con un ordenador -ejecutando Emacs. (Esto es lo que me gusta hacer; me gustan los libros -impresos.) Si no se está ejecutando Emacs, todavía se -puede leer este libro, pero en este caso, lo mejor es tratarlo como -una novela, o como una guía de víaje a un país aún -no visitado: interesante, pero no es lo mismo -que estar allí. -</p> -<p>Gran parte de esta introducción se dedica a paseos guiados de -código usado en GNU Emacs. Estos paseos están diseñados para dos -propósitos: primero, familiarizarse con código real que funciona -(código que se usa cada día); y, segundo, -familiarizarse con cómo funciona Emacs. Es interesante ver cómo se -implementa un entorno completamente operativo. También, espero que -se adquiera el hábito de navegar a través del código fuente. Se -puede aprender mucho comparando código de otros con el propio, -ganando nuevas ideas. Tener GNU Emacs es como tener la cueva del -dragón de los tesoros. -</p> -<p>Además de aprender acerca de Emacs como editor y Emacs Lisp como -lenguaje de programación, los ejemplos y visitas guiadas le -darán una oportunidad para familiarizarse con Emacs como un -entorno de programación Lisp. GNU Emacs soporta programación y -provee herramientas que llegarán a usarse cómodamente, -como <kbd>M-.</kbd> (la clave que invoca el comando -<code>find-tag</code>). También aprendera sobre búffers y otros -objetos que forman parte del entorno. Aprender estas funcionalidades de -Emacs es como aprender nuevas rutas alrededor de tu hogar. -</p> - -<p>Finalmente, espero poder transmitir algunas habilidades de Emacs -para aprender aspectos de programación que no se conocen. Con -frecuencia se puede usar Emacs para ayudar a comprender qué puzzles -encontrar o como hacer alguna cosa nueva. Este auto-descubrimiento no es -solo un placer, también es una ventaja. -</p> -<hr> -<a name="Quien-eres"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Prefacio" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-este-texto" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Historia-de-Lisp" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Para-quien-esta-esto-escrito"></a> -<h2 class="unnumberedsec">Para quien está esto escrito</h2> - -<p>Este texto está escrito como una introducción elemental para -personas que no son programadoras. Quien ya programa, puede no estar -satisfecho con este libro. La razón es que un programador puede -tener que convertirse en experto leyendo manuales de referencia y este -texto no está organizado como un manual de referencia. -</p> -<p>Un programador experto que revisó este texto me dijo: -</p> -<blockquote> -<p><i>Prefiero aprender desde manuales de referencia. Yo “me sumerjo” en -cada párrafo y “subo a por aire” entre párrafos.</i> -</p> -<p><i>Cuando llego al fin de un párrafo, asumo que este asunto está -hecho, finalizado, que conozco cada cosa que necesito (con la posible -excepción del caso en el que el siguiente párrafo empiece hablando -acerca de eso mismo en más detalle). Yo espero que un manual de -referencia bien escrito no tendrá un montón de redundancia, y -tendrá excelentes punteros a (un) lugar donde está la -información que quiero.</i> -</p></blockquote> - -<p>¡Esta introducción no está escrita para esta persona! -</p> -<p>Primero, intento decir cada cosa al menos tres veces: primero, -introducirlo; segundo, mostrarlo en contexto; y tercero, mostrarlo en -un contexto diferente, o revisarlo. -</p> -<p>Segundo, yo no siempre pongo toda la información acerca de un asunto -en un mismo lugar, ni mucho menos en un párrafo. Desde mi punto de -vista, se necesita una carga bastante fuerte en el lector. En vez de -eso intento explicar solo lo que se necesita saber en el -momento. (Algunas veces incluyo una pequeña información extra, -para que no haya sorpresas más tarde cuando la información -adicional se presente formalmente.) -</p> -<p>Cuando uno lee este texto, no espera aprender todo la primera -vez. Frecuentemente, solo necesita hacer un ‘reconocimiento’ con -alguno de los elementos mencionados. Mi esperanza es haber -estructurado el texto y dar suficientes indicios que dejarán alerta -de lo que es importante y concentrarse en ellos. -</p> -<p>Es necesario “sumergirse” en algunos párrafos; no hay otro modo de -leerlos. Pero yo he intentado guardar el número de tales -párrafos. Este libro pretende ser como una colina asequible, en vez -de una montaña abrumadora. -</p> -<p>Esta introducción de <cite>Programación en Emacs Lisp</cite> viene -acompañada de un documento complementario. -<a href="El Manual de Referencia de GNU Emacs Lisp.html#Arriba">(El Manual de Referencia de GNU Emacs Lisp)El Manual de Referencia de GNU Emacs Lisp</a>. -El manual de referencia tiene más detalles que esta -introducción. En el manual de referencia, toda la información -sobre un asunto está concentrada en un lugar. Se debe cambiar si es -como el programador citado arriba. Y, por supuesto, después de haber -leido esta <cite>Introducción</cite>, será muy útil consultar el -<cite>Manual de Referencia</cite> al escribir programas propios. -</p> -<hr> -<a name="Historia-de-Lisp"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Prefacio" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Quien-eres" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Nota-para-principiantes" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Historia-de-Lisp-1"></a> -<h2 class="unnumberedsec">Historia de Lisp</h2> -<a name="index-Historia-de-Lisp"></a> - -<p>Lisp fué originariamente desarrollado en los 50 en el Instituto -Tecnológico de Massachusetts para investigar en inteligencia -artificial. El gran poder del lenguaje Lisp lo hace superior para -otros propósitos también, tal como escribir comandos de edición y -entornos integrados. -</p> -<a name="index-Maclisp"></a> -<a name="index-Common-Lisp"></a> -<p>GNU Emacs Lisp está fuertemente inspirado en Maclisp, que está -escrito en el MIT en los sesenta. Está en cierto modo inspirado en -Common Lisp, que llega a ser un estándar en los 80. Sin embargo, -Emacs Lisp es mucho más simple que Common Lisp. (La distribución -estándar de Emacs contiene un fichero de extensiones opcional, -‘<tt>cl.el</tt>’, que añade muchas funcionalidades a Emacs Lisp.) -</p> -<hr> -<a name="Nota-para-principiantes"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Prefacio" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Historia-de-Lisp" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Se-agradece" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-nota-para-principiantes"></a> -<h2 class="unnumberedsec">Una nota para principiantes</h2> - -<p>Aunque no se conozca GNU Emacs, este documento puede resultar -útil. Sin embargo, es mejor aprender Emacs, al menos aprender a -moverse alrededor de la pantalla del ordenador. Uno puede aprender de -manera autodidacta cómo usar Emacs con el tutorial on-line. Para -usarlo, se debe escribir <kbd>C-h t</kbd>. (Esto significa que se presione -la tecla <CTRL> y la <kbd>h</kbd> al mismo tiempo, y después se -presiona <kbd>t</kbd>). -</p> -<p>Con frecuencia, también aludo a uno de los comandos de Emacs -estándar listando las teclas que se presionan para invocar el -comando y, luego dar el nombre del comando entre paréntesis, -asi: <kbd>M-C-\</kbd> (<code>indent-region</code>). Esto significa invocar el -comando <code>indent-region</code> presionando <kbd>M-C-\</kbd>.(Si lo desea, se pueden -cambiar las teclas que son escritas para invocar el comando; esto se -llama <em>rebinding</em>. Véase la sección <a href="#Mapas-de-teclado">Mapas de Teclado</a>.) -La abreviación <kbd>M-C-\</kbd> significa que se presiona la tecla -<META>, <CTRL>, y <\> todo al mismo tiempo. (En muchos -teclados modernos la tecla <META> es etiquetada con <ALT>.) -Algunas veces una combinación como esta se llama <em>keychord</em>, -puesto que es similar a tocar un acorde en un piano. Si el teclado no -tiene una tecla <META>, en su lugar se usa la tecla <ESC> -como prefijo. En este caso <kbd>M-C-\</kbd> significa que se presiona y libera -<ESC> -y luego presiona la tecla <CTRL> y la tecla <\> al mismo -tiempo. Pero -normalmente <kbd>M-C-\</kbd> significa presionar la tecla <CTRL> junto -a la tecla que está etiquetada <ALT> y, al mismo tiempo, -presionar la tecla <\>. -</p> -<p>Además de pulsar una sola combinación de teclas, se puede -prefijar lo que se escribe con <kbd>C-u</kbd>, que es llamado el ‘argumento -universal’. El atajo <kbd>C-u</kbd> pasa a ser un argumento para el comando -subsiguiente. De este modo, para indentar una región de texto plano -a 6 espacios, se marca la región, y entonces se presiona <kbd><span class="nolinebreak">C-u</span> 6 <span class="nolinebreak">M-C-\</span></kbd>. (Si no se especifica un número, Emacs pasa el número 4 -al comando o de otra manera ejecuta el comando de manera -diferente). See <a href="emacs.html#Argumentos">Argumentos Numéricos</a> in <cite>El Manual de GNU Emacs</cite>. -</p> -<p>Si se está leyendo esto en Info usando GNU Emacs, se puede avanzar a -través de este documento completo solo presionando la barra de espacio, -<SPC>. (Para aprender acerca de Info, presiona <kbd>C-h i</kbd> y -luego selecciona Info.) -</p> -<p>Una nota en terminología: cuando uso la palabra Lisp -sola, con frecuencia me estoy refiriendo a los dialectos de Lisp en -general, pero cuando hablo de Emacs Lisp, me estoy refiriendo a -GNU Emacs Lisp en particular. -</p> -<hr> -<a name="Se-agradece"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Prefacio" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Nota-para-principiantes" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Prefacio" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Se-agradece-1"></a> -<h2 class="unnumberedsec">Se agradece</h2> - -<p>Estoy agradecido a todas las personas que me ayudaron con este -libro. Especialmente agradecido a <span class="roman">Jim Blandy</span>, <span class="roman">Noah Friedman</span>, -Jim Kingdon, <span class="roman">Roland McGrath</span>, Frank Ritter, Randy Smith, Richard M. Stallman, y Melissa Weisshaus. Gracias -también a Philip Johnson y David Stampe por su ánimo -paciente. Mis errores son míos. -</p> -<p align="right">Robert J. Chassell -<a href="mailto:bob@gnu.org">bob@gnu.org</a> -</p> - - - - -<hr> -<a name="Procesamiento-de-listas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Prefacio" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Se-agradece" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-Lisp" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Procesamiento-de-listas-1"></a> -<h1 class="chapter">1 Procesamiento de listas</h1> - -<p>Para el ojo inexperto, Lisp es un lenguaje de -programación extraño. En código Lisp hay paréntesis por todas -partes. Algunas personas incluso reclaman que el nombre signfica ‘Lots -of Isolated Silly Parentheses’ (‘Montones de Paréntesis Aislados -Estúpidos’). Pero la protesta no tiene fundamento. Lisp es para -procesamiento de listas, y el lenguaje de programación maneja -<em>listas</em> (y listas de listas) poniéndolas entre -paréntesis. Los paréntesis marcan los límites de la -lista. Algunas veces una lista va precedida por un apóstrofe simple -o una marca de cita, ‘<samp>'</samp>’<a name="DOCF1" href="#FOOT1">(1)</a> -Las listas son el fundamento de Lisp. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Listas-Lisp">1.1 Listas Lisp</a></td><td> </td><td align="left" valign="top"> ¿Qué son listas? -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></td><td> </td><td align="left" valign="top"> Cualquier lista en Lisp es un programa listo - para ejecutarse. -</td></tr> -<tr><td align="left" valign="top"><a href="#Creando-errores">1.3 Generar un mensaje de error</a></td><td> </td><td align="left" valign="top"> Generando un mensaje de error. -</td></tr> -<tr><td align="left" valign="top"><a href="#Nombres-y-definiciones">1.4 Nombres de símbolos y definiciones de funciones</a></td><td> </td><td align="left" valign="top"> Nombres de símbolos y - definiciones de función. -</td></tr> -<tr><td align="left" valign="top"><a href="#Interpr_00e9te-Lisp">1.5 El intérprete Lisp</a></td><td> </td><td align="left" valign="top"> Qué hace el intérprete Lisp. -</td></tr> -<tr><td align="left" valign="top"><a href="#Evaluaci_00f3n">1.6 Evaluación</a></td><td> </td><td align="left" valign="top"> Ejecutando un programa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Variables">1.7 Variables</a></td><td> </td><td align="left" valign="top"> Devolviendo un valor desde una variable. -</td></tr> -<tr><td align="left" valign="top"><a href="#Argumentos">1.8 Argumentos</a></td><td> </td><td align="left" valign="top"> Pasando información a una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#set-y-setq">1.9 Configurando el valor de una variable</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Resumen">1.10 Resumen</a></td><td> </td><td align="left" valign="top"> Los mayores puntos. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-de-mensajes-de-error">1.11 Ejercicios</a></td><td> </td><td align="left" valign="top"> Ejercicios de mensajes de error -</td></tr> -</table> - -<hr> -<a name="Listas-Lisp"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-de-n_00fameros" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Listas-Lisp-1"></a> -<h2 class="section">1.1 Listas Lisp</h2> -<a name="index-Listas-Lisp"></a> - -<p>En Lisp, una lista como esta: <code>'(rosa violeta margarita -botóndeoro)</code>. Esta lista es precedida por una comilla. -Bien, podría estar escrita de la siguente manera, que se -parece -más al tipo de lista con la que se está familiarizado: -</p> -<div class="smallexample"> -<pre class="smallexample">'(rosa - violeta - margarita - botóndeoro) -</pre></div> - -<p>Los elementos de esta lista son los nombres de 4 flores diferentes, -separados por espacios en blanco y rodeados de paréntesis, como -flores en un campo con un muro de piedras alrededor de ellas. -<a name="index-Flores-en-un-campo"></a> -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Listas-de-n_00fameros">Números, listas dentro de listas</a></td><td> </td><td align="left" valign="top"> Lista tener números, otras listas, en ellas. -</td></tr> -<tr><td align="left" valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td><td> </td><td align="left" valign="top"> Entidades Elementales. -</td></tr> -<tr><td align="left" valign="top"><a href="#Espacios-en-blanco-en-listas">1.1.2 Espacios en blanco en listas</a></td><td> </td><td align="left" valign="top"> Formatenado listas para ser legibles. -</td></tr> -<tr><td align="left" valign="top"><a href="#Escribiendo-listas">1.1.3 GNU Emacs te ayuda a escribir listas</a></td><td> </td><td align="left" valign="top"> Cómo GNU Emacs te ayuda a escribir listas. -</td></tr> -</table> - -<hr> -<a name="Listas-de-n_00fameros"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-Lisp" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-Lisp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00c1tomos-Lisp" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Numeros_002c-listas-dentro-de-listas"></a> -<h3 class="unnumberedsubsec">Números, listas dentro de listas</h3> - -<p>Las listas pueden también tener números dentro, como en esta lista: -<code>(+ 2 2)</code>. Esta lista tiene un signo más, ‘<samp>+</samp>’, seguido por -dos ‘<samp>2</samp>’, cada uno separado por espacios en blanco. -</p> -<p>En Lisp, tanto datos como programas están representados de la misma -manera; es decir, són a la vez listas de palabras, números, u otras -listas, -separadas por espacios en blanco y rodeadas de paréntesis. (Puesto -que un programa son datos, un programa puede fácilmente servir datos -a otros programas; esta es una funcionalidad muy poderosa de Lisp.) -(Incidentalmente, estas dos marcas de paréntesis <em>no</em> son -listas Lisp, porque contienen ‘<samp>;</samp>’ y ‘<samp>.</samp>’ como marcas -de puntuación.) -</p> -<p>Aquí hay otra lista, esta vez con una lista dentro: -</p> -<div class="smallexample"> -<pre class="smallexample">'(esta lista tiene (una lista dentro de ella)) -</pre></div> - -<p>Los componentes de esta lista son las palabras ‘<samp>esta</samp>’, -‘<samp>lista</samp>’, ‘<samp>tiene</samp>’, y la lista ‘<samp>(una lista dentro de -ella)</samp>’. La lista interior se construye con las palabras ‘<samp>una</samp>’, -‘<samp>lista</samp>’, ‘<samp>dentro</samp>’, ‘<samp>de</samp>’, ‘<samp>ella</samp>’. -</p> -<hr> -<a name="g_t_00c1tomos-Lisp"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-de-n_00fameros" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-Lisp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Espacios-en-blanco-en-listas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Atomos-Lisp"></a> -<h3 class="subsection">1.1.1 Átomos Lisp</h3> -<a name="index-Atomos-Lisp"></a> - -<p>En Lisp, lo que hemos estado llamando palabras son en realidad -<em>átomos</em>. Este término viene del significado histórico de la -palabra -átomo, que significa ‘indivisible’. En lo que a Lisp concierne, las -palabras -que hemos estado usando en las listas no pueden ser divididas en -pequeñas partes, sin perder su significado dentro del programa; lo -mismo ocurre con números y símbolos de un caracterer -como ‘<samp>+</samp>’. Por otro lado, a diferencia de un átomo, una -lista puede ser dividida en pequeñas partes. Ver <a href="@code{cdr} y @code{cons}.html#Car-cdr-y-cons"><code>car</code></a> in <cite>Funciones Fundamentales</cite>. -</p> -<p>En una lista, los átomos se separan unos de otros por espacios en -blanco. Pueden ir pegados a un paréntesis. -</p> -<a name="index-lista-vacia-definida"></a> -<p>Técnicamente hablando, una lista en Lisp consiste de paréntesis -alrededor de átomos separados por espacios en blanco o alrededor de -otras lista o alrededor de ambos átomos u otras listas. Una lista -puede tener solo un átomo o no tener absolutamente nada en -ella. Una lista con nada dentro se ve así: <code>()</code>, y -se llama <em>lista vacía</em>. A diferencia de cualquier -otra cosa, una lista vacía es tanto un átomo, como una -lista al mismo tiempo. -</p> -<a name="index-Expresiones-simbolicas_002c-introducidas"></a> -<a name="index-expresion-definida"></a> -<a name="index-forma-definida"></a> -<p>La representación impresa de átomos y listas se llama -<em>expresiones simbólicas</em> o, más concisamente, -<em>s-expresiones</em>. La palabra <em>expresión</em> por sí -misma puede referir o bien a la representación impresa, o al átomo -o a la lista como se maneja internamente en el ordenador. Con -frecuencia, las personas usan el término <em>expresión</em> -indiscriminadamente. (También, en muchos textos, la palabra -<em>forma</em> se usa como un sinónimo para la expresión.) -</p> -<p>Por cierto, los átomos que componen nuestro universo fueron nombrados -así -cuando se pensaba que eran indivisibles; pero -pero se ha encontrado que los átomos fisicos no son -indivisibles. Las partes pueden dividir un átomo o puede fisionarse -en 2 partes de igual tamaño. Los átomos físicos -se nombraron prematuramente, antes de que su verdadera naturaleza -fuese encontrada. En Lisp, ciertos tipos de átomos, como un array, -pueden ser separados en partes; pero el mecanismo de hacer esto es -diferente de el mecanismo para dividir una lista. En lo que se refiere -a operaciones de lista, los átomos de una lista -son indivisibles. -</p> -<p>Como en español, el significado de las letras que componen un átomo Lisp -difiere del significado de las letras compuestas como una palabra. -Por ejemplo, la expresión ‘<samp>ay</samp>’, es -completamente diferente de las dos palabras ‘<samp>a</samp>’, e ‘<samp>y</samp>’. -</p> -<p>Hay muchos tipos de átomos en la naturaleza, pero solo unos pocos en Lisp: -por ejemplo, <em>números</em>, tales como 37, 511, o 1729, y -<em>símbolos</em>, tales como ‘<samp>+</samp>’, ‘<samp>foo</samp>’, o -‘<samp>forward-line</samp>’. Las palabras que hemos listado en los ejemplos -anteriores son todos símbolos. En una conversación cotidiana -de -Lisp, la palabra “átomo” no se usa con frecuencia, -porque los programadores normalmente intentan ser más -específicos acerca de que tipo de átomo están -tratando. La programación Lisp es sobre todo de -símbolos (y algunas veces números) con -listas. (De ese modo, tres palabras rodeadas de paréntesis son una -apropiada lista en Lisp, ya que consiste de átomos, que en -este caso son símbolos, separados por espacios en blanco -y cerrados por paréntesis, sin ninguna puntuación no Lisp.) -</p> -<p>Texto entre comillas—incluso frases o párrafos—son -también un átomo. Aquí hay un ejemplo: -<a name="index-Texto-entre-comillas"></a> -</p> -<div class="smallexample"> -<pre class="smallexample">'(esta lista incluye "texto entre comillas.") -</pre></div> - -<a name="index-cadena-definida"></a> -<p>En Lisp, todo el texto citado incluyendo la marca de puntuación y -los espacios en blanco son un solo átomo. Este tipo de átomo es -llamado <em>string</em> (por ‘cadena de caracteres’) y es el tipo de cosa -que es usada para mensajes que un ordenador puede imprimir para que un -humano lea. Las cadenas son un tipo de átomo diferente a los -números, o símbolos y se usan de manera diferente. -</p> -<hr> -<a name="Espacios-en-blanco-en-listas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00c1tomos-Lisp" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-Lisp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-listas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Espacios-en-blanco-en-listas-1"></a> -<h3 class="subsection">1.1.2 Espacios en blanco en listas</h3> -<a name="index-Espacio-en-blanco-en-listas"></a> - -<p>La cantidad de espacios en blanco en una lista no importa. Desde el -punto de vista del lenguaje Lisp, -</p> -<div class="smallexample"> -<pre class="smallexample">'(esta lista - parece esto) -</pre></div> - -<p>es exactamente lo mismo que esto: -</p> -<div class="smallexample"> -<pre class="smallexample">'(esta lista parece esto) -</pre></div> - -<p>Ambos ejemplos muestran que en Lisp es la misma lista, la lista hecha de -los símbolos ‘<samp>esta</samp>’, ‘<samp>lista</samp>’, ‘<samp>parece</samp>’, -y ‘<samp>esto</samp>’ en este orden. -</p> -<p>Los espacios en blanco adicionales y los saltos de línea están -diseñados -para crear una lista más legible por humanos. Cuando Lisp lee la -expresión, asimila los espacios en blanco extra (pero necesita tener -al menos un espacio entre átomos en orden para contarlos aparte.) -</p> -<p>Aunque parezca raro, los ejemplos que hemos visto cubren casi todo lo -aparece en las listas Lisp. Cualquier otra lista en Lisp se ve más o menos -igual a uno -de estos ejemplos, excepto que la lista puede ser más larga y más -compleja. En resumen, una lista está entre paréntesis, una cadena -está entre comillas, un símbolo parece como una -palabra, y un número parece un número. (Para ciertas situaciones, -corchetes, puntos y otros caracteres especiales pueden ser usados; sin -embargo; iremos bastante lejos sin ellos.) -</p> -<hr> -<a name="Escribiendo-listas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Espacios-en-blanco-en-listas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-Lisp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejecutar-un-programa" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="GNU-Emacs-te-ayuda-a-escribir-listas"></a> -<h3 class="subsection">1.1.3 GNU Emacs te ayuda a escribir listas</h3> -<a name="index-Ayuda-escribiendo-listas"></a> -<a name="index-Formateando-ayuda"></a> - -<p>Cuando se escribe una expresión Lisp en GNU Emacs usando bien el -modo de Interacción Lisp o el modo Emacs Lisp, están disponibles -varios comandos para formatear la expresión Lisp, de modo que sea -fácil de leer. Por ejemplo, presionando la tecla <TAB> -automáticamente se indenta la línea donde se encuetra el -cursor -a la cantidad correcta. Un comando para indentar -apropiadamente el código en una región está asociado a -<kbd>M-C-\</kbd>. La indentación está diseñada de modo que se pueda ver qué -elementos percecen a cada lista—los -elementos de una sublista están más indentados que los elementos -de una lista cerrada. -</p> -<p>Además, cuando se escribe un paréntesis de cierre, Emacs -momentáneamente salta el cursor atrás para hacer el matching -(emparejamiento) con el paréntesis de apertura, para ver cuál -es. Esto es muy útil, ya que cada lista que se escribe en Lisp debe -tener sus paréntesis emparejados con sus paréntesis de -apertura. (Ver <a href="El Manual de GNU Emacs.html#Modos-Mayores">(El Manual de GNU Emacs)emacs</a>, para más información acerca de modos de Emacs.) -</p> -<hr> -<a name="Ejecutar-un-programa"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-listas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Creando-errores" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejecutar-un-programa-1"></a> -<h2 class="section">1.2 Ejecutar un programa</h2> -<a name="index-Ejecuta-un-programa"></a> -<a name="index-Programa_002c-ejecutando-uno"></a> - -<a name="index-se-definio-evaluate"></a> -<p>Una lista en Lisp —cualquier lista— es un programa listo para ser -ejecutado. Si lo ejecutas (lo que la jerga Lisp llama <em>evaluar</em>), -el ordenador hará una de tres cosas: nada excepto devolverte la -lista misma; enviar un mensaje de error; o, tomar el primer -símbolo en la lista como un comando para hacer alguna -cosa. (¡Normalmente, es lo último de estas tres cosas de -lo que realmente se quiere!). -</p> -<p>El apóstrofe, <code>'</code>, que se pone enfrente de algúnos ejemplos de -lista en secciones anteriores se llama <em>quote</em>; (citar); -cuando precede a una lista, se informa a Lisp no hacer nada con la lista, -mas que la tomarla tal como está escrita. Pero si no hay una cita -precediendo la lista, el primer ítem de la lista es -especial: es un comando para que el ordenador obedezca. (En Lisp, -estos comandos son llamados <em>funciones</em>.) A continuación se muestra la -lista no citada <code>(+ 2 2)</code>, por lo que Lisp comprende que -<code>+</code> es una instrucción para hacer alguna cosa con -el resto de la lista: suma los números que siguen. -</p> -<p>Si estás leyendo esto dentro de GNU Emacs en Info, -aquí está como puedes evaluar una lista: coloca tu cursor -justo después del paréntesis derecho de la siguiente lista y presiona -<kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 2 2) -</pre></div> - -<p>Verás que el número <code>4</code> aparece en el área echo. (En la jerga, lo -que acabas de hacer es “evaluar la lista.” El área echo es la -línea en la parte inferior de la pantalla que muestra o -hace “echo” del texto). Ahora intenta la misma cosa con una lista -citada: posiciona el cursor justo después de la siguiente -lista y presiona <kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">'(esto es una lista con comillas) -</pre></div> - -<p>Se verá aparecer <code>(esto es una lista con comillas)</code> en el área -echo. -</p> -<a name="index-Interprete-Lisp_002c-explicada"></a> -<a name="index-Interprete_002c-Lisp_002c-explicado"></a> -<p>En ambos casos, lo que estás haciendo es dar un comando al programa -dentro de GNU Emacs llamado <em>intérprete Lisp</em> — dando al -intérprete un comando para evaluar la expresión. El nombre del -intérprete Lisp viene de la palabra para la tarea hecha por un -humano que viene con el significado de una expresión — quien lo -“interpreta”. -</p> -<p>También se puede evaluar un átomo que no es parte de una lista — -uno que no está rodeado por paréntesis; de nuevo, el intérprete -Lisp traduce desde la expresión humanamente legible al lenguaje del -ordenador. Pero antes de discutir esto (ver <a href="#Variables">Variables</a>), vamos a -discutir lo que el intérprete de Lisp hace cuando tu creas el -error. -</p> -<hr> -<a name="Creando-errores"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejecutar-un-programa" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Nombres-y-definiciones" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Generar-un-mensaje-de-error"></a> -<h2 class="section">1.3 Generar un mensaje de error</h2> -<a name="index-Genera-un-mensaje-de-error"></a> -<a name="index-Generacion-de-mensaje-de-Error"></a> - -<p>No se preocupe si genera un mensaje de error de manera accidental, ahora -daremos un comando al intérprete de Lisp que genara un mensaje de error. -Esta es una accion inofensiva; y de hecho, a menudo se intenta generar -mensajes de error de manera intencional. Una vez se comprende la -jerga, los mensajes de error pueden ser informativos. En vez de ser -llamados mensajes de “error”, deberían ser llamados -mensajes de “ayuda”. Son como letreros para un viajero en un paÃs extraño; -descifrarlos puede ser duro, pero una vez comprendidos, pueden señalar el -camino. -</p> -<p>El mensaje de error es generado por un depurador de código -incorporado dentro de GNU Emacs. Así se ‘entra al -depurador’. Se puede salir del depurador pulsando <code>q</code>. -</p> -<p>Lo que se hace es evaluar una lista que no está citada y no tiene un -comando con significado como su primer elemento. Aquí -hay una lista casi exactamente igual a la que acabamos de usar, pero sin -la cita al inicio. Coloque el cursor a la derecha donde esta finaliza y -presione <kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(esto es una lista sin cita) -</pre></div> - - -<p>Se abrirá una ventana ‘<tt>*Backtrace*</tt>’ y se verá lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--Lisp error: (void-function esto) - (esto es una lista sin cita) - eval((esto es una lista sin cita) nil) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp nil nil) - command-execute(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>Su cursor estará en esta ventana (puede tener que esperar unos -pocos segundos antes de que sea visible). Para salir del -depurador y de su ventana, presione: -</p> -<div class="smallexample"> -<pre class="smallexample">q -</pre></div> - -<p>Por favor, ahora pulsa <kbd>q</kbd>, así se comprueba que se -puede salir del depurador. A continuacion, presione "<kbd>C-x C-e</kbd> una -vez más para re-entrar. -</p> -<a name="index-funcion-definida"></a> -<p>Sobre la base de lo que ya sabemos, casi podemos leer este mensaje de error. -</p> -<p>Leer el búffer ‘<tt>*Backtrace*</tt>’ de abajo hacia arriba; informa lo que -Emacs ha hecho. Cuando se presiona <kbd>C-x C-e</kbd>, se hace una llamada -interactiva a el comando <code>eval-last-sexp</code>. <code>eval</code> es una -abreviatura para ‘evaluar’ y <code>sexp</code> es una abreviatura para -‘expresión simbólica’. El comando significa ‘evalúa la -última expresión simbólica’, que es la expresión justo antes -de tu cursor. -</p> -<p>Cada línea anterior a esta cuenta lo que el intérprete de -Lisp evaluo después. La acción más reciente está en la parte -superior. El -búffer es llamado ‘<tt>*Backtrace*</tt>’ ya que permite realizar un -seguimiento -de Emacs hacia atrás. -</p> -<p>En la parte superior del búffer ‘<tt>*Backtrace*</tt>’, verá la -línea: -</p> -<div class="smallexample"> -<pre class="smallexample">Debugger entered--Lisp error: (void-function esto) -</pre></div> - -<p>El intérprete Lisp intentó evaluar el primer átomo de la lista, -la palabra ‘<samp>esto</samp>’. Esta es la acción que generó el mensaje de error -‘<samp>void-function esto</samp>’. -</p> -<p>El mensaje contiene las palabras ‘<samp>void-function</samp>’ y ‘<samp>esto</samp>’. -</p> -<a name="index-funcion-definida-1"></a> -<p>La palabra ‘<samp>function</samp>’ fué mencionada antes. Es una palabra muy -importante. Para nuestros propósitos, podemos definirla diciendo -que una <em>función</em> (<em>function</em>) es un conjunto de -instrucciones para decirle al ordenador que haga alguna cosa. -</p> -<p>Ahora podemos empezar a comprender el mensaje de error: -‘<samp>void-function this</samp>’. La función (que es, la palabra -‘<samp>this</samp>’) no tiene la definición de ningun conjunto de -instrucciones que el ordenador pueda realizar. -</p> -<p>La palabra ligeramente extraña, ‘<samp>void-function</samp>’, está diseñada -para -cubrir la forma en que Emacs Lisp lo implementa, que es cuando un símbolo -no tiene una definición de función atribuido, el sitio que contiene la -instrucción esta ‘vacío’ (‘<samp>void</samp>’). -</p> -<p>Por otro lado, ya que fuimos capaces de añadir 2 más 2 de -manera exitosa, evaluando <code>(+ 2 2)</code>, se puede inferir que el -símbolo <code>+</code> debe tener un conjunto de instrucciones -que el ordenador ejecuta y estas instrucciones deben sumar -los números despues del <code>+</code>. -</p> -<p>Es posible evitar que Emacs entre en el depurador en casos como -este. No se explicará cómo hacer esto aquí, pero se -mencionará un resultado asi, porque se puede encontrar una -situación similar si hay un error en algún código de Emacs que -este usando. En tales casos, verá solo una línea del -mensaje de error; aparecer en el área echo con el siguente aspecto -</p> -<div class="smallexample"> -<pre class="smallexample">Symbol's function definition is void: esto -</pre></div> - -<p>El mensaje aparece tan pronto se presiono una tecla, aunque sólo sea para -mover el cursor. -</p> -<p>Conocemos el significado de la palabra -‘<samp>Símbolo</samp>’. Se refiere al primer átomo de la -lista, la palabra ‘<samp>este</samp>’. La palabra ‘<samp>función</samp>’ se refiere -a las instrucciones que dicen al ordenador que -hacer. (Técnicamente, el símbolo indica al ordenador -donde encontrar las instrucciones, pero esta es una complicación que -podemos ignorar por el momento.) -</p> -<p>El mensaje de error puede ser comprendido: ‘<samp>La definición del -símbolo está vacía: este</samp>’. El -símbolo (que es, la palabra ‘<samp>este</samp>’) carece de -instrucciones que el ordenador realize. -</p> -<hr> -<a name="Nombres-y-definiciones"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Creando-errores" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Interpr_00e9te-Lisp" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Nombres-de-simbolos-y-definiciones-de-funciones"></a> -<h2 class="section">1.4 Nombres de símbolos y definiciones de funciones</h2> -<a name="index-Nombres-de-Simbolos"></a> - -<p>Se puede articular otra característica de Lisp basada en -lo que se discutió hace tiempo—una característica -importante: un símbolo, como <code>+</code>, no es en -sí mismo el conjunto de instrucciones que el ordenador -realiza. En su lugar, el símbolo es usado, -quizás temporalmente, como una manera de localizar la definición o -conjunto de instrucciones. Lo que vemos es el nombre -con el cual se pueden encontrar las instrucciones. Los nombres de las -personas -funcionan de la misma manera. Por ejemplo, puede referirse a mi -como ‘<samp>Bob</samp>’; sin embargo, no soy las letras ‘<samp>B</samp>’, ‘<samp>o</samp>’, ‘<samp>b</samp>’ -pero soy, o -o fuí, conscientemente asociado con una forma de vida -particular. El -nombre no soy yo, pero puede ser usado para referirme. -</p> -<p>En Lisp, un conjunto de instrucciones puede ligarse a varios -nombres. Por ejemplo, las instrucciones de ordenador para añadir -números pueden ser enlazados al símbolo <code>más</code> -tan bien como el símbolo <code>+</code> (y se encuantran en algunos -dialectos de Lisp). Entre humanos, puede referirse a ‘<samp>Robert</samp>’ tan -bien como ‘<samp>Bob</samp>’ y en otras palabras también. -</p> -<p>Por otra parte, un símbolo puede estar ligado solo con una -función -a la vez. De lo contrario, el ordenador -estaría confundido acerca de qué definición usar. Si -este fuera el caso, solo una persona en el mundo podría -llamarse ‘<samp>Bob</samp>’. Sin embargo, la definición de función a la -que el nombre hace referencia puede cambiarse fácilmente. -(Ver <a href="#Instalar">Instalar una Definición de Función</a>.) -</p> -<p>Ya que Emacs Lisp es extenso, se acostumbra nombrar los -símbolos de un modo que pueda establecerse a que parte de -Emacs -pertenece la función. En consecuencia, todos los nombres de -funciones relacionadas con Texinfo empiezan con ‘<samp>texinfo-</samp>’ y aquellas -relaciondas con la lectura de correo empiezan con -‘<samp>rmail-</samp>’. -</p> -<hr> -<a name="Interpr_00e9te-Lisp"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Nombres-y-definiciones" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Complicaciones" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-interprete-Lisp"></a> -<h2 class="section">1.5 El intérprete Lisp</h2> -<a name="index-Interprete-Lisp_002c-que-hace"></a> -<a name="index-Interprete_002c-que-hace"></a> - -<p>Basado en lo que se ha visto, ahora podemos empezar a entender lo que -el intéprete Lisp hace cuando mandamos a evaluar una -lista. Primero, examina si hay un símbolo cita -antes de la lista; si lo hay, el intérprete nos da la lista. Por otro -lado, si no hay cita, el intéprete mira si el primer elemento en la -lista tiene una definición de función. Si no, el -intérprete imprime un mensaje de error. -</p> -<p>Así es como Lisp trabaja. Simple. Hay complicaciones -añadidas que veremos en un minuto, pero estos son -los fundamentos. Claro está, para escribir programas Lisp, se necesita -conocer como escribir definiciones de función y vincularlas a -nombres, y como hacer esto sin confundirnos a nosotros mismos o al -ordenador. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Complicaciones">Complicaciones</a></td><td> </td><td align="left" valign="top"> Variables, formas especiales, Listas. -</td></tr> -<tr><td align="left" valign="top"><a href="#Compilaci_00f3n-de-bytes">1.5.1 Compilación de bytes</a></td><td> </td><td align="left" valign="top"> Especialmente procesando código por la - velocidad. -</td></tr> -</table> - -<hr> -<a name="Complicaciones"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Interpr_00e9te-Lisp" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Interpr_00e9te-Lisp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Compilaci_00f3n-de-bytes" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Complicaciones-1"></a> -<h3 class="unnumberedsubsec">Complicaciones</h3> - -<p>Ahora, una primera complicación. Además de las listas, el -intérprete Lisp puede evaluar un símbolo no -citado que no tiene paréntesis -en torno a el. El intérprete Lisp intentará determinar el valor del -símbolo como una <em>variable</em>. Esta situación es -descrita en el apartado de las variablesla. (Ver <a href="#Variables">Variables</a>.) -</p> -<a name="index-Forma-Especial"></a> -<p>La segunda complicación ocurre debido a que algunas funciones son -inusuales y no funcionan de la manera habitual. Estas son llamadas -<em>formas especiales</em>. Son usadas para trabajos especiales, como -definir una función, y no son muchas de ellas. En los siguientes -capítulos, se introducirán varias de las -formas especiales más importantes. -</p> -<p>La tercera y final complicación es la siguiente: si la función que -el intérprete Lisp está buscando no es una forma especial, y si -es parte de una lista, el intérprete Lisp mira si la lista -tiene una lista dentro de ella. Si hay una lista dentro, el intérprete -Lisp -primero descubre qué hacer con la lista interior, y luego trabaja en la -lista exterior. Si aún hay otra lista embebida -dentro de la lista interna, trabaja en esta primero, y -así. Siempre se trabaja en la lista más interna primero. El -intérprete trabaja en la lista más interana primero, para evaluar el -resultado de esta lista. El resultado puede ser usado por la -expresión entre paréntesis. -</p> -<p>Por lo demás, el intérprete trabaja de izquierda a derecha, desde -una expresión a la siguiente. -</p> -<hr> -<a name="Compilaci_00f3n-de-bytes"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Complicaciones" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Interpr_00e9te-Lisp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Evaluaci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Compilacion-de-bytes"></a> -<h3 class="subsection">1.5.1 Compilación de bytes</h3> -<a name="index-Compilando-Byte"></a> - -<p>Otro aspecto de interpretación: el intérprete Lisp es capaz de -interpretar dos tipos de entidad: código humanamente legible, en el -que nos centraremos exclusivamente, y código especialmente procesado, -llamado <em>byte compilado</em>, que no es humanamente legible. El -código máquina compilado se ejecuta más rápido que el código -humanamente legible. -</p> -<p>Tu puedes transformar código legible por humanos en código compilado -ejecutando uno de los comandos de compilacion como -<code>byte-compile-file</code>. El código compilado es normalmente -almacenado en un fichero que finaliza con una extensión ‘<tt>.elc</tt>’ -en vez de una extensión ‘<tt>.el</tt>’. Verás ambos tipos de ficheros -en el directorio ‘<tt>emacs/lisp</tt>’; los ficheros para leer estos -tienen la extensión ‘<tt>.el</tt>’. -</p> -<p>Como una cuestión práctica, para hacer la mayoría de las -cosas como personalizar o extender Emacs, no -necesitas compilar byte; y no comentare el asunto -aquí. Ver <a href="elisp.html#Compilaci_00f3n-de-Byte">Compilación de Byte</a> in <cite>El Manual de Referencia de GNU Emacs</cite>, para una completa -descripción sobre compilar código. -</p> -<hr> -<a name="Evaluaci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Compilaci_00f3n-de-bytes" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#C_00f3mo-el-int_00e9rprete-act_00faa" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Evaluacion"></a> -<h2 class="section">1.6 Evaluación</h2> -<a name="index-Evaluacion"></a> - -<p>Cuando el intérprete Lisp trabaja en una expresión, el término -para la actividad es llamada <em>evaluación</em>. Decimos que el -intérprete ‘evalúa la expresión’. Yo he usado este término -varias veces antes. La palabra proviene de su uso en el lenguaje -cotidiano, ‘para determinar el valor o la cantidad de; para -estimar’ de acuerdo a <cite>Webster’s New Collegiate Dictionary</cite>. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#C_00f3mo-el-int_00e9rprete-act_00faa">Cómo el intérprete actúa</a></td><td> </td><td align="left" valign="top"> Devolver y Efectos Colaterales... -</td></tr> -<tr><td align="left" valign="top"><a href="#Evaluando-listas-propias">1.6.1 Evaluando listas propias</a></td><td> </td><td align="left" valign="top"> Listas con listas... -</td></tr> -</table> - -<hr> -<a name="C_00f3mo-el-int_00e9rprete-act_00faa"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Evaluaci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Evaluando-listas-propias" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Como-el-interprete-actua"></a> -<h3 class="unnumberedsubsec">Cómo el intérprete actúa</h3> - -<a name="index-valor-devuelto-explicado"></a> -<p>Después de evaluar una expresión, el intérprete Lisp normalmente -<em>devuelve</em> el valor que el ordenador produce al llevar a cabo -las instrucciones encontradas en la definición de la función, o -quizás dará esta función y producirá un mensaje de error. (El -intérprete puede también quedarse colgado, por así -decirlo, a una función diferente o puede intentar repetir -continuamente lo que está haciendo y para siempre en lo que -se llama un ‘bucle infinito’. Estas acciones son menos -comunes; y pueden ignorarse). Más frecuentemente, el intérprete -devuelve un valor. -</p> -<a name="index-efecto-lateral-definido"></a> -<p>Al mismo tiempo el intérprete devuelve un valor, puede hacer -cualquier cosa más también, tal como mover un cursor o copiar un -fichero; este otro tipo de acción es llamado <em>efecto -secundario</em>. Acciones que los humanos creen que son importantes tales -como imprimir resultados, con frecuencia son, “efectos secundarios” del -intérprete Lisp. La jerga puede sonar peculiar, pero resulta que es -bastante fácil aprender a utilazar los efectos secundarios. -</p> -<p>En resumen, evaluar una expresión simbólica normalmente -causa que el intérprete devuelva un valor y tal vez llevar a cabo un -efecto -secundario; o al menos produce un error. -</p> -<hr> -<a name="Evaluando-listas-propias"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#C_00f3mo-el-int_00e9rprete-act_00faa" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Variables" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Evaluando-listas-propias-1"></a> -<h3 class="subsection">1.6.1 Evaluando listas propias</h3> -<a name="index-Evaluacion-de-listas-internas"></a> -<a name="index-Evaluando-listas-internas"></a> - -<p>Si la evaluación se aplica a una lista que está dentro de una -lista, la lista externa puede usar el valor devuelto por la primera -evaluación como información cuando la lista externa es -evaluada. Esto explica por qué las expresiones internas son evaluadas -primero: los valores devueltos son usados por las expresiones -externas. -</p> -<p>Nosotros podemos investigar este proceso evaluando otro ejemplo -adicional. Coloca tu cursor después de la siguiente expresión y -presiona <kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 2 (+ 3 3)) -</pre></div> - -<p>El número 8 aparecerá en el área echo. -</p> -<p>Lo que ocurre es que el intérprete Lisp primero evalúa la -expresión interna, <code>(+ 3 3)</code>, para que el valor 6 se devuelva; -a continuación evalúa la expresión externa como si fuera escrita -<code>(+ 2 6)</code>, que devuelve el valor 8. Puesto que no hay más -expresiones entre parentesis a evaluar el intérprete imprime este valor -en el área echo. -</p> -<p>Ahora es fácil comprender el nombre del comando invocado por -el atajo <kbd>C-x C-e</kbd>: el nombre es <code>eval-last-sexp</code>. Las letras -<code>sexp</code> son una abreviación para ‘expresión simbólica’, y -<code>eval</code> es una abreviación para ‘evaluar’. El comando significa -‘evaluar la última expresión simbólica’. -</p> -<p>Como un experimento, puedes intentar evaluar la expresión -poniendo el cursor al principio de la siguiente línea -inmediatamente después de la expresión, o dentro de la expresión. -</p> -<p>Aquí hay otra copia de la expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 2 (+ 3 3)) -</pre></div> - -<p>Si se posiciona el cursor al principio de la línea en -blanco que sigue inmediatamente a la expresión y presionas <kbd>C-x -C-e</kbd>, todavía se obtendrá el valor 8 impreso en el -área echo. Ahora intenta poner el cursor dentro de la -expresión. Si lo coloca justo después del penultimo -paréntesis (dara la impresión de situarse sobre el -último paréntesis), ¡obtendrá un 6 impreso en -el área echo! Esto es porque el comando evalúa la expresión -<code>(+ 3 3)</code>. -</p> -<p>Ahora coloque el cursor inmediatamente después de un -número. Presiona <kbd>C-x C-e</kbd> y obtendrá el número en -sí. En Lisp, si evalúas un número, obtienes el -número en sí—así es cómo los números difieren -de los símbolos. Si se evalúa una lista que inicia con -un símbolo como <code>+</code>, tendrás un valor devuelto -que es el resultado del ordenador tras ejecutar las instrucciones que -aparecen -en la definición de la función adjunta a este nombre. Si un -símbolo por sí mismo es evaluado, algo -diferente sucede, como veremos en la siguiente sección. -</p> -<hr> -<a name="Variables"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Evaluando-listas-propias" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-rellenar-columna" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Variables-1"></a> -<h2 class="section">1.7 Variables</h2> -<a name="index-Variables"></a> - -<p>En Emacs Lisp, un símbolo puede estar ligado a un valor -como a una definición de función. Las dos son -diferentes. La definición de función es un conjunto de -instrucciones que el ordenador ejecuta. Un valor, por otro lado, es -algo, como un número o un nombre, que puede variar (es por ello, que -tal símbolo es llamado variable). El valor -de un símbolo puede ser cualquier expresión en Lisp, por -ejemplo un símbolo, número, lista, o cadena. Un -símbolo que tiene un valor es con frecuencia llamado una -<em>variable</em>. -</p> -<p>Un símbolo puede tener ambos, una definición de -función y un valor adjunto al mismo tiempo. O puede tener solo uno u -otro. Los dos son independientes. Esto es algo similar a la forma en que el -nombre Cambridge puede referirse a la ciudad en Massachusetts y tener -alguna información ligada al nombre, por ejemplo, un “gran -centro de programación”. -</p> - -<p>Otra forma de pensar en esto es imaginar un símbolo como un mueble con -cajones. La definición de función se pone en un cajón, el valor en -otro, y -asi sucesivamente. Lo que se pone en el cajón que contiene el valor puede -ser cambiado sin afectar los contenidos del cajón que almacena la -definición de función, y viceversa. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Ejemplo-de-rellenar-columna"><code>fill-column</code>, un ejemplo de variable</a></td><td> </td><td align="left" valign="top"> Ejemplo de rellenar columna -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-vac_00eda">1.7.1 Mensaje de error de un símbolo sin una función</a></td><td> </td><td align="left" valign="top"> El mensaje de error para un - símbolo sin una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#Variable-vac_00eda">1.7.2 Mensaje de error de un símbolo sin un valor</a></td><td> </td><td align="left" valign="top"> El mensaje de error para un - símbolo sin un valor. -</td></tr> -</table> - -<hr> -<a name="Ejemplo-de-rellenar-columna"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Variables" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Variables" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-vac_00eda" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="fill_002dcolumn_002c-un-ejemplo-de-variable"></a> -<h3 class="unnumberedsubsec"><code>fill-column</code>, un ejemplo de variable</h3> - -<a name="index-fill_002dcolumn_002c-una-variable-de-ejemplo"></a> -<a name="index-Variable-de-Ejemplo_002c-fill_002dcolumn"></a> -<a name="index-Variable_002c-ejemplo-de_002c-fill_002dcolumn"></a> -<p>La variable <code>fill-column</code> ilustra un símbolo con un -valor adjunto: en cada buffer de GNU Emacs, este símbolo -se establece a algún valor, normalmente 72 o 70, pero algunas veces -a algún otro valor. Para encontrar el valor de este -símbolo, evalúalo por sí mismo. Si está -leyendo esto en Info dentro de GNU Emacs, puedes hacer esto -poniendo el cursor después del símbolo y pulsar -<kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">fill-column -</pre></div> - -<p>Después de presionar <kbd>C-x C-e</kbd>, Emacs imprimió el -número 72 en mi área echo. Este es el valor que he establecido para -<code>fill-column</code> mientras escribo esto. Puede -ser diferente para ti en tu búffer Info. Observe que el valor devuelto -como una variable es impreso exactamente de la misma forma que el -valor devuelto por una función tras ejecutar sus instrucciones. Desde -el punto de vista del intérprete Lisp, un valor devuelto es un valor -devuelto. Que -tipo de expresión sea, deja de importar una vez que el valor -se conoce. -</p> -<p>Un símbolo puede tener cualquier valor ligado a él o, -siendo tecnicos, se puede <em>bind</em> (asociar) la variable a un valor: a -un número, por ejemplo 72; a una cadena, <code>\"como esta\"</code>; a -una lista, como <code>(abeto pino roble)</code>; podemos incluso asociar -una variable a una definición de función. -</p> -<p>Un símbolo puede vincularse a un valor de varias -maneras. Ver <a href="#set-y-setq">Configurando el valor de una variable</a>, -para obtener información sobre una manera de hacer esto. -</p> -<hr> -<a name="Funci_00f3n-vac_00eda"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-rellenar-columna" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Variables" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Variable-vac_00eda" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Mensaje-de-error-de-un-simbolo-sin-una-funcion"></a> -<h3 class="subsection">1.7.1 Mensaje de error de un símbolo sin una función</h3> -<a name="index-Simbolo-sin-funcion-de-error"></a> -<a name="index-Error-para-simbolo-sin-funcion"></a> - -<p>Cuando se evalúa <code>fill-column</code> para encontrar el valor de una -variable, no se ponen paréntesis alrededor de la palabra. Esto es -porque no pretendemos usarlos como un nombre de función. -</p> -<p>Si <code>fill-column</code> fuese el primer o único elemento de una lista, -el intérprete de Lisp intentaría encontrar la -definición de función adjunta. Pero <code>fill-column</code> no tiene -una definición de función. Prueba evaluando esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(fill-column) -</pre></div> - -<p>Se creará un buffer ‘<tt>*Backtrace*</tt>’ que dice: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--Lisp error: (void-function fill-column) - (fill-column) - eval((fill-column)) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>(Recuerda, para salir del depurador y hacer que la ventana del depurador -desaparezca, presiona <kbd>q</kbd> en el buffer ‘<tt>*Backtrace*</tt>’.) -</p> - -<hr> -<a name="Variable-vac_00eda"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-vac_00eda" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Variables" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Mensaje-de-error-de-un-simbolo-sin-un-valor"></a> -<h3 class="subsection">1.7.2 Mensaje de error de un símbolo sin un valor</h3> -<a name="index-Simbolo-sin-valor-de-error"></a> -<a name="index-Error-para-simbolo-sin-valor"></a> - -<p>Si se intenta evaluar un símbolo que no tiene un valor -asociado, recibirá un mensaje de error. Esto se puede ver -experimentando con nuestra suma 2 más 2. En la siguiente -expresión, pon el cursor correcto después del <code>+</code>, antes del -primer número 2, presiona <kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 2 2) -</pre></div> - -<p>En GNU Emacs 24, se creará un buffer ‘<tt>*Backtrace*</tt>’ que dice: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--Lisp error: (void-variable +) - eval(+) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>(De nuevo, se puede salir del depurador pulsando <kbd>q</kbd> en el -búffer ‘<tt>*Backtrace*</tt>’.) -</p> -<p>Esta traza es diferente del primer mensaje de error que -vimos, que dijimos, ‘<samp>Debugger entered--Lisp error: (void-function -esto)</samp>’. En este caso, la función no -tiene una valor como una variable; mientras en el otro mensaje de -error, la función (la palabra ‘esto’) no tuvo una definición. -</p> -<p>En este experimento con el <code>+</code>, lo que se hizo fué causar -que el intérprete Lisp evalúe el <code>+</code> y busque el valor de la -variable en vez de la definición de la función. Hicimos -esto colocando el cursor justo después del símbolo en -lugar de ponerlo al final de los paréntesis que cierran la lista como -hicimos -antes. Como consecuencia, el intérprete Lisp evaluó la -s-expresión anterior, que en este caso fué el <code>+</code> en -sí. -</p> -<p>Ya que <code>+</code> no tiene un valor asociado, solo la definición de -función, el mensaje de error informa que el valor del -símbolo como una variable estaba vacío. -</p> - -<hr> -<a name="Argumentos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Variable-vac_00eda" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Tipos-de-datos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Argumentos-1"></a> -<h2 class="section">1.8 Argumentos</h2> -<a name="index-Argumentos"></a> -<a name="index-Pasando-informacion-para-funciones"></a> - -<p>Para ver cómo la información se pasa a las funciones, veamos -de nuevo a nuestro viejo recurso, la adición de dos más dos. En -Lisp, esto se escribe como sigue: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 2 2) -</pre></div> - -<p>Si se evalúa esta expresión, el número 4 aparecerá en tu área -echo. Lo que el intérprete de Lisp hace es sumar los números despues -del <code>+</code>. -</p> -<a name="index-argumento-definido"></a> -<p>Los números sumados por <code>+</code> son llamados <em>argumentos</em> de -la función <code>+</code>. Estos números son la información que se -da o <em>pasa</em> a la función. -</p> -<p>La palabra ‘argumento’ viene del ámbito de las matemáticas y no se -refiere a una disputa entre 2 personas, sino que se refiere a la -información presentada a la función, en este caso, al <code>+</code>. En -Lisp, los argumentos de una función son los átomos o listas que -siguen a la función. Los valores devueltos por la evaluación de -estos átomos o listas son pasados a la función. Funciones -diferentes requieren diferentes números de argumentos; algunas -funciones no requieren ninguno en absoluto.<a name="DOCF2" href="#FOOT2">(2)</a> -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Tipos-de-datos">1.8.1 Tipos de argumentos de datos</a></td><td> </td><td align="left" valign="top"> Tipos de datos pasados a una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#Argumentos-como-variables-o-listas">1.8.2 Un argumento como el valor de una variable o lista</a></td><td> </td><td align="left" valign="top"> Un argumento puede ser el valor de - una variable o lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#N_00famero-de-variables-de-argumentos">1.8.3 Número de variables de argumentos</a></td><td> </td><td align="left" valign="top"> Algunas funciones pueden tomar un - número variable de argumentos. -</td></tr> -<tr><td align="left" valign="top"><a href="#Tipo-incorrecto-de-argumento">1.8.4 Usando el tipo incorrecto de objeto como un argumento</a></td><td> </td><td align="left" valign="top"> Pasando un argumento del tipo incorrecto a - una función. -</td></tr> -<tr><td align="left" valign="top"><a href="#message">1.8.5 La función <code>message</code></a></td><td> </td><td align="left" valign="top"> Una función útil para enviar mensajes. -</td></tr> -</table> - -<hr> -<a name="Tipos-de-datos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos-como-variables-o-listas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Tipos-de-argumentos-de-datos"></a> -<h3 class="subsection">1.8.1 Tipos de argumentos de datos</h3> -<a name="index-Tipos-de-datos"></a> -<a name="index-Tipos-de-datos-1"></a> -<a name="index-Tipos-de-dato-de-los-argumentos"></a> - -<p>Los tipos de datos que deberían ser pasados a una -función dependen de que tipo de información usan. Los argumentos de -una función como <code>+</code> deben tener valores que son -números, puesto que <code>+</code> añade números. Otras funciones usan -diferentes tipos de datos para sus argumentos. -</p> -<a name="index-concatenar"></a> -<p>Por ejemplo, la función <code>concat</code> concatena o une dos o más -cadenas de texto para producir una cadena. Los argumentos son -cadenas. La concatenación de los dos caracteres de cadenas -<code>abc</code>, <code>def</code> produce una cadena <code>abcdef</code>. Esto -puede ser visto evaluando lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(concat "abc" "def") -</pre></div> - -<p>El valor producido para evaluar esta expresión es <code>"abcdef"</code>. -</p> -<p>Una función tal como <code>substring</code> usa como argumento tanto una -cadena como números. La función devuelve una parte de la cadena, -una subcadena del primer argumento. Esta función toma tres -argumentos. Su primer argumento es la cadena de caracteres, el segundo -y tercer argumento son números que indican el principio y el fin de la -subcadena. Los números son un conteo del número de caracteres -(incluyendo espacios y puntuaciones) desde el principio de la cadena. -</p> -<p>Por ejemplo, si evalúa lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(substring "El rápido zorro marrón saltó." 10 15) -</pre></div> - -<p>se verá <code>"zorro"</code> en el área echo. Los argumentos son la cadena -y los dos números. -</p> -<p>Nótese que la cadena pasada a <code>substring</code> es un solo átomo -apesar de estar compuesto de varias palabras separadas por -espacios. Lisp considera que cualquier cosa entre dos marcas de cita es -parte -de la cadena, incluyendo los espacios. Se puede pensar la función -<code>substring</code> como un tipo de ‘acelerador de particulas’ ya que toma -un átomo indivisible y extrae una parte. Sin embargo, -<code>substring</code> solo es capaz de extraer una subcadena desde un -argumento que es una cadena, no otro tipo de átomo tal como un -número o símbolo. -</p> -<hr> -<a name="Argumentos-como-variables-o-listas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Tipos-de-datos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#N_00famero-de-variables-de-argumentos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-argumento-como-el-valor-de-una-variable-o-lista"></a> -<h3 class="subsection">1.8.2 Un argumento como el valor de una variable o lista</h3> - -<p>Un argumento puede ser un símbolo que devuelva un valor -cuando es evaluado. Por ejemplo, evaluar el símbolo -<code>fill-column</code> en si, devuelve un -número. Este número puede ser usado en una adición. -</p> -<p>Posicionar el cursor después de la siguiente expresión y presiona -<kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 2 fill-column) -</pre></div> - -<p>El valor será dos más el número que se obtiene al evaluar solamente -<code>fill-column</code>. En mí caso, este es 74, porque mi -valor de <code>fill-column</code> es 72. -</p> -<p>Como acabamos de ver, un argumento puede ser un símbolo que -devuelve un valor cuando se evalúa. Además, un argumento puede -ser una lista que devuelve un valor cuando es evaluada. Por ejemplo, -en la siguiente expresión, los argumentos de la función -<code>concat</code> son las cadenas <code>"Los"</code> y <code>" zorros rojos."</code> y la lista <code>(number-to-string (+ 2 fill-column))</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(concat "Los " (number-to-string (+ 2 fill-column)) " zorros rojos.") -</pre></div> - -<p>Si se evalúa esta expresión—y si, como con mi Emacs, -<code>fill-column</code> se evalúa a 72—aparecerá <code>"Los 74 -zorros rojos."</code> en el área echo. (Nótese que se debe poner espacio -después de la palabra ‘<samp>Los</samp>’ y antes de la palabra ‘<samp>rojos</samp>’ -y así es como aparecerá en la cadena final. La -función <code>number-to-string</code> convierte el entero que devuelve la -función de adición a una cadena. <code>number-to-string</code> -también se conoce como <code>int-to-string</code>.) -</p> -<hr> -<a name="N_00famero-de-variables-de-argumentos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos-como-variables-o-listas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Tipo-incorrecto-de-argumento" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Numero-de-variables-de-argumentos"></a> -<h3 class="subsection">1.8.3 Número de variables de argumentos</h3> -<a name="index-Numero-variable-de-argumentos"></a> -<a name="index-Argumentos_002c-numero-variable-de"></a> - -<p>Algunas funciones, como <code>concat</code>, <code>+</code>, o <code>*</code>, -toman cualquier número de argumentos. (El <code>*</code> es el -símbolo para multiplicar.) Esto puede ser visto -evaluando cada una de las siguientes expresiones de la forma -habitual. Lo que verás en el área echo se imprime en este texto -después de ‘<samp>⇒</samp>’, que se puede leer como ‘evaluar a’. -</p> -<p>En el primer conjunto, las funciones no tienen argumentos: -</p> -<div class="smallexample"> -<pre class="smallexample">(+) ⇒ 0 - -(*) ⇒ 1 -</pre></div> - -<p>En este conjunto, las funciones tienen un argumento cada una: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 3) ⇒ 3 - -(* 3) ⇒ 3 -</pre></div> - -<p>En este conjunto, las funciones tienen tres argumentos cada una: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 3 4 5) ⇒ 12 - -(* 3 4 5) ⇒ 60 -</pre></div> - -<hr> -<a name="Tipo-incorrecto-de-argumento"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#N_00famero-de-variables-de-argumentos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#message" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Usando-el-tipo-incorrecto-de-objeto-como-un-argumento"></a> -<h3 class="subsection">1.8.4 Usando el tipo incorrecto de objeto como un argumento</h3> -<a name="index-Tipo-incorrecto-de-argumento"></a> -<a name="index-Argumento_002c-tipo-incorrecto-de"></a> - -<p>Cuando a una función se le pasa un argumento del tipo incorrecto, el -interpréte Lisp produce un mensaje de error. Por ejemplo, la -función <code>+</code> espera que los valores de sus argumentos sean -números. Como un experimento podemos pasar el -símbolo citado <code>hola</code> en vez de un -número. Coloca el cursor después de la siguiente expresión y -presiona <kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 2 'hola) -</pre></div> - -<p>Al hacer esto se generará un mensaje de error. Lo qué ha -ocurrido es que <code>+</code> ha intentado añadir el 2 al valor -devuelto por <code>'hola</code>, pero el valor devuelto por <code>'hola</code> -es el símbolo <code>hola</code>, no un número. Solo los -números pueden ser añadidos. Por tanto <code>+</code> -no pudo llevar a cabo su adición. -</p> -<p>Se creará e introducirá un búffer ‘<tt>*Backtrace*</tt>’ que dice: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p hola) - +(2 hola) - eval((+ 2 (quote hola))) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>Como de costumbre, el mensaje de error intenta ser útil y tiene sentido -después de aprender cómo leerlo.<a name="DOCF3" href="#FOOT3">(3)</a> -</p> -<p>La primera parte del mensaje de error es sencilla; dice ‘<samp>wrong -type argument</samp>’ (tipo de argumento incorrecto). A continuación viene la -misteriosa palabra tecnica ‘<samp><span class="nolinebreak">number-or-marker-p</span></samp>’. Esta -palabra está intentando decirte qué tipo de argumento espera <code>+</code>. -</p> -<p>El símbolo <code>number-or-marker-p</code> dice que el -intérprete Lisp está intentando determinar si la información -presentada (el valor del argumento) es un número o una marca (un -objeto especial que representa una posición de buffer). Lo que hace -es probar si se le estan dando numeros a sumar a <code>+</code>. -También chequea si el argumento es algo llamado -un marcador, que es una caracteristica específica de -Emacs Lisp. (En Emacs, las ubicaciones en un búffer se registran -como marcadores. Cuando se establece la marca con el comando -<kbd>C-@</kbd> o <kbd>C-<SPC></kbd>, su posición se guarda como un -marcador. La marca puede ser considerada como un número—el número de -caracteres es la localización desde el principio del búffer.) -En Emacs Lisp, <code>+</code> se puede utilizar para añadir el valor -numérico de los marcadores como números. -</p> -<p>La ‘<samp>p</samp>’ de <code>number-or-marker-p</code> es la encarnación de una -práctica iniciada en los primeros días de la -programación Lisp. La ‘<samp>p</samp>’ significa ‘predicado’. En la jerga -usada por los primeros investigadores de Lisp, un predicado se refiere -a una función para determinar si alguna propiedad es verdadera o -falsa. Así la ‘<samp>p</samp>’ nos dice que -<code>number-or-marker-p</code> es el nombre de una función que determina -si el argumento dado es un número o una marca. Otros -símbolos Lisp que finalizan en ‘<samp>p</samp>’ incluyen -<code>zerop</code>, una función que chequea si su argumento tienen el -valor de cero, y <code>listp</code>, una función que prueba si su -argumento es una lista. -</p> -<p>Finalmente, la última parte del mensaje de error es el -símbolo <code>hola</code>. Este es el valor del argumento -dado a <code>+</code>. Si a la adición se le hubiese pasado el -tipo correcto de objeto, el valor habría sido un -número, como 37, en lugar de un símbolo como -<code>hola</code>. Pero entonces no habrías obtenido el -mensaje de error. -</p> - -<hr> -<a name="message"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Tipo-incorrecto-de-argumento" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#set-y-setq" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-message"></a> -<h3 class="subsection">1.8.5 La función <code>message</code></h3> -<a name="index-message"></a> - -<p>Al igual que <code>+</code>, la función <code>message</code> toma un número variable -de argumentos. Se utiliza para enviar mensajes al usuario y es -tan útil que vamos a describirla. -</p> -<p>Se impre un mensaje en el área echo. Por ejemplo, puede -imprimir un mensaje en su área echo evaluando la siguiente lista: -</p> -<div class="smallexample"> -<pre class="smallexample">(message "¡Este mensaje aparece en el área echo!") -</pre></div> - -<p>Toda la cadena entre comillas dobles es un unico argumento y se -imprime <i>en su totalidad</i>. (Nótese que en este ejemplo, el mensaje en -sí aparece en el área echo entre comillas -dobles; esto se debe a que ves el valor devuelto por la función -<code>message</code>. En la mayoría de programas que escribiras, -el texto será impreso en -el área echo como un efecto secundario de <code>message</code>, sin las -comillas. Ver <a href="#multiply_002dby_002dseven-en-detalle"><code>multiply-by-seven</code> en detalle</a>, para un ejemplo de esto.) -</p> -<p>Sin embargo, si hay un ‘<samp>%s</samp>’ en la cadena de caracteres citada, la -función <code>message</code> no imprime el ‘<samp>%s</samp>’ como tal, pero mira -el siguente argumento a continuación de la cadena. Se evalúa el segundo -argumento e -imprime el valor en la ubicación de la cadena donde está el ‘<samp>%s</samp>’ . -</p> -<p>Puede ver esto colocando el cursor después de la siguiente -expresión y presionar <kbd>C-x C-e</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(message "El nombre de este búffer es: %s." (buffer-name)) -</pre></div> - -<p>En Info, <code>"El nombre de este búffer es: *info*."</code> aparecerá -en el área echo. La función <code>buffer-name</code> devuelve el nombre -del búffer como una cadena, que la función <code>message</code> inserta -en lugar de <code>%s</code>. -</p> -<p>Para imprimir un valor como un entero, utiliza ‘<samp>%d</samp>’ de la misma forma -que ‘<samp>%s</samp>’. Por ejemplo, para imprimir un mensaje en el -área echo que indique el valor de <code>fill-column</code>, evalúa lo -siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(message "El valor de fill-column es %d." fill-column) -</pre></div> - -<p>En mi sistema, cuando evalúo esta lista, <code>"El valor de -fill-column es 72"</code> aparece en mi área echo<a name="DOCF4" href="#FOOT4">(4)</a> -</p> -<p>Si hay más de un ‘<samp>%s</samp>’ en la cadena citada, el valor del primer -argumento después de la cadena citada se imprime en la posición del -primer ‘<samp>%s</samp>’ y el valor del segundo argunmento se imprime en la -posición del segundo ‘<samp>%s</samp>’, y así sucesivamente. -</p> -<p>Por ejemplo, si se evalúa lo siguiente, -</p> -<div class="smallexample"> -<pre class="smallexample">(message "¡Hay %d %s en la oficina!" - (- fill-column 14) "elefantes rosas") -</pre></div> - -<p>un mensaje característico aparecerá en el área -echo. En mi sistema dice <code>"¡Hay 58 elefantes rosas en -la oficina!"</code> -</p> -<p>Se evalua la expresión <code>(- fill-column 14)</code> y el número -resultante se inserta en lugar del ‘<samp>%d</samp>’; y la cadena entre -comillas dobles, <code>"elefantes rosas"</code>, se trata como un -solo argumento y se inserta en lugar del ‘<samp>%s</samp>’. (Esto es decir, -una cadena entre comillas dobles se evalúa así misma, -como un número.) -</p> -<p>Finalmente, aquí está un ejemplo algo complejo que no -solo ilustra el cálculo de un número, también muestra -como se puede usar una expresión dentro de una expresión para generar el -texto que -sustituira el ‘<samp>%s</samp>’: -</p> -<div class="smallexample"> -<pre class="smallexample">(message "Él vió %d %s" - (- fill-column 36) - (concat (substring - "Los rápidos zorros marrones saltaron." 12 18) - " rojos trotando.")) -</pre></div> - -<p>En este ejemplo, <code>message</code> tiene tres argumentos: la cadena, -<code>"Él vió %d %s"</code>, la expresión, <code>(- fill-column 32)</code>, y la -expresión a partir de -la función <code>concat</code>. El valor resultante desde la evaluación -de <code>(- fill-column 32)</code> se inserta en lugar del ‘<samp>%d</samp>’; y -el valor devuelto por la expresión que inicia con <code>concat</code> se -inserta en lugar del ‘<samp>%s</samp>’. -</p> -<p>Cuando <code>fill-column</code> es 70 y se evalúa la expresión, aparecera el -mensaje <code>"Él vió 41 zorros rojos trotando."</code> en tu -área echo. -</p> -<hr> -<a name="set-y-setq"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#message" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Usando-set" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Configurando-el-valor-de-una-variable"></a> -<h2 class="section">1.9 Configurando el valor de una variable</h2> -<a name="index-Variable_002c-asignando-valor"></a> -<a name="index-Asignando-valor-de-variable"></a> - -<a name="index-bind-se-definio"></a> -<p>Hay varias formas de asignar un valor a una variable. Una de -ellas es usar la función <code>set</code> o la función -<code>setq</code>. Otra forma es usar <code>let</code> (véase la sección <a href="#let"><code>let</code></a>). (La jerga -para este proceso es <em>bind</em> (ligar) una variable a un valor.) -</p> -<p>Las siguientes secciones no solo describen cómo operan <code>set</code> y -<code>setq</code>, también ilustran como se pasan los argumentos. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Usando-set">1.9.1 Usando <code>set</code></a></td><td> </td><td align="left" valign="top"> Configurando valores. -</td></tr> -<tr><td align="left" valign="top"><a href="#Usando-setq">1.9.2 Usando <code>setq</code></a></td><td> </td><td align="left" valign="top"> Configurando un valor citado. -</td></tr> -<tr><td align="left" valign="top"><a href="#Contando">1.9.3 Contando</a></td><td> </td><td align="left" valign="top"> Usando <code>setq</code> para contar. -</td></tr> -</table> - -<hr> -<a name="Usando-set"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#set-y-setq" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#set-y-setq" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Usando-setq" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Usando-set-1"></a> -<h3 class="subsection">1.9.1 Usando <code>set</code></h3> -<a name="index-set"></a> - -<p>Para establecer el valor del símbolo <code>flores</code> a la -lista <code>'(rosa violeta margarita botóndeoro)</code>, evalúa la -siguiente expresión colocando el cursor después de la -expresión y presiona <kbd>C-x C-e</kbd>. -</p> -<div class="smallexample"> -<pre class="smallexample">(set 'flores '(rosa violeta margarita botóndeoro)) -</pre></div> - -<p>La lista <code>(rosa violeta margarita botóndeoro)</code> aparecerá en el -área echo. Esto es <em>devuelto</em> por la función -<code>set</code>. Como efecto secundario, el símbolo -<code>flores</code> está ligado a la lista; es decir, el -símbolo <code>flores</code>, puede ser visto como una -variable, que entrega la lista como su valor. (Este proceso, -ilustra un efecto lateral al intérprete Lisp: asignando el valor, -que puede ser el efecto primario en el que los humanos -estamos interesados. Esto se debe a que cada función Lisp debe devolver -un valor si no se obtiene un error, pero solo tendrá un efecto -secundario si está diseñado para tener uno.) -</p> -<p>Después de evaluar la expresión <code>set</code>, se puede evaluar el -símbolo <code>flores</code> y devolverá el valor -asignado. Aquí está el símbolo. Coloca -el cursor al final de este y presiona <kbd>C-x C-e</kbd>. -</p> -<div class="smallexample"> -<pre class="smallexample">flores -</pre></div> - -<p>Cuando se evalúa <code>flores</code>, la lista <code>(rosa violeta margarita -botóndeoro)</code> aparece en el área echo. -</p> -<p>Por cierto, si se evalúa <code>'flores</code>, la variable con una -comilla en frente, lo que verá en el área echo es el -símbolo en sí mismo: <code>flores</code>. -Aquí está el símbolo citado, -para que pueda probar esto: -</p> -<div class="smallexample"> -<pre class="smallexample">'flores -</pre></div> - -<p>Nótese también, que cuando se usa <code>set</code>, se necesitan citar -ambos argumentos de <code>set</code>, a menos que los quiera evaluar. Puesto -que nosotros no queremos evaluar, ni la variable -<code>flores</code>, ni la lista <code>(rosa violeta margarita -botóndeoro)</code>, ambos se citan. (Cuando se usa <code>set</code> sin citar su -primer -argumento, el primer argumento se evalúa antes de realizar cualquier otra -cosa. Si hizo esto y <code>flores</code> no tenía -ya un valor, se tendría un mensaje de error con el -‘<samp>Valor de símbolo como variable -vacío</samp>’; por otro lado, si <code>flores</code> regreso un -valor después de ser evaluado, <code>set</code> -intentaría establecer el valor que fue -devuelto. Hay situaciones donde esto el justo lo que la función -a de hacer, pero tales situaciones son poco frecuentes.) -</p> -<hr> -<a name="Usando-setq"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Usando-set" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#set-y-setq" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Contando" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Usando-setq-1"></a> -<h3 class="subsection">1.9.2 Usando <code>setq</code></h3> -<a name="index-setq"></a> - -<p>Como una cuestión práctica, casi siempre se cita el primer argumento de -<code>set</code>. La combinación de <code>set</code> y un primer argumento citado -es tan común que tiene nombre propio: la forma especial -<code>setq</code>. Esta forma especial es igual a <code>set</code> excepto que -el primer argumento se cita automáticamente, por lo que no necesita -escribir la marca de cita. También, como -una conveniencia añadida, <code>setq</code> permite asignar varias -variables diferentes a diferentes valores, todo en una expresión. -</p> -<p>Para establecer el valor de la variable <code>carnívoros</code> a -la lista <code>'(leon tigre leopardo)</code> usando <code>setq</code>, se utiliza la -siguiente -expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq carnivoros '(leon tigre leopardo)) -</pre></div> - -<p>Esto es exactamente lo mismo que usar <code>set</code> excepto que el primer -argumento se cita automáticamente por <code>setq</code>. (La ‘<samp>q</samp>’ en -<code>setq</code> significa <code>quote</code>.) -</p> -<p>Con <code>set</code>, la expresión que se vería es: -</p> -<div class="smallexample"> -<pre class="smallexample">(set 'carnivoros '(leon tigre leopardo)) -</pre></div> - -<p>Además, <code>setq</code> se puede utilizar para asignar diferentes valores -a diferentes variables. El primer argumento se une a al valor -del segundo argumento, el tercer argumento se une a al valor del -cuarto argumento, y así sucesivamente. Por ejemplo, se -podría usar lo siguiente para asignar una lista de -árboles al símbolo <code>arboles</code> y una lista -de herbívoros al símbolo <code>herbivoros</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq arboles '(pino abeto roble arce) - herbivoros '(gacela antilope cebra)) -</pre></div> - -<p>(La expresión podría también haber estado en una -sola línea, pero podría no caber en -una página; y a los humanos les resulta más fácil leer listas -con un formato agradable.) -</p> -<p>Aunque he estado usando el término ‘asignar’, hay otra forma de -pensar respecto a el funcionamiento de <code>set</code> y <code>setq</code>; y consiste -en -decir que <code>set</code> y <code>setq</code> crean un símbolo -que <em>apunta</em> a la lista. Esta ultima forma de pensar es muy -común y en los capítulos siguientes deberiamos encontrar al -menos un símbolo con un ‘puntero’ como parte de su nombre. El -nombre es elegido porque el símbolo tiene un valor, -específicamente una lista, unida a el; o, expresado de otra -manera, el símbolo se ajusta para “apuntar” a la lista. -</p> -<hr> -<a name="Contando"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Usando-setq" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#set-y-setq" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Resumen" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Contando-1"></a> -<h3 class="subsection">1.9.3 Contando</h3> -<a name="index-Contando"></a> - -<p>He aquí un ejemplo que muestra cómo usar <code>setq</code> -en un contador. Se podría usar esto para contar cuantas -veces una parte de un programa se -repite. En primer lugar asigna una variable a cero; a continuación suma -uno al -número cada vez que el programa se -repita. Para ello, se necesita una variable que sirve como un -contador, y dos expresiones: una expresión <code>setq</code> inicial que asigna -la -variable contador a cero; y una segunda expresión <code>setq</code> que -incrementa el contador cada vez se evalua. -</p> -<div class="smallexample"> -<pre class="smallexample">(setq contador 0) ; <span class="roman">Llamemos a esto el inicializador.</span> - -(setq contador (+ contador 1)) ; <span class="roman">Este es el incremento.</span> - -contador ; <span class="roman">Esste es el contador.</span> -</pre></div> - -<p>(El texto que sigue al ‘<samp>;</samp>’ son los comentarios. Ver Véase la sección <a href="#Cambiar-un-defun">Cambiar una definición de función</a>.) -</p> -<p>Si evalúas la primera de estas expresiones, el inicializador, -<code>(setq contador 0)</code>, y luego evalúas la tercera expresión, -<code>contador</code>, el número <code>0</code> aparecerá en el área echo. Si -a continuación se evalúa la segunda expresión, el incremento, -<code>(setq contador (+ contador 1))</code>, el contador tendrá el valor -1. Así que si evalúas de nuevo <code>contador</code>, el número -<code>1</code> aparecerá en el área echo. Cada vez que se evalúa la -segunda expresión, el valor del contador será incrementado. -</p> -<p>Al evalúar el incremento, <code>(setq contador (+ contador -1))</code>, el intérprete Lisp primero evalúa la lista interna; esta es -la adición. Con el fin de evaluar esta lista, se debe evaluar la -variable <code>contador</code> y el número <code>1</code>. Cuando evalúa la -variable <code>contador</code>, se recibe su valor actual. Se pasa este valor y -el número <code>1</code> a <code>+</code> que los añade. La suma -es devuelta como el valor de la list interior y pasa a <code>setq</code> que -asigna la variable <code>contador</code> a este nuevo valor. Por lo tanto, el -valor de la variable <code>contador</code>, cambia. -</p> -<hr> -<a name="Resumen"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Contando" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-de-mensajes-de-error" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Resumen-1"></a> -<h2 class="section">1.10 Resumen</h2> - -<p>Aprender Lisp es como subir una colina en la que la primera parte -es la más empinada. Ahora has subido la parte más -difícil; lo que queda se vuelve más fácil a medida que -avanzas hacia adelante. -</p> -<p>En resumen, -</p> -<ul> -<li> -Los programas Lisp se componen de expresiones, que son listas o átomos -individuales. - -</li><li> -La listas se componen de cero o más átomos o listas internas, -separadas por espacios en blanco y rodeadas por paréntesis. Una lista -puede estar vacía. - -</li><li> -Los átomos son símbolos multi-carácter, como -<code>forward-paragraph</code>, símbolos de un solo caracterer -como <code>+</code>, cadenas de caracteres entre comillas dobles, -o números. - -</li><li> -Un número se evalúa a sí mismo. - -</li><li> -Una cadena entre comillas dobles también se evalúa a -sí mismo. - -</li><li> -Cuando se evalúa un símbolo a sí mismo, -su valor se devuelve. - -</li><li> -Cuando se evalúa una lista, el intérprete Lisp mira el primer -símbolo en la lista y luego la definición de función -asociada a este símbolo. A continuación, las -instrucciones en la definición de función se llevan a cabo. - -</li><li> -Una marca de cita, -<code>'</code> -, le indica al intérprete Lisp que devuelva la -siguiente expresión como esta escrita, y no la evalúa como lo haria si -la cita -no estuviera alli. - -</li><li> -Los argumentos son la información que se pasa a una función. Los -argumentos a una función son computados evaluando el resto de los -elementos de la lista de la que la función es el primer elemento. - -</li><li> -Una función siempre devuelve un valor cuando se evalúa (a menos -que obtenga un error); además, también se puede llevar a cabo algun tipo -de acción -llamado “efecto secundario”. En muchos casos, el propósito principal -de una función es crear un efecto secundario. -</li></ul> - -<hr> -<a name="Ejercicios-de-mensajes-de-error"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Resumen" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicios-1"></a> -<h2 class="section">1.11 Ejercicios</h2> - -<p>Unos ejercicios sencillos: -</p> -<ul> -<li> -Generar un mensaje de error evaluando un símbolo -apropiado que no está entre paréntesis. - -</li><li> -Generar un mensaje de error evaluando un símbolo -apropiado que está entre paréntesis. - -</li><li> -Crear un contador que se incrementa en dos en lugar de uno. - -</li><li> -Escribe una expresión que imprima un mensaje en el área eco cuando es -evaluada. -</li></ul> - -<hr> -<a name="Practicando-evaluaci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Procesamiento-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-de-mensajes-de-error" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#C_00f3mo-evaluar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Practicando-evaluacion"></a> -<h1 class="chapter">2 Practicando evaluación</h1> -<a name="index-Practicando-evaluacion"></a> -<a name="index-Evaluacion-practica"></a> - -<p>Antes de aprender como escribir una definición de función en Emacs -Lisp, es útil gastar un poco de tiempo evaluando varias expresiones -que ya han sido escritas. Estas expresiones serán listas con -funciones como su primer (y con frecuencia único) elemento. Dado que -algunas de las funciones asociadas con búffers son a la vez simples e -interesantes, vamos a iniciar con estas. En esta sección, -vamos a evaluar algunas de este tipo. En otra sección, estudiaremos el -código de varias otras funciones relacionadas con búffers, para -ver la forma cómo fueron escritas. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#C_00f3mo-evaluar">Cómo evaluar</a></td><td> </td><td align="left" valign="top"> Escribiendo comandos de edición o con - <kbd>C-x C-e</kbd>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Nombres-de-b_00faffer">2.1 Nombres de búffer</a></td><td> </td><td align="left" valign="top"> Buffers y ficheros son diferentes. -</td></tr> -<tr><td align="left" valign="top"><a href="#Obteniendo-b_00faffers">2.2 Obteniendo búffers</a></td><td> </td><td align="left" valign="top"> Obteniendo un buffer por sí - mismo, no solamente su nombre. -</td></tr> -<tr><td align="left" valign="top"><a href="#Cambiando-b_00faffers">2.3 Cambiando búffers</a></td><td> </td><td align="left" valign="top"> Cómo cambiar a otro buffer. -</td></tr> -<tr><td align="left" valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td><td> </td><td align="left" valign="top"> Dónde el punto está - localizado y el tamaño del - buffer. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-evaluaci_00f3n">2.5 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio de evaluación -</td></tr> -</table> - -<hr> -<a name="C_00f3mo-evaluar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Nombres-de-b_00faffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Como-evaluar"></a> -<h2 class="unnumberedsec">Cómo evaluar</h2> - -<p><i>Siempre que proporciona un comando de edición</i> a Emacs Lisp, -como el comando para mover el cursor o para desplazarse por la pantalla, -<i>se está evaluando una expresión,</i> de la cual el primer elemento es -una función. <i>Así es cómo funciona Emacs</i>. -</p> -<a name="index-funcion-interactiva-definida"></a> -<a name="index-comando-definido"></a> -<p>Al presionar las teclas, se causa que el intérprete Lisp evalúe -una expresión que devuelve resultados. Incluso escribir texto -plano implica evalúar una función Emacs Lisp, en este caso, -se utiliza <code>self-insert-command</code>, que simplemente inserta el -caracter escrito. Las funciones que se evalúan presionando -atajos de teclado se llaman funciones <em>interactive</em>, o -<em>comandos</em>; como crear una función interactive será ilustrado -en el capítulo sobre cómo escribir definiciones de -funciones. Ver <a href="#Interactive">Creando una Función Interactive</a>. -</p> -<p>Además de presionar comandos de teclado, hemos visto una segunda -manera de evaluar una expresión: colocar el cursor después de -una lista y presionar <kbd>C-x C-e</kbd>. Esto es lo que se hará -en el resto de esta sección. Hay otras maneras de evaluar una -expresión; que serán descritas cuando llegemos a ellas. -</p> -<p>Ademas de utilizarse para practicar la evaluación, las funciones mostradas -en -las siguientes secciones son importantes por derecho -propio. Un estudio de estas funciones deja claro la distinción -entre búffers y ficheros, cómo cambiar a un búffer, y como -determinar una ubicación dentro de ella. -</p> -<hr> -<a name="Nombres-de-b_00faffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#C_00f3mo-evaluar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Obteniendo-b_00faffers" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Nombres-de-buffer"></a> -<h2 class="section">2.1 Nombres de búffer</h2> -<a name="index-buffer_002dname"></a> -<a name="index-buffer_002dfile_002dname"></a> - -<p>Las dos funciones, <code>buffer-name</code> y <code>buffer-file-name</code>, -muestran la diferencia entre un fichero y un búffer. Cuando -se evalúa la siguiente expresión, <code>(buffer-name)</code>, el nombre -del buffer aparece en el area eco. Al evaluar <code>(buffer-file-name)</code>, el -nombre -del fichero al que se relaciona el búffer aparece en el área -echo. Normalmente, el nombre devuelto por <code>(buffer-name)</code> es el -mismo que el nombre del fichero al que hace referencia, y el nombre -devuelto por <code>(buffer-file-name)</code> es la ruta completa del fichero. -</p> -<p>Un fichero y un búffer son dos entidades diferentes. Un fichero es -información grabada de manera permanente en el ordenador (a menos -que se borre). Un búffer, por otro lado, es información dentro -de Emacs que desaparecerá al final de la sesión de edición (o -cuando se mate el búffer). Normalmente, un búffer contiene -información que se ha copiado desde un fichero; decimos que -el búffer está <em>visitando</em> este fichero. Esta copia es la que se -trabaja y modifica. Los cambios al búffer no cambian el fichero, hasta -ser guardados. Al guardar el búffer, el búffer se copia en el -fichero y por lo tanto se guarda de forma permanente. -</p> -<p>Si está leyendo esto en Info dentro de GNU Emacs, puede evaluar -cada una de las siguientes expresiones colocando el cursor -después de estas y pulsando <kbd>C-x C-e</kbd>. -</p> -<div class="example"> -<pre class="example">(buffer-name) - -(buffer-file-name) -</pre></div> - -<p>Cuando hago esto en Info, el valor devuelto para la evaluación de -<code>(buffer-name)</code> es ‘<tt>"*info*"</tt>’, y el valor devuelto por -evaluar <code>(buffer-file-name)</code> es ‘<tt>nil</tt>’. -</p> -<p>Por otro lado, mientras escribo este documento, el valor -devuelto por la evaluación de <code>(buffer-name)</code> es -‘<tt>"introduction.texinfo"</tt>’, y el valor devuelto por la evaluación de -<code>(buffer-file-name)</code> es ‘<tt>"/gnu/work/intro/introduction.texinfo"</tt>’. -</p> -<a name="index-nil_002c-historia-de-palabra"></a> -<p>El primero es el nombre del búffer y el segundo es el nombre del -fichero. En Info, el nombre del búffer es ‘<tt>"*info*"</tt>’. Info no -apunta a ningún fichero, por lo que el resultado de evaluar -<code>(buffer-file-name)</code>] es ‘<tt>nil</tt>’. El símbolo -<code>nil</code> proviene del Latin, significa ‘nada’; en este caso, -significa que el búffer no está asociado con ningun -fichero. (En Lisp, <code>nil</code> también se usa con el significado de -‘falso’ y es sinómino para lista vacía, <code>()</code>.) -</p> -<p>Cuando estoy escribiendo, el nombre de mi búffer es -‘<tt>"introduction.texinfo"</tt>’. El nombre del fichero al que -se apunta es ‘<tt>"/gnu/work/intro/introduction.texinfo"</tt>’. -</p> -<p>(En las expresiones, los paréntesis hacen que el intérprete Lisp -trate a <code><span class="nolinebreak">buffer-name</span></code> y <code><span class="nolinebreak">buffer-file-name</span></code> como -funciones; sin los paréntesis, el intérprete -intentaría evaluar los símbolos como -variables. Ver <a href="#Variables">Variables</a>.) -</p> -<p>A pesar de la distinción entre ficheros y búffers, con frecuencia -encontrara que hay personas que se refieren a un fichero cuando quieren -un búffer y vice-versa. En realidad, la mayoría de la -gente dice, “Estoy editando un fichero,” en lugar de decir, -“Estoy editando un búffer que pronto voy a guardar en un fichero.” -Esto casi siempre queda claro a partir del contexto de lo que las personas -quieren -decir. No obstante, al tratar con programas de ordenador, es -importante tener la distinción en mente, ya que el ordenador no es -tan inteligente como una persona. -</p> -<a name="index-Buffer_002c-historia-de-palabra"></a> -<p>Por cierto, la palabra ‘búffer’, viene del significado de la -palabra como un cojín que amortigua la fuerza de una colisión. En los -primeros ordenadores, un búffer amortiguaba la interacción entre -los ficheros y la unidad central de procesamiento de la cumputadora. Los -tambores o cintas -que contenian un fichero y la unidad de procesamiento eran -piezas de equipamiento muy diferentes entre si, -trabajando a sus propias velocidades, por rachas. El búffer hizo posible -que -ambos trabajaran juntos de manera efectiva. Con el tiempo, el búffer -pasó de ser un intermediario, a un lugar de almacenamiento temporal, donde -se -realiza el trabajo. Esta transformación se parace bastante a la de -un pequeño puerto que se convierte en una gran ciudad: -una vez fué el lugar donde la carga era depositada temporalmente -antes de ser cargada en los barcos; despues se convirtio en un centro -comercial -y cultural por derecho propio. -</p> -<p>No todos los búffers están asociados con ficheros. Por ejemplo, el -búffer ‘<tt>*scratch*</tt>’ no visita ningun fichero. Del mismo modo, un -búffer -‘<tt>*Help*</tt>’ no está asociado a ningun fichero. -</p> -<p>Antaño, cuando se carecia de un fichero ‘<tt>~/.emacs</tt>’ -y se iniciava una sesión Emacs escribiendo unicamente el comando -<code>emacs</code>, -sin nombrar ningun fichero, Emacs iniciaba con el búffer -‘<tt>*scratch*</tt>’ visible. Hoy en día, vera una -pantalla de vienvenida. Se puede seguir uno de los comandos sugeridos en -dicha pantalla, visitar un fichero, o presionar la barra espaciadora -para llegar al búffer ‘<tt>*scratch*</tt>’. -</p> -<p>Si cambia al búffer ‘<tt>*scratch*</tt>’, escriba -<code>(buffer-name)</code>, coloque el cursor al final de la expresión, y -presione -<kbd>C-x C-e</kbd> para evaluar la expresión. El nombre -<code>*scratch*</code> será devuelto y aparecerá en el área -echo. <code>*scratch*</code> es el nombre del búffer. Al escribir y evalúar -<code>(buffer-file-name)</code> en el búffer ‘<tt>*scratch*</tt>’, -<code>nil</code> aparecerá en el área echo, igual que cuando -evalúa <code>(buffer-file-name)</code> en Info. -</p> -<p>Por cierto, si se encuentra en el búffer ‘<tt>*scratch*</tt>’ y -quiere que el valor devuelto por una expresión aparesca en el -búffer en sí y no en el área echo, presione <kbd>C-u C-x -C-e</kbd> en lugar de <kbd>C-x C-e</kbd>. Esto causa que el valor devuelto -aparezca después de la expresión. El búffer se verá -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(buffer-name)"*scratch*" -</pre></div> - -<p>No se puede hacer esto en Info ya que Info es de solo lectura y no -se permitirá cambiar el contenido del búffer. Pero puedes -hacer esto en cualquier búffer que se puede editar; y cuando se escribe -código o documentación (como este libro), esta funcionalidad -es muy útil. -</p> -<hr> -<a name="Obteniendo-b_00faffers"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Nombres-de-b_00faffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Cambiando-b_00faffers" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Obteniendo-buffers"></a> -<h2 class="section">2.2 Obteniendo búffers</h2> -<a name="index-current_002dbuffer"></a> -<a name="index-other_002dbuffer"></a> -<a name="index-Teniendo-un-buffer"></a> - -<p>La función <code>buffer-name</code> devuelve el <em>nombre</em> del búffer; -para obtener el búffer <em>en sí</em>, una función -diferente es necesaria: la función <code>current-buffer</code>. Si usa -esta función en el código, lo que se obtiene es el búffer en -sí. -</p> -<p>Un nombre y el objeto o entidad a la que se refiere el nombre son -cosas diferentes entre si. Tu no eres tu nombre, eres una persona a la que -se -refieren los demas por tu nombre. Si pides hablar con Jorge -y alguien te entrega una tarjeta con las letras ‘<samp>J</samp>’, ‘<samp>o</samp>’, -‘<samp>r</samp>’, ‘<samp>g</samp>’, y ‘<samp>e</samp>’ escritas, podrías divertirte, -pero no estarías satisfecho. No quieres -hablar con el nombre, sino con la persona a la que el -nombre se refiere. Un búffer es similar: el nombre del búffer -scratch es ‘<tt>*scratch*</tt>’, pero el nombre no es el búffer. Para -obtener un búffer en sí, se necesita usar una -función como <code>current-buffer</code>. -</p> -<p>Sin embargo, hay una ligera complicación: si evalúas -<code>current-buffer</code> en una expresión por sí sola, -como haremos aquí, lo que ves es una representación -impresa del nombre del búffer sin los contenidos del búffer. Emacs -funciona de esta forma por dos razones: el búffer puede contener -miles de líneas—demasiado largo para ser -mostrado convenientemente; y, otro búffer puede tener los mismos -contenidos pero un nombre diferente, y es importante distinguir entre ellos. -</p> -<p>Aquí hay una expresión conteniendo la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(current-buffer) -</pre></div> - -<p>Si evalúa esta expresión en Info de la manera habitual, -‘<tt>#<buffer *info*></tt>’ aparecerá en el área echo. El formato -especial indica que el búffer en sí está -siendo devuelto, en lugar de solo su nombre. -</p> -<p>Por cierto, si bien puedes escribir un número o símbolo -en un programa, no se puede hacer esto con la representación impresa -del búffer: la única manera de obtener un búffer -en sí mismo es con una función tal como -<code>current-buffer</code>. -</p> -<p>Un función relacionada es <code>other-buffer</code>. Esta devuelve el -último buffer seleccionado distino al que te encuentras -actualmente, no una representación impresa de su -nombre. Si recientemente has ido y vuelto del búffer ‘<tt>*scratch*</tt>’, -<code>other-buffer</code> devolverá este búffer. -</p> -<p>Se puede ver esto evaluando la expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(other-buffer) -</pre></div> - -<p>Verás que ‘<tt>#<buffer *scratch*></tt>’ aparece en el área echo, o el -nombre de cualquier otro búffer cambiado anteriormente a partir del más -reciente<a name="DOCF5" href="#FOOT5">(5)</a> -</p> -<hr> -<a name="Cambiando-b_00faffers"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Obteniendo-b_00faffers" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Tama_00f1o-de-b_00faffer-y-localizaciones" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Cambiando-buffers"></a> -<h2 class="section">2.3 Cambiando búffers</h2> -<a name="index-switch_002dto_002dbuffer"></a> -<a name="index-set_002dbuffer"></a> -<a name="index-Cambiando-a-un-buffer"></a> - -<p>La función <code>other-buffer</code> realmente proporciona un búffer -cuando se utiliza como argumento de una función que requiera -uno. Podemos ver esto usando <code>other-buffer</code> y -<code>switch-to-buffer</code> para cambiar a un búffer diferente. -</p> -<p>Pero primero, una breve introducción a la función -<code>switch-to-buffer</code>. Cuando cambia de ida y vuelta de -Info al búffer ‘<tt>*scratch*</tt>’ para evaluar <code>(buffer-name)</code>, -normalmente se -presiona <kbd>C-x b</kbd> y se pasa ‘<tt>*scratch*</tt>’<a name="DOCF6" href="#FOOT6">(6)</a> en el minibuffer cuando se le solicita el nombre -del búffer al que se quiere cambiar. El atajo, <kbd>C-x -b</kbd>, hace que el intérprete Lisp evalúe la función interactiva -<code>switch-to-buffer</code>. Como hemos dicho anteriormente, -así es como funciona Emacs: diferentes atajos de teclado -llaman o ejecutan diferentes funciones. Por ejemplo, <kbd>C-f</kbd> llama a -<code>forward-char</code>, <kbd>M-e</kbd> llama a <code>forward-sentence</code>, -etc’etera. -</p> -<p>Escribiendo <code>switch-to-buffer</code> en una expresión, y dándole un -búffer para cambiar, se puede cambiar de búffers tal y como hace -<kbd>C-x b</kbd>. -</p> -<div class="smallexample"> -<pre class="smallexample">(switch-to-buffer (other-buffer)) -</pre></div> - -<p>El símbolo <code>switch-to-buffer</code> es el primer elemento -de la lista, por lo que el intérprete Lisp lo tratará como -una función y llevara a cavo las instrucciones adjuntas al mismo. Pero -antes de -hacer esto, el intérprete observara que <code>other-buffer</code> está -dentro de paréntesis y trabaja en este símbolo -primero. <code>other-buffer</code> es el primer (y en este caso, el -único) elemento de esta lista, por lo que el intérprete -Lisp llama o ejecuta la función. Esto devuelve un buffer distinto al -actual. A continuación, el intérprete ejecuta <code>switch-to-buffer</code>, -pasando, como argumento, el búffer devuelto, que es al que Emacs -cambia. Si estás leyendo esto en Info, prueba esto ahora. Evalúa -la expresión. (Para volver, presiona <kbd>C-x b -<RET></kbd>.)<a name="DOCF7" href="#FOOT7">(7)</a>. -</p> -<p>En los ejemplos de las secciones siguentes, veras con más frecuencia la -función <code>set-buffer</code> que <code>switch-to-buffer</code>. Esto es porque a -diferencia -de los programas de ordenador: los humanos tienen ojos y -esperan ver el búffer en el que están trabajando en la -terminal de su ordenador. Esto es tan obvio, que casi no hace falta -decirlo. Sin embargo, los programas no tienen ojos. Cuando un -programa de ordenador trabaja en un búffer, el búffer no -necesita ser visible en la pantalla. -</p> -<p><code>switch-to-buffer</code> está diseñado para los seres humanos y hace dos -cosas diferentes: cambia el búffer a el que Emacs dirige la atención; -y cambia el búffer mostrada en la ventana al -nuevo búffer. <code>set-buffer</code>, por otro lado, solo hace una cosa: -cambia la atención del programa del ordenador a un búffer diferente. El -búffer en la pantalla permanece sin cambios (por supuesto, normalmente -no ocurre nada hasta que el comando termina de ejecutarse). -</p> -<a name="index-llamada-definida"></a> -<p>También, acabamos introduciendo otro término tecnico, la -palabra <em>llamada</em>. Cuando evalúas una lista en la que el -primer símbolo es una función, estás llamando -a esta función. El uso del término viene de la noción de la -función como una entidad que puede hacer algo por ti cuando -la ‘llamas’ — al igual que un fontanero es una entidad que -puede arreglar una fuga si le llamas. -</p> -<hr> -<a name="Tama_00f1o-de-b_00faffer-y-localizaciones"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Cambiando-b_00faffers" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-evaluaci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Tamano-de-buffer-y-la-ubicacion-del-punto"></a> -<h2 class="section">2.4 Tamaño de búffer y la ubicación del punto</h2> -<a name="index-Tamano-del-buffer"></a> -<a name="index-Tamano-del-Buffer"></a> -<a name="index-Localizacion-del-Punto"></a> -<a name="index-Localizacion-del-punto"></a> - -<p>Por último, vamos a ver varias funciones bastante simples, -<code>buffer-size</code>, <code>point</code>, <code>point-min</code>, y -<code>point-max</code>. Estas entregan información sobre el tamaño de un -búffer y la ubicación del punto dentro de este. -</p> -<p>La función <code>buffer-size</code> te dice el tamaño del búffer -actual; es decir, la función devuelve un conteo del número de caracteres -en -el buffer. -</p> -<div class="smallexample"> -<pre class="smallexample">(buffer-size) -</pre></div> - -<p>Puedes evaluar esto de la forma habitual, coloca el cursor -después de la expresión y presiona <kbd>C-x C-e</kbd>. -</p> -<a name="index-definicion-de-punto"></a> -<p>En Emacs, la posición actual del cursor es llamada <em>punto</em>. La -expresión <code>(point)</code> devuelve un número que informa donde está -situado el cursor como un conteo del número de caracteres desde el -principio del búffer hasta el punto. -</p> -<p>Puedes ver el conteo de caracteres del punto para este búffer -evaluando la siguiente expresión de la forma habitual: -</p> -<div class="smallexample"> -<pre class="smallexample">(point) -</pre></div> - -<p>Mientras escribo esto, el valor de <code>point</code> es 65724. La función -<code>point</code> se utiliza con frecuencia en algunos de los ejemplos -mas adelante en este libro. -</p> -<p>El valor del punto depende, por supuesto, de su posición dentro del -búffer. Si se evalúa el punto en este lugar, el número será -mayor: -</p> -<div class="smallexample"> -<pre class="smallexample">(point) -</pre></div> - -<p>Para mí, el valor del punto en esta posición es 66043, -lo que significa que hay 319 caracteres (incluyendo espacios) entre -las dos expresiones. (Sin duda, se verán diferentes números, puesto -que se ha editado esto desde que se evaluó (point).) -</p> -<a name="index-narrowing-definido"></a> -<p>La función <code>point-min</code> es similar a <code>point</code>, pero -devuelve el valor mínimo permisible del punto en el -búffer actual. Este es el número 1 a menos que <em>narrowing</em> -esté en efecto. (Narrowing, <em>Encogiendo</em> es un mecanismo mediante el -cual -puedes restringirte a ti mismo, o un programa, a operar -solo en un parte de un búffer. <a href="#Encogiendo-y-extendiendo">Encogiendo y extendiendo</a>.) -Del mismo modo, la función <code>point-max</code> devuelve el valor del -valor máximo permisible del punto en el búffer actual. -</p> -<hr> -<a name="Ejercicio-de-evaluaci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Tama_00f1o-de-b_00faffer-y-localizaciones" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio"></a> -<h2 class="section">2.5 Ejercicio</h2> - -<p>Busca un fichero en el que trabajar y avanza hasta la -mitad. Encuentra el nombre de búffer, el nombre del fichero, -su tamaño, y la posición en el fichero. -</p> -<hr> -<a name="Escribiendo-funciones"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Practicando-evaluaci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-evaluaci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Funciones-primitivas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Como-escribir-definiciones-de-funciones"></a> -<h1 class="chapter">3 Cómo escribir definiciones de funciones</h1> -<a name="index-Escribiendo-la-Definicion"></a> -<a name="index-Escribiendo-la-Definicion-de-Funcion"></a> -<a name="index-Escribiendo-una-definicion-funcion"></a> - -<p>Cuando el intérprete evalúa una lista, mira si el primer -símbolo en la lista tiene una definición adjunta; o, dicho -de otro -modo, si el símbolo apunta a una definición de -función. Si lo hace, el ordenador lleva a cabo las instrucciones que -aparecen en la -definición. Un símbolo que tiene una definición de -función se llamada, simplemente, una función (aunque hablando con -propiedad, la definición es la función y el símbolo -se refiere a ella.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Funciones-primitivas">Una vía acerca de funciones primitivas</a></td><td> </td><td align="left" valign="top"> Funciones primitivas -</td></tr> -<tr><td align="left" valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Instalar">3.2 Instalar una definición de función</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Interactive">3.3 Crear una función interactive</a></td><td> </td><td align="left" valign="top"> Creando una función interactive. -</td></tr> -<tr><td align="left" valign="top"><a href="#Opciones-de-interactive_002e">3.4 Diferentes opciones para <code>interactive</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Instalaci_00f3n-Permanente">3.5 Instalar código permanentemente</a></td><td> </td><td align="left" valign="top"> Instalando código permanentemente. -</td></tr> -<tr><td align="left" valign="top"><a href="#let">3.6 <code>let</code></a></td><td> </td><td align="left" valign="top"> Creando e inicializando variables locales. -</td></tr> -<tr><td align="left" valign="top"><a href="#if">3.7 La forma especial <code>if</code></a></td><td> </td><td align="left" valign="top"> ¿Y qué si? -</td></tr> -<tr><td align="left" valign="top"><a href="#else">3.8 Expresiones if–then–else</a></td><td> </td><td align="left" valign="top"> Expresiones If–then–else. -</td></tr> -<tr><td align="left" valign="top"><a href="#Verdad-y-falsedad">3.9 Verdad y falsedad en Emacs Lisp</a></td><td> </td><td align="left" valign="top"> Que considera Lisp falso y cierto. -</td></tr> -<tr><td align="left" valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td><td> </td><td align="left" valign="top"> Guardando la traza del punto, la marca, y el - buffer. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisar">3.11 Revisar</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-defun">3.12 Ejercicios</a></td><td> </td><td align="left" valign="top"> Ejercicios defun -</td></tr> -</table> - -<hr> -<a name="Funciones-primitivas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#defun" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-via-acerca-de-funciones-primitivas"></a> -<h2 class="unnumberedsec">Una vía acerca de funciones primitivas</h2> -<a name="index-Funciones-primitivas"></a> -<a name="index-Funciones_002c-primitiva"></a> - -<a name="index-Primitivas-en-lenguaje-C"></a> -<a name="index-Primitivas-escritas-en-C"></a> -<p>Todas las funciones se definen en términos de otras -funciones, a excepcion de algunas <em>primitivas</em> que estan -escritas en el lenguaje de programación C. Cuando escribas -definiciones de funciones, deben escribirse en Emacs Lisp y utilizar otras -funciones como bloques de construcción. Algunas de las funciones -a utilizar estaran a su vez escritas en Emacs Lisp -(quizás por tí) y algunas serán primitivas escritas -en C. Las funciones primitivas se usan exactamente igual que las escritas en -Emacs Lisp y se -comportan de igual forma. Están escritas en C para que podamos ejecutar -fácilmente -GNU Emacs en cualquier ordenador -que tenga la potencia suficiente y pueda ejecutar C. -</p> -<p>Permíteme volver a enfatizar esto: cuando se escribe código -en -Emacs Lisp, no se distinge entre el uso de funciones escritas en C y el -uso de funciones escritas en Emacs Lisp. La diferencia es -irrevelante. Menciononé la distinción solo porque es interesante -conocerla. De hecho, a menos de que investigues, no sabras si una -función previamente escrita esta en Emacs Lisp o en C. -</p> -<hr> -<a name="defun"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Funciones-primitivas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Instalar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-forma-especial-defun"></a> -<h2 class="section">3.1 La forma especial <code>defun</code></h2> -<a name="index-defun"></a> -<a name="index-Forma-Especial-de-defun"></a> - -<a name="index-definicion-funcion-definida"></a> -<p>En Lisp, un símbolo como <code>mark-whole-buffer</code> -tiene código unido a el que le dice al ordenador que hacer cuando se -invoca la -función. Este código se denomina la <em>definición de -función</em> y se crea mediante la evaluación de una expresión Lisp que -comienza con -el símbolo <code>defun</code> (que es una abreviatura para -<em>define function</em> (definir función)). Porque <code>defun</code> no evalúa -sus -argumentos en la forma habitual, eso se llama <em>forma especial</em>. -</p> -<p>En las siguientes secciones, miraremos en definiciones de función -partiendo del código fuente de Emacs, por ejemplo -<code>mark-whole-buffer</code>. En esta sección, describiremos una -definición de función sencilla, para que puedas ver su -aspecto. Esta definición de función usa aritmética porque es un -ejemplo simple. A algunas personas les disgutan los ejemplos usando -aritmética; sin embargo, si usted es tal persona, no se desespere. Casi -ningun código a estudiar en el resto de esta -introducción implica aritmética o matemáticas. Los -ejemplos de manera mayoritaria involucran texto en una forma u otra. -</p> -<p>Una definición de función tiene un máximo de cinco partes despues de -la palabra <code>defun</code>: -</p> -<ol> -<li> -El nombre del símbolo al que la definición de -función debe vincularse. - -</li><li> -Una lista de los argumentos que serán pasados a la función. Si no -hay argumentos que pasar, tendremos una lista vacía, -<code>()</code>. - -</li><li> -Documentación describiendo la función. (Técnicamente opcional, -pero fuertemente recomendada.) - -</li><li> -Opcionalmente, una expresión para hacer que la función interactive -pueda usarse presionando <kbd>M-x</kbd> seguido del -nombre de la función; o pulsando una tecla o atajo de teclado. - -<a name="index-cuerpo-definido"></a> -</li><li> -El código que indica a el ordenador qué hacer: el <em>cuerpo</em> de -la definición de función. -</li></ol> - -<p>Es útil pensar en las cinco partes de una definición de función -siendo organizadas como una plantilla, con slots para cada parte: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun <var>nombre-de-función</var> (<var>argumentos</var>…) - "<var>documentacion-opcional</var>…" - (interactive <var>argument-passing-info</var>) ; <span class="roman">opcional</span> - <var>cuerpo</var>…) -</pre></div> - -<p>A modo de ejemplo, aquí está el código de una -función que multiplica su argumento por 7. (Este ejemplo no es -interactivo. Ver <a href="#Interactive">Creando una Función Interactive</a>, -para esta información.) -</p> -<div class="smallexample"> -<pre class="smallexample">(defun multiplicar-por-siete (numero) - "Multiplica NUMERO por siete." - (* 7 numero)) -</pre></div> - -<p>Esta definición comienza con un paréntesis y el -símbolo <code>defun</code> seguido por el nombre de la -función. -</p> -<a name="index-lista-de-argumentos-definida"></a> -<p>El nombre de la función es seguido por una lista que contiene -los argumentos que serán pasados a la función. Esta lista se -llama <em>lista de argumentos</em>. En este ejemplo, la lista -solo tiene un elemento, el símbolo <code>numero</code>. Cuando -se utiliza la función, el símbolo será asociado al -valor que se utiliza como argumento de la función -</p> -<p>En lugar de elegir la palabra <code>numero</code> para el nombre del -argumento, podría haber escogido cualquier otro -nombre. Por ejemplo, la palabra -<code>multiplicando</code>. Escogi la palabra ‘numero’ porque indica -qué tipo de valor se pretende para este espacio; pero -podría haber elegido ‘multiplicando’ para indicar el rol -que jugara el valor en el funcionamiento de la -función. Podría haberlo llamado <code>foogle</code>, pero -habría sido una mala elección porque no -comunicaria qué significa. La elección del nombre es -responsabilidad del programador y debe elegirse para hacer que el -significado de la función sea claro. -</p> -<p>De hecho, se puede elegir cualquier nombre que se desee para un -símbolo en una lista de argumentos, incluso el nombre -del símbolo usado en alguna otra función: el nombre a -usar en una lista de argumentos es privado para esta definición -particular. En esta definición, el nombre hace referencia a una entidad -diferente a cualquiera que utilice el mismo nombre fuera de la -definición de función. Supón que tu familia te apoda ‘Enano’; -cuando tus familiares digan ‘Enano’, -queren hacer referencia a ti. Pero fuera de tu familia, en una -película, por ejemplo, el nombre ‘Enano’ se refiere a -alguien más. Debido a que el nombre en una lista de argumentos es privado -para la definición de la función, se puede cambiar el valor de un -símbolo dentro del cuerpo de una función sin cambiar -su valor fuera de la función. El efecto es similar al producido -por la expresión <code>let</code>. (Ver sección <a href="#let"><code>let</code></a>.) -</p> - -<p>La lista de argumentos es seguida por la cadena de documentación que -describe la función. Esto es lo que ves cuando presionas -<kbd><span class="nolinebreak">C-h</span> f</kbd> y escribes el nombre de una función. Por cierto, cuando -escribas una cadena de documentación como esta, debes confeccionar la -primer línea como una sentencia completa ya que algunos -comandos, -como <code>apropos</code>, imprimen solo la primer línea -de una cadena de documentación de varias líneas. Ademas, no -debes indentar la segunda línea de la -cadena de documentación, si tienes una, porque se ve extraño al utilizar -<kbd>C-h f</kbd> -(<code>describe-function</code>). La cadena de documentación es opcional, pero -es -tan útil, que deberías incluirla en casi cualquier -función que escribas. -</p> -<a name="index-_002a-_0028multiplicacion_0029"></a> -<p>La tercera línea del ejemplo consiste en el cuerpo de la -definición de función. (La mayoría de las -definiciones de función, claro esta, son más extensas que esta.) En -esta función, el cuerpo es la lista, <code>(* 7 numero)</code>, que indica -multiplicar el valor de <var>numero</var> por 7. (En Emacs Lisp, <code>*</code> -es la función para la multiplicación, al igual que <code>+</code> es la -función de la adición. -</p> -<p>Cuando se utiliza la función <code>multiplicar-por-siente</code>, el argumento -<code>numero</code> se evalúa al numero que desees -usar. He aquí un ejemplo que muestra como -utilizar <code>multiplicar-por-siente</code>; pero ¡no intentes -evaluar esto primero!. -</p> -<div class="smallexample"> -<pre class="smallexample">(multiplicar-por-siente 3) -</pre></div> - -<p>El símbolo <code>numero</code>, especificado en la -definición de función en la siguiente sección, se da o -“une a” el valor 3 en el actual uso de la función. Note que -aunque <code>numero</code> estaba dentro de paréntesis en la -definición de función, el argumento pasado a la función -<code>multiplicar-por-siente</code> no está entre paréntesis. Los -paréntesis se escriben en la definición de función -para que el ordenador pueda averiguar donde termina la lista de -argumentos e inicia el resto de la definición de función. -</p> -<p>Si evalúas este ejemplo, es probable que obtengas un mensaje de -error. (¡adelante, intentalo!) Esto se debe a que hemos -escrito la definición de función pero aún no se a comunicado -al ordenador la definición — no hemos -instalado (o ‘cargado’) la definición de función en -Emacs. Instalar una función es el proceso comunicar al -intérprete Lisp la definición de la función. La instalación se -describe en la siguiente sección. -</p> -<hr> -<a name="Instalar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#defun" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Efecto-de-instalaci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Instalar-una-definicion-de-funcion"></a> -<h2 class="section">3.2 Instalar una definición de función</h2> -<a name="index-Instalar-una-definicion-de-funcion"></a> -<a name="index-Definicion-de-la-instalacion"></a> -<a name="index-Definicion-de-la-Instalacion-de-Funcion"></a> - -<p>Si estás leyendo esto dentro de Info en Emacs, puedes probar la -función <code>multiply-by-seven</code> evaluando en primer ]ugar la definición -de función y luego evaluar <code>(multiplicar-por-siente 3)</code>. Hay una -copia de la definición a continuación. Coloca el cursor después del -último paréntesis de la definición de función y presiona -<kbd>C-x C-e</kbd>. Al hacer esto, <code>multiplicar-por-siente</code> -aparecerá en el área echo. (Lo que significa es que cuando una -definición de función se evalua, el valor devuelto es el nombre -de la función definida.) Al mismo tiempo, esta acción instala la -definición de función. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun multiplicar-por-siete (numero) - "Multiplica NUMERO por siete." - (* 7 numero)) -</pre></div> - -<p>Al evaluar este <code>defun</code>, estas instanlado <code>multiply-by-seven</code> -en Emacs. La función es ahora solo una parte de Emacs como -<code>forward-word</code> o cualquier otra función de edición que -utilices. (<code>multiplicar-por-siente</code> seguira instalado hasta que salgas -de -Emacs. Para volver a cargar el código automáticamente cada vez que -Emacs inicie, ver <a href="#Instalaci_00f3n-Permanente">Instalar Código Permanentemente</a>.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Efecto-de-instalaci_00f3n">El efecto de instalación</a></td><td> </td><td align="left" valign="top"> Efecto de instalación -</td></tr> -<tr><td align="left" valign="top"><a href="#Cambiar-un-defun">3.2.1 Cambiar una definición de función</a></td><td> </td><td align="left" valign="top"> Cómo cambiar una definición de función -</td></tr> -</table> - -<hr> -<a name="Efecto-de-instalaci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Instalar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Instalar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Cambiar-un-defun" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-efecto-de-instalacion"></a> -<h3 class="unnumberedsubsec">El efecto de instalación</h3> - -<p>Puedes ver el efecto de instalar <code>multiplicar-por-siente</code> evaluando -el siguiente ejemplo. Coloca el cursor después de la siguiente -expresión y presiona <kbd>C-x C-e</kbd>. El número 21 aparacerá en el -área echo. -</p> -<div class="smallexample"> -<pre class="smallexample">(multiplicar-por-siente 3) -</pre></div> - -<p>Si lo deseas, puedes leer la documentación de la función -presiona <kbd>C-h f</kbd> (<code>describe-function</code>) y luego escribe el -nombre de la función, <code>multiplicar-por-siente</code>. Al hacer esto, -una ventana ‘<tt>*Help*</tt>’ aparecerá en tu pantalla diciendo: -</p> -<div class="smallexample"> -<pre class="smallexample">multiplicar-por-siente is a Lisp function. -(multiplicar-por-siente NUMERO) - -Multiplica NUMERO por siete. -</pre></div> - -<p>(Para volver a una sola ventana en la pantalla, presiona <kbd>C-x 1</kbd>.) -</p> -<hr> -<a name="Cambiar-un-defun"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Efecto-de-instalaci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Instalar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Interactive" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Cambiar-una-definicion-de-funcion"></a> -<h3 class="subsection">3.2.1 Cambiar una definición de función</h3> -<a name="index-Cambiando-una-definicion-de-funcion"></a> -<a name="index-Definicion-de-Funcion_002c-como-cambiar"></a> -<a name="index-Definicion_002c-como-cambiar"></a> - -<p>Si deseas modificar al código de <code>multiplicar-por-siente</code>, -simplemente -reescríbelo. Para instalar la nueva versión en lugar -de la vieja, evalúa la nueva definición de la función. -Esta, es la forma de modificar el código en -Emacs. Es muy simple, -</p> -<p>A modo de ejemplo, puedes cambiar la función <code>multiplicar-por-siente</code> -para sumar el número a sí mismo siete veces en lugar de -multiplicar el número por siete. Esto produce el mismo resultado, -pero por una ruta diferente. Al mismo tiempo, añadiremos un -comentario al codigo; un comentario es texto que el intérprete Lisp -ignora, -pero un lector humano puede encontrar útil o esclarecedor. El -comentario es que esto es la “segunda versión”. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun multiplicar-por-siente (numero) ; <span class="roman">Segunda versión.</span> - "Multiplica NUMERO por siete." - (+ numero numero numero numero numero numero numero)) -</pre></div> - -<a name="index-Comentarios-en-Codigo-Lisp"></a> -<p>El comentario sigue a un punto y coma, ‘<samp>;</samp>’. En Lisp culquier cosa -en una línea despues de un punto y coma es un -comentario. El fin de la línea es el fin del -comentario. Para extender un comentario por dos o más -líneas, inicia cada línea con un punto y -coma. -</p> -<p>@xref{Beginning a .emacs File, , Empezando un Fichero -@file{.emacs}}, y <a href="elisp.html#Comments">Comentarios</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, para más informacion sobre los comentarios. -</p> -<p>Se puede instalar esta versión de la función -<code>multiply-by-seven</code> evaluando esta de la misma forma en que se -evaluó la primer función: coloca el cursor después del -último paréntesis y presiona <kbd>C-x C-e</kbd>. -</p> -<p>En resumen, esta es la forma en que puedes escribir código en Emacs Lisp: -escribes una función; la instalas; la pruebas; luego haces -correciones y mejoras e instálalas de nuevo. -</p> -<hr> -<a name="Interactive"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Cambiar-un-defun" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#multiply_002dby_002dseven-interactivo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Crear-una-funcion-interactive"></a> -<h2 class="section">3.3 Crear una función interactive</h2> -<a name="index-Funciones-Interactivas"></a> -<a name="index-interactive"></a> - -<p>Haces a una función interactiva colocando una lista que inicia con -la clase especial <code>interactive</code> inmediatamente después de la -documentación. Un usuario puede invocar una función interactiva -con <kbd>M-x</kbd> seguido del nombre de la función; o -con un atajo de teclado ligado a esta, por ejemplo, -pulsa <kbd>C-n</kbd> para <code>next-line</code> o <kbd>C-x h</kbd> para -<code>mark-whole-buffer</code>. -</p> -<p>Curiosamente, cuando se llama a una función interactiva -interactivamente, el valor devuelto no se muestra automáticamente -en el área echo. Esto se bede a que a menudo se llama a -una función interactiva para sus efectos secundarios, tales como -avanzar hacia adelante por palabra o línea, y no -para el valor devuelto. Si el valor devuelto fuera mostrado en el -área echo cada vez que presionas una tecla, -distraería mucho -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#multiply_002dby_002dseven-interactivo">Un <code>multiply-by-seven</code> interactivo, Un resumen</a></td><td> </td><td align="left" valign="top"> Un resumen -</td></tr> -<tr><td align="left" valign="top"><a href="#multiply_002dby_002dseven-en-detalle">3.3.1 <code>multiplicar-por-siente</code> interactivo</a></td><td> </td><td align="left" valign="top"> La versión interactive. -</td></tr> -</table> - -<hr> -<a name="multiply_002dby_002dseven-interactivo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Interactive" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Interactive" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#multiply_002dby_002dseven-en-detalle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-multiply_002dby_002dseven-interactivo_002c-Un-resumen"></a> -<h3 class="unnumberedsubsec">Un <code>multiply-by-seven</code> interactivo, Un resumen</h3> - -<p>Tanto el uso de la forma especial <code>interactive</code> y una forma de -mostrar un valor en el área echo pueden ilustrarse creando una -versión interactiva de <code>multiplicar-por-siente</code>. -</p> -<p>Aquí está el código: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun multiplicar-por-siente (numero) ; <span class="roman">Versión Interactiva.</span> - "Multiplica NUMERO por siete." - (interactive "p") - (message "El resultado es %d" (* 7 numero))) -</pre></div> - -<p>Para instalar este código colaca el cursor después del ultimo parentesis -y -presiona <kbd>C-x C-e</kbd>. El nombre de la función aparecerá en el -área echo. Despues, puedes utilizar este código al presionar -<kbd>C-u</kbd> seguido de un número, lugo <kbd>M-x -multiplicar-por-siente</kbd> y finalmente <RET>. La frase ‘<samp>El -resultado es …</samp>’ seguida por el producto aparecerá en el área -echo -</p> -<p>Hablando en terminos mas generales, puedes invocar una función como -ésta de dos maneras: -</p> -<ol> -<li> -Al escribir un argumento prefijo que contiene el número a pasar, y -a continuación presionar <kbd>M-x</kbd> y escribir el nombre de la función, -como ocurre con -<kbd>C-u 3 M-x forward-sentence</kbd>; o, - -</li><li> -Al escribir cualquier tecla o atajo de teclado ligado a la funcion a tratar, -como ocurre con <kbd>C-u 3 M-e</kbd>. -</li></ol> - -<p>Ambos ejemplos operan de forma identica moviendo el punto -hacia adelantes tres frases. (Si <code>multiply-by-seven</code> no -estuviese ligado a una tecla, no podría ser usado -como ejemplo de enlace a tecla. -</p> -<p>(Véase la sección <a href="#Atajos-de-teclado">Algunos Atajos de Teclas</a>, para aprender -como vincular un comando a una tecla.) -</p> -<p>Un argumento prefijo se pasa a una función interactiva -pulsando la tecla <META> seguida por un número, por ejemplo, -<kbd>M-3 M-e</kbd>, o con <kbd>C-u</kbd> y luego un número, por -ejemplo, <kbd>C-u 3 M-e</kbd> (si presionas <kbd>C-u</kbd> sin ningun número, el -valor por -defecto es 4). -</p> -<hr> -<a name="multiply_002dby_002dseven-en-detalle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#multiply_002dby_002dseven-interactivo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Interactive" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Opciones-de-interactive_002e" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="multiplicar_002dpor_002dsiente-interactivo"></a> -<h3 class="subsection">3.3.1 <code>multiplicar-por-siente</code> interactivo</h3> - -<p>Veamos la clase especial <code>interactive</code> y -despues la función <code>message</code> en la versión interactiva de -<code>multiplicar-por-siente</code>. Recordaras que la definición de -función tiene el siguente aspecto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun multiplicar-por-siente (numero) ; <span class="roman">Versión Interactiva.</span> - "Multiplica NUMERO por siete." - (interactive "p") - (message "El resultado es %d" (* 7 numero))) -</pre></div> - -<p>En esta función, la expresión, <code>(interactive "p")</code>, es una -lista de dos elementos. La <code>"p"</code> le indica a Emacs que debe pasar el -argumento prefijo a la función y utilizar este valor para el argumento de -la función. -</p> -<p>El argumento debe ser un número. Esto significa que el -símbolo <code>numero</code> estara asociado a un -número en la línea: -</p> -<div class="smallexample"> -<pre class="smallexample">(message "El resultado es %d" (* 7 numero)) -</pre></div> - -<p>Por ejemplo, si tu argumento prefijo es 5, el intérprete Lisp -evaluará la línea como si fuera: -</p> -<div class="smallexample"> -<pre class="smallexample">(message "El resultado es %d" (* 7 5)) -</pre></div> - -<p>(Si estás leyendo esto en GNU Emacs, puedes evaluar esta -expresión por ti mismo.) Primera, el intérprete -evaluará la lista interna, que es <code>(* 7 5)</code>. Esto devuelve un -valor de 35. A continuación, se evaluará la lista externa, pasando los -valores del segundo y posteriores elementos de la lista a la -función <code>message</code>. -</p> -<p>Como hemos visto, <code>message</code> es una función Emacs Lisp -especialmente diseñada para enviar un -mensaje de una línea al usuario. (Véase la sección <a href="#message">La función <code>message</code></a>) -En resumen, la función <code>message</code> imprime su primer argumento en -el área echo tal cual, exceptuando las apariciones de ‘<samp>%d</samp>’, o -‘<samp>%s</samp>’ (y varias otras secuencias de control que no hemos -mencionado). Cuando aparece una secuencia de control, la función observa -al segundo o posteriores argumentos e imprime el valor del argumento -en la ubicación donde se encuentra la secuencia de control. -</p> -<p>En la función interactiva <code>multiplicar-por-siente</code>, la cadena de -control es ‘<samp>%d</samp>’, que requiere un número, y el valor devuelto -por la evaluación de <code>(* 7 5)</code> es el número 35. Por consiguiente, -el -número 35 se imprime en lugar de ‘<samp>%d</samp>’ y el mensaje es ‘<samp>El -resultado es 35</samp>’. -</p> -<p>(Nótese que cuando llamas a la función <code>multiplicar-por-siente</code>, -el mensaje se imprime sin comillas, pero cuando llamas a -<code>message</code>, el texto se impreme entre comillas. Esto se debe -a que el valor devuelto por <code>message</code> aparece en el área echo -cuando evalúas una expresión cuyo primer elemento es -<code>message</code>; pero si se integra en una función, -<code>message</code> imprime el texto como un efecto secundario sin comillas.) -</p> -<hr> -<a name="Opciones-de-interactive_002e"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#multiply_002dby_002dseven-en-detalle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Instalaci_00f3n-Permanente" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Diferentes-opciones-para-interactive"></a> -<h2 class="section">3.4 Diferentes opciones para <code>interactive</code></h2> -<a name="index-Opciones-para-interactive"></a> -<a name="index-Opciones-Interactive"></a> - -<p>En el ejemplo, <code>multiplicar-por-siente</code> usa <code>"p"</code> como el -argumento para <code>interactive</code>. Este argumento indica a Emacs que -interprete cualquier cosa que escriba despues de <kbd>C-u</kbd> o -del comando <META> como un número que sera el argumento a pasar -a la función. Emacs tiene más de veinte -caracteres predefinidos para usar con <code>interactive</code>. En casi todos los -casos, una de estas opciones te permitira pasar la -información adecuada interactivamente a una -función. (See <a href="elisp.html#Interactive-Codes">Carácteres Código para <code>interactive</code></a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>). -</p> -<p>Considera la función <code>zap-to-char</code>. Su expresión interactiva es -</p> -<div class="smallexample"> -<pre class="smallexample">(interactive "p\ncZap to char: ") -</pre></div> - -<p>La primer parte del argumento de <code>interactive</code> es ‘<samp>p</samp>’, -con el que ya estás familiarizado. Este argumento le indica a Emacs -intepretar un ‘prefijo’, como un número que se pasa a la -función. Puedes especificar un prefijo plesionando <kbd>C-u</kbd> -seguido por un número o igualmente con <META> seguido por un -número. El prefijo es un número de caracteres especifico. De -este modo, si el prefijo es tres y el caracter -establecido es ‘<samp>x</samp>’, entonces se borrará todo el -texto incluido el tercer ‘<samp>x</samp>’ siguiente. Si no se establece un -prefijo, entonces borras todo el texto incluido el cuarto carácter -establecido, pero no más. -</p> -<p>La ‘<samp>c</samp>’ indica a la función el nombre del carácter que va a -eliminar. -</p> -<p>Más formalmente, una función con dos o más argumentos puede -tener información que pasa a cada argumento añadiendo partes en la -cadena viene despues de <code>interactive</code>. Cuando haces esto, la -información se pasa a cada argumento en el mismo orden que se especifica -en la lista <code>interactive</code>. En la cadena, cada -parte está separada de la siguiente parte por un ‘<samp>\n</samp>’, que -significa nueva línea. Por ejemplo, a -‘<samp>p</samp>’ puede continuar un ‘<samp>\n</samp>’ y un ‘<samp>cZap to char:</samp>’. Esto hace -que -Emacs pase el valor del argumento prefijo (si lo hay) y el -carácter. -</p> -<p>En este caso, la definición de función se parace a la siguiente, -donde <code>arg</code> y <code>char</code> son los símbolos que -<code>interactive</code> vincula el argumento prefijo y el caracter especificado: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun <var>nombre-de-funcion</var> (arg char) - "<var>documentacion</var>…" - (interactive "p\ncZap to char: ") - <var>cuerpo-de-funcion</var>…) -</pre></div> - -<p>(El espacio después del punto y coma en pantalla hace que se vea -mejor. Véase la sección <a href="#copy_002dto_002dbuffer">La Definición de <code>copy-to-buffer</code></a>, para un ejemplo.) -</p> -<p>Cuando una función no toma argumentos, <code>interactive</code> no -requiere ninguno. Una función asi contiene unicamente la expresión -<code>(interactive)</code>. La función <code>mark-whole-buffer</code> es asi. -</p> -<p>Alternativamente, si los códigos de letras especiales no son adecuados -para tu -aplicación, puedes pasar tus propios argumentos a -<code>interactive</code> como una lista. -</p> -<p>Véase la sección <a href="#append_002dto_002dbuffer">La Definición de <code>append-to-buffer</code></a>, -para un ejemplo. See <a href="elisp.html#Using-Interactive">Usando <code>interactive</code></a> in <cite>El Manual de GNU Emacs Lisp</cite>, para una -explicación más completa acerca de esta técnica. -</p> -<hr> -<a name="Instalaci_00f3n-Permanente"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Opciones-de-interactive_002e" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#let" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Instalar-codigo-permanentemente"></a> -<h2 class="section">3.5 Instalar código permanentemente</h2> -<a name="index-Instalar-codigo-permanentemente"></a> -<a name="index-Codigo-Permanente-de-Instalacion"></a> -<a name="index-Codigo-de-instalacion"></a> - -<p>Cuando instalas una definición de función evaluada por ti, -permanecera instalada hasta que salgas de Emacs. La -proxima vez que inicies una nueva sesión de Emacs, la -función no será instalada a menos que evalúes de nuevo la -definición. -</p> -<p>En algún punto, podrias necesitar que el código se instale -automáticamente cada vez que inicies una nueva sesión de -Emacs. Hay varias formas de hacer esto: -</p> -<ul> -<li> -Si tienes código solo para tu uso, puedes poner el -código de la definición de función en el fichero de -inicialización ‘<tt>.emacs</tt>’. Cuando se inicia Emacs, el fichero -‘<tt>.emacs</tt>’ se evalúa automática y se instalan todas sus definiciones -de -función. Véase la sección <a href="#Inicializaci_00f3n-de-Emacs">Tu Fichero ‘<tt>.emacs</tt>’</a>. - -</li><li> -Como Alternativa, puedes poner las definiciones de función -en uno o más ficheros y usar la función -<code>load</code> para hacer que Emacs evalue y con ello instale cada una de las -funciones en -los ficheros. Véase la sección <a href="#Cargando-ficheros">Cargando ficheros</a>. - -</li><li> -En tercer lugar, si tienes código que todo tu sitio va a utilizar, es -normal -ponerlo en un fichero llamado ‘<tt>site-init.el</tt>’ que se carga -cuando se construye Emacs. Esto hace que el código este disponible a -cualquiera que use tu máquina. (Mira el fichero ‘<tt>INSTALL</tt>’ que -forma parte de la distribución Emacs.) -</li></ul> - -<p>Finalmente, si tienes código que cualquier usuario de Emacs puede -querer, puedes publicarlo en una red de ordenadores o enviar una copia a -la Free Software Foundation. (Al hacer esto, por favor, licencia -el código y su documentación bajo una licencia que permita a otras -personas ejecutar, copiar, estudiar, modificar, y redistribuir el -código y te proteja de quien tome tu trabajo.) Si envias -una copia de tu código a la Free Software Foundation, y lo proteges -apropiadamente de tí mismo y otros, puede ser -incluido en la siguiente version de Emacs. En gran parte, esta -es la forma como ha crecido Emacs a través de los -años, por donaciones. -</p> -<hr> -<a name="let"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Instalaci_00f3n-Permanente" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Prevenir-confusi_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="let-1"></a> -<h2 class="section">3.6 <code>let</code></h2> -<a name="index-let"></a> - -<p>La expresión <code>let</code> es una forma especial en Lisp que -tendras que utilizar en la mayoría de las -definiciones de función. -</p> -<p><code>let</code> se utiliza para unir o enlazar un símbolo -a un valor de tal manera que el intérprete no confunda la -variable con otra variable del mismo nombre que no forma parte de la -función. -</p> -<p>Para comprender por qué la forma especial <code>let</code> es necesaria, -considera la situación donde eres dueño de una casa que generalmente -vinculas con -‘la casa’, como en la frase, “La casa necesita -pintura.” Si visitas a un amigo y tu anfitrión hace -referencia a ‘la casa’, es probable que se refiera a -<em>su</em> casa, no a la tuya, es decir, es una casa distinta. -</p> -<p>Si tu amigo se refiere a su casa y tu crees que él se -está refiriéndo a tu casa, puedes tener cierta -confusión. Lo mismo podria ocurrir en Lisp si una -variable que se utiliza dentro de una función tiene el mismo que una -variable usada dentro de otra función, y las dos no tienen la -intención de referirse al mismo valor. La forma especial <code>let</code> -previene este tipo de confusión. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Prevenir-confusi_00f3n"><code>let</code> evita confusiones</a></td><td> </td><td align="left" valign="top"> Prevenir confusión -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-de-la-expresi_00f3n-let">3.6.1 Las partes de una expresión <code>let</code></a></td><td> </td><td align="left" valign="top"> Partes de la expresión let -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-de-expresi_00f3n-let">3.6.2 Ejemplo de Expresión <code>let</code></a></td><td> </td><td align="left" valign="top"> Ejemplo de expresión let -</td></tr> -<tr><td align="left" valign="top"><a href="#Variables-let-inicializadas">3.6.3 Variables sin inicializar en un sentencia <code>let</code></a></td><td> </td><td align="left" valign="top"> Variables let inicializadas -</td></tr> -</table> - -<hr> -<a name="Prevenir-confusi_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#let" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#let" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-de-la-expresi_00f3n-let" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="let-evita-confusiones"></a> -<h3 class="unnumberedsubsec"><code>let</code> evita confusiones</h3> - -<a name="index-variable-local-definida"></a> -<a name="index-variable_002c-local_002c-definida"></a> -<p>La forma especial <code>let</code> evita confusiones. <code>let</code> crea -un nombre para una <em>variable local</em> que eclipsa cualquier uso -del mismo nombre fuera de la expresión <code>let</code>. Esto es como -entender que siempre que tu anfitrión se refiera a ‘la casa’, -significa su casa, no la tuya. (Los símbolos usados en -las listas de argumentos funcionan de la misma manera. Véase la sección <a href="#defun">La Forma Especial <code>defun</code></a>.) -</p> -<p>Las variable locales por una expresión <code>let</code> conservan -su valor <em>solo</em> dentro de la expresión <code>let</code> -misma (y dentro de expresiones llamadas dentro de la expresión -<code>let</code>); las variables locales no tiene efecto fuera de la -expresión <code>let</code>. -</p> -<p>Otra forma de pensar respecto a <code>let</code> es que es como un -<code>setq</code> que es temporal y local. Los valores establecidos por -<code>let</code> son automáticamente deshechos cuando termina el <code>let</code>. -La configuración solo afecta a las expresiones que se encuentran -dentro de los limites de la expresión <code>let</code>. En jerga -informatica, diríamos “la -union de un simbolo es visible solo en las -funciones llamadas en la forma <code>let</code>; en Emacs Lisp, el alcance -es dinámico, no léxico.” -</p> -<p><code>let</code> puede crear más de una variable a la vez. Ademas, -<code>let</code> da a cada variable que crea un valor inicial, ya sea un valor -especificado por tí, o <code>nil</code>. (En la jerga, eso se -llama ‘unir la variable al valor’.) Después que <code>let</code> ha creado -y unido las variables, ejecuta el código en el cuerpo del -<code>let</code> y devuelve el valor de la última expresión en el -cuerpo, como el valor de toda la expresión <code>let</code>. -(‘Ejecutar’ es un término tecnico que significa evaluar -una lista: proviene del significando de la palabra ‘llevar a la -práctica’ (<cite>Diccionario de Inglés de Oxford</cite>). Dado que -evalúas una expresión para realizar una acción, ‘ejecutar’ ha -evolucionado como un sinónimo para ‘evaluar’.) -</p> -<hr> -<a name="Partes-de-la-expresi_00f3n-let"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Prevenir-confusi_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#let" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-expresi_00f3n-let" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Las-partes-de-una-expresion-let"></a> -<h3 class="subsection">3.6.1 Las partes de una expresión <code>let</code></h3> -<a name="index-expresion-let_002c-partes-de"></a> -<a name="index-Partes-de-la-expresion-let"></a> - -<a name="index-varlist-definida"></a> -<p>Una expresión <code>let</code> es una lista de tres partes. La primer -parte es el símbolo <code>let</code>. La segunda parte es una -lista, denominada <em>varlist</em> (lista de variables), cada uno de cuyos -elementos es un -símbolo por sí mismo o una lista de dos -elementos, el primer elemento es un símbolo. La -tercera parte de la expresión <code>let</code> es el cuerpo del -<code>let</code>. El cuerpo normalmente consiste de una o más listas. -</p> -<p>Una plantilla para una expresión <code>let</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(let <var>varlist</var> <var>body</var>…) -</pre></div> - -<p>Los símbolos en la varlist son las variables que dan -los valores iniciales para la forma especial <code>let</code>. Los -símbolos por sí solos reciven el -valor inicial de <code>nil</code>; y cada símbolo que es el -primer elemento de una lista de dos elementos es unido al valor -que el devuelto cuando el intérprete Lisp evalúa el segundo elemento. -</p> -<p>De este modo, una varlist como: -<code>(thread (needles 3))</code>. En este caso, dentro una expresión -<code>let</code>, Emacs une el símbolo <code>thread</code> a un -valor inicial de <code>nil</code>, y une el símbolo -<code>needles</code> a un valor inicial de 3. -</p> -<p>Cuando escribes una expresión <code>let</code>, lo que haces es poner las -expresiones apropiadas en los huecos de la plantilla de expresión -<code>let</code>. -</p> -<p>Si la varlist está compuesta de listas de 2 elementos, -como suele ser el caso, la plantilla de la expresión -<code>let</code> es la siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((<var>variable</var> <var>valor</var>) - (<var>variable</var> <var>valor</var>) - …) - <var>cuerpo</var>…) -</pre></div> - -<hr> -<a name="Ejemplo-de-expresi_00f3n-let"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-de-la-expresi_00f3n-let" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#let" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Variables-let-inicializadas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejemplo-de-Expresion-let"></a> -<h3 class="subsection">3.6.2 Ejemplo de Expresión <code>let</code></h3> -<a name="index-Ejemplo-de-Expresion-let"></a> -<a name="index-expresion-simple-let"></a> - -<p>La siguiente expresión crea y da valores iniciales a las -dos variables <code>cebra</code> y <code>tigre</code>. El cuerpo de la expresión -<code>let</code> es una lista que llama a la función <code>message</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((cebra 'rayas) - (tigre 'fiero)) - (message "Un tipo de animal tiene %s y otro es %s." - cebra tigre)) -</pre></div> - -<p>Aquí, la varlist es <code>((cebra 'rayas) (tigre -'fiero))</code>. -</p> -<p>Las dos variables son <code>cebra</code> y <code>tigre</code>. Cada variable es el -primer elemento de una lista de dos elementos y cada valor es el -segundo elemento de su lista de dos elementos. En la varlist, Emacs -une la variable <code>cebra</code> al valor <code>rayas</code><a name="DOCF8" href="#FOOT8">(8)</a>, y -une la variable <code>tigre</code> al valor <code>fiero</code>. En este -ejemplo, ambos valores son símbolos precedidos por una -cita. Los valores podrían muy bien haber sido otra -lista o una cadena. El cuerpo de <code>let</code> sigue después de la lista -que contiene las variables. En este ejemplo, el cuerpo es una lista que -usa la función <code>message</code> para imprimir una cadena en el área -echo. -</p> -<p>Puedes evaluar el ejemplo de la forma habitual, coloca el cursor -después del último paréntesis y presiona <kbd>C-x -C-e</kbd>. Al hacer esto, aparecerá lo siguiente en el área echo: -</p> -<div class="smallexample"> -<pre class="smallexample">"Un tipo de animal tiene rayas y otro es fiero." -</pre></div> - -<p>Como hemos visto antes, la función <code>message</code> imprime su primer -argumento, excepto por ‘<samp>%s</samp>’. En este ejemplo, el valor de la -variable <code>cebra</code> se imprime en la posición del primer ‘<samp>%s</samp>’ -y el valor de la variable <code>tigre</code> se imprime en la posición del -segundo ‘<samp>%s</samp>’. -</p> -<hr> -<a name="Variables-let-inicializadas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-expresi_00f3n-let" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#let" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#if" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Variables-sin-inicializar-en-un-sentencia-let"></a> -<h3 class="subsection">3.6.3 Variables sin inicializar en un sentencia <code>let</code></h3> -<a name="index-Variables-let-no-inicializadas"></a> -<a name="index-Variables-let-no-inicializadas-1"></a> - -<p>Si no se une a las variables en una sentencia <code>let</code> con valores -iniciales específicos, automáticamente seran unidos -a un valor inicial de <code>nil</code>, como en la siguiente expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((abedul 3) - pino - abeto - (roble 'algunos)) - (message - "Aquí están %d variables con %s, %s, y el valor %s." - abedul pino abeto roble)) -</pre></div> - -<p>Aquí, la varlist es <code>((abedul 3) pino abeto (roble -'algunos))</code>. -</p> -<p>Si evalúas esta expresión de la forma habitual, aparecerá lo -siguiente en el área echo: -</p> -<div class="smallexample"> -<pre class="smallexample">"Aquí están 3 variables con nil, nil, y el valor algunos." -</pre></div> - -<p>En este ejemplo, Emacs une el símbolo <code>abedul</code> -al número 3, une los símbolos -<code>pino</code> y <code>abeto</code> a <code>nil</code>, y une el -símbolo <code>roble</code> al valor <code>algunos</code>. -</p> -<p>Observe que en la primera parte de <code>let</code>, las variables <code>pino</code> -y <code>abeto</code> son unicamente átomos que no están rodeados por -paréntesis; esto se debe a que están siendo unidos a <code>nil</code>, -la lista vacía. Pero <code>roble</code> se une a -<code>algunos</code> por ello es parte de la lista <code>(roble -'algunos)</code>. De manera similar, <code>abedul</code> se une al número 3 en -una lista con este número. (Ya que un -número se evalúa a sí mismo, el número no -necesita ser citado. Ademas, el número se imprime en el mensaje -usando un ‘<samp>%d</samp>’ en lugar de un ‘<samp>%s</samp>’.) Las cuatro variables como un -grupo son puestas dentro de una lista para delimitarla de el -cuerpo de <code>let</code>. -</p> -<hr> -<a name="if"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Variables-let-inicializadas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#if-en-m_00e1s-detalle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-forma-especial-if"></a> -<h2 class="section">3.7 La forma especial <code>if</code></h2> -<a name="index-if"></a> -<a name="index-Condicional-con-if"></a> - -<p>Además de <code>let</code> y <code>defun</code>, esta la forma especial -condicional <code>if</code>. Esta forma se utiliza para indicar al -computador que tome decisiones. Puedes escribir definiciones de -función sin necesidad de utilizar <code>if</code>, pero se usa con bastante -frecuencia, y es lo suficientemente importante como para incluirse -aquí. Se utiliza, por ejemplo, en el código para la -función <code>beginning-of-buffer</code>. -</p> -<p>La idea básica detras de <code>if</code>, es que “<em>if</em> (si) una prueba es -verdad -<em>then</em> (entonces) se evalua la expresión.” Si la prueba no es -verdad, la -expresión no se evalua. Por ejemplo, podría -tomar una decisión como, “¡si es cálido y -soleado, entonces ir a la playa!” -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#if-en-m_00e1s-detalle"><code>if</code> en más detalle</a></td><td> </td><td align="left" valign="top"> if en más detalle -</td></tr> -<tr><td align="left" valign="top"><a href="#tipo_002dde_002danimal-en-detalle">3.7.1 La función <code>tipo-de-animal</code> en detalle</a></td><td> </td><td align="left" valign="top"> Un ejemplo de una expresión <code>if</code>. -</td></tr> -</table> - -<hr> -<a name="if-en-m_00e1s-detalle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#if" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#if" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#tipo_002dde_002danimal-en-detalle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="if-en-mas-detalle"></a> -<h3 class="unnumberedsubsec"><code>if</code> en más detalle</h3> - -<a name="index-parte_002dsi-definida"></a> -<a name="index-parte_002dentonces-definida"></a> -<p>Al escribir una expresión <code>if</code> en Lisp no se utiliza la -palabra ‘then’; la prueba y la acción son el segundo y tercer -elementos de la lista cuyo primer elemento es <code>if</code>. -No obstante, la parte de la prueba en una expresión -<code>if</code> a menudo se llamada <em>if-part</em> -(<em>parte-si</em>) y el segundo argumento a menudo se llamada -<em>then-part</em> (<em>parte-entonces</em>). -</p> -<p>Adembas, cuando se escribe una expresión <code>if</code>, la -prueba-verdadero-o-falso normalmente se escribe en la misma -línea que el símbolo <code>if</code>, pero la -acción a llevar a cabo si la prueba es verdadera, “then-part” -(<em>parte-entonces</em>), se escribe en la segunda y siguientes -líneas. Esto hace que la expresión <code>if</code> -sea mas fácil de leer. -</p> -<div class="smallexample"> -<pre class="smallexample">(if <var>prueba-verdadero-o-falso</var> - <var>accion-a-realizar-si-el-test-es-cierto</var>) -</pre></div> - -<p>La prueba-verdadero-o-falso es una expresión que evalua el -intérprete Lisp. -</p> -<p>Aquí hay un ejemplo que puedes evaluar. -La prueba consiste en si el número 5 es mayor que el número 4. Ya que es -así, -se imprime el mensaje ‘<samp>¡5 es mayor que 4!</samp>’. -</p> -<div class="smallexample"> -<pre class="smallexample">(if (> 5 4) ; <span class="roman">parte-si</span> - (message "¡5 es mayor que 4!")) ; <span class="roman">parte-entonces</span> -</pre></div> - -<p>(La función <code>></code> comprueba si su primer argumento es mayor que su -segundo argumento y devuelve verdadero si lo es.) -<a name="index-_003e-_0028mayor-que_0029"></a> -</p> -<p>Por supuesto, en un caso real, la prueba en una expresión <code>if</code> no -será siempre la misma, como en la expresión -<code>(> 5 4)</code>. En su lugar, al menos una de las variables utilizadas en la -prueba estara unida a un valor de antemano desconocido. -(Si el valor se conoce de antemano, ¡no -necesitamos realizar la prueba!) -</p> -<p>Por ejemplo, el valor puede estar unido a un argumento de una -definición de función. En la siguiente definición de función, -el tipo de animal es un valor que se pasa a la función. Si -el valor unido a <code>caracteristica</code> es -<code>fiero</code>, entonces se imprime el mensaje, ‘<samp>¡Es un -tigre!</samp>’; -de otro modo, se devolvera <code>nil</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun tipo-de-animal (caracteristica) - "Imprime el mensaje en el área echo dependiendo de CARACTERISTICA. -Si la CARACTERISTICA es el símbolo `fiero', -entonces advierte que es un tigre." - (if (equal caracteristica 'fiera) - (message "¡Es un tigre!"))) -</pre></div> - -<p>Si estás leyendo esto dentro de GNU Emacs, puedes evaluar la -definición de función de la forma habitual para instalarlo en Emacs, y -luego puedes evaluar las dos expresiones siguientes para ver los resultados: -</p> -<div class="smallexample"> -<pre class="smallexample">(tipo-de-animal 'fiero) -(tipo-de-animal 'cebra) - -</pre></div> - -<p>Al evaluar <code>(tipo-de-animal 'fiero)</code>, veras el siguiente -mensaje impreso en el área echo: <code>"¡Es un tigre!"</code>; -y cuando se evalúa <code>(tipo-de-animal 'cebra)</code> verás <code>nil</code> -impreso en el área echo. -</p> -<hr> -<a name="tipo_002dde_002danimal-en-detalle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#if-en-m_00e1s-detalle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#if" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#else" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-tipo_002dde_002danimal-en-detalle"></a> -<h3 class="subsection">3.7.1 La función <code>tipo-de-animal</code> en detalle</h3> - -<p>Veamos la función <code>tipo-de-animal</code> en detalle. -</p> -<p>La definición de función <code>tipo-de-animal</code> se escribio -llenando los espacios de dos plantillas, la primera para la definición -de función como un todo, y la seguanda para una expresión <code>if</code>. -</p> -<p>La plantilla para cada función no interactiva es: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun <var>nombre-de-funcion</var> (<var>lista-de-argumentos</var>) - "<var>documentacion</var>…" - <var>cuerpo</var>…) -</pre></div> - -<p>Las partes de la función que encajan con esta plantilla se ven asi: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun tipo-de-animal (caracteristica) - "Imprime el mensaje en el área echo dependiendo de CARACTERISTICA. -Si la CARACTERISTICA es el símbolo `fiero', -entonces advierte que es un tigre." - <var>cuerpo: la expresión</var> <code>if</code>) -</pre></div> - -<p>El nombre de función es <code>tipo-de-animal</code>; se pasa al valor de -un argumento. A la lista de argumentos se sigue una cadena de -documentación multi-línea. La cadena de -documentación se incluye en el ejemplo porque es un buen hábito -escribir la cadena de documentación para cada definición de -función. El -cuerpo de la definición de función consiste en la expresión -<code>if</code>. -</p> -<p>La plantilla para una expresión <code>if</code> se ve así: -</p> -<div class="smallexample"> -<pre class="smallexample">(if <var>prueba-verdadero-o-falso</var> - <var>accion-a-realizar-si-la-prueba-devuelve-verdadero</var>) -</pre></div> - -<p>En la función <code>tipo-de-animal</code>, el código para <code>if</code> -se ve así: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (equal caracteristica 'fiero) - (message "¡Es un tigre!"))) -</pre></div> - -<p>Aquí, está la expresión prueba-verdadero-o-falso -</p> -<div class="smallexample"> -<pre class="smallexample">(equal caracteristica 'fiero) -</pre></div> - -<p>En Lisp, <code>equal</code> es una función que determina si su primer -argumento es igual a su segundo argumento. El segundo argumento es -el símbolo citado <code>'fiero</code> y el primer argumento es -el valor del símbolo <code>caracteristico</code> -— en otras palabras, el argumento pasado a esta función. -</p> -<p>En la primer prueba de <code>tipo-de-animal</code>, el argumento -<code>fiero</code> se pasa a <code>tipo-de-animal</code>. Ya que <code>fiero</code> -es igual a <code>fiero</code>, la expresión, <code>(equal caracteristica -'fiero)</code>, devuelve el valor verdadero. Cuando esto sucede, -<code>if</code> evalúa el segundo argumento o la parte-entonces -del <code>if</code>: <code>(message "¡Es un tigre!")</code>. -</p> -<p>Por otro lado, en la segunda prueba de <code>tipo-de-animal</code>, se -pasa el argumento <code>cebra</code> a <code>tipo-de-animal</code>. <code>cebra</code> -no es igual a <code>fiero</code>, por lo que la parte-entonces no -se evalua y se devuelve <code>nil</code> por la expresión -<code>if</code> (<em>si</em>). -</p> -<hr> -<a name="else"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#tipo_002dde_002danimal-en-detalle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Verdad-y-falsedad" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Expresiones-if_002d_002dthen_002d_002delse"></a> -<h2 class="section">3.8 Expresiones if–then–else</h2> -<a name="index-Else"></a> - -<p>Una expresión <code>if</code> puede tener un tercer argumento -opcional, llamado la <em>parte-de_otro_modo</em>, en caso de que -la prueba-verdadero-o-falso devuelva falso. Cuando esto sucede, el segundo -argumento o then-part de la expresión <code>if</code> -global, <em>no</em> se evalúa, pero el tercer argumento o la -parte-de_otro_modo -<em>se</em> evalúa. Podría pensar en esto como la -alternativa del día nublado para la decisión “si es -cálido y soleado, entonces ir a la playa, de otro modo ¡leer -un -libro!” -</p> -<p>La palabra “else” (“de otro modo”) no se escribe en el código -Lisp; la parte-de_otro_modo de una expresión <code>if</code> -viene después de la parte-entonces. En Lisp, -la parte-de_otro_modo suele escribirse al inicio -de una nueva línea y se indenta menos -que la parte-entonces: -</p> -<div class="smallexample"> -<pre class="smallexample">(if <var>prueba-verdadero-o-falso</var> - <var>accion-a-realizar-si-la-prueva-devuelve-verdadero</var> - <var>accion-a-realizar-si-la-prueba-devuelve-falso</var>) -</pre></div> - -<p>Por ejemplo, la siguiente expresión <code>if</code> imprime el mensaje -‘<samp>¡4 no es mayor que 5!</samp>’ al evaluarse en la forma -habitual: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (> 4 5) ; <span class="roman">parte-si</span> - (message "¡4 falsamente es mayor que 5!") ; <span class="roman">parte-entonces</span> - (message "¡4 no es mayor que 5!")) ; <span class="roman">parte-resto</span> -</pre></div> - -<p>Nótese que los diferentes niveles de indentación hacen fácil -distinguir la parte then desde la parte resto. (GNU Emacs tiene varios -comandos que automáticamente indenta expresiones correctamente -<code>if</code> <em>si</em>. Véase la sección <a href="#Escribiendo-listas">GNU Emacs te ayuda a escribir listas</a>.) -</p> -<p>Podemos extender la función <code>tipo-de-animal</code> para incluir una -parte else para simplemente incorporar una parte adicional para la -expresión <code>if</code> <em>si</em>. -</p> -<p>Se puede ver las consecuencias de hacer esto si se evalúa la -siguiente versión de la definición de función -<code>type-of-animal</code> (<em>tipo-de-animal</em>) para instalarlo y -entonces evaluar las dos expresiones subsiguientes para pasar -diferentes argumentos para la función. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun tipo-de-animal (caracteristica) ; <span class="roman">Segunda versión.</span> - "Imprime el mensaje en el área echo dependiendo de CARACTERISTICA. -Si la CARACTERISTICA es el símbolo `fiera', -entonces avisa de un tigre; sino di que no es una fiera." - (if (equal caracteristica 'fiera) - (message "¡Es un tigre!") - (message "¡No es una fiera!"))) -</pre></div> -<br> - -<div class="smallexample"> -<pre class="smallexample">(tipo-de-animal 'fiero) -(tipo-de-animal 'cebra) - -</pre></div> - -<p>Cuando se evalúa <code>(tipo-de-animal 'fiera)</code>, se verá el -siguiente mensaje impreso en el área echo: <code>"¡Eso -es un tigre!"</code>; pero cuando se evalúa <code>(tipo-de-animal -'cebra)</code>, se verá <code>"¡No es una fiera!"</code>. -</p> -<p>(De acuerdo, si la <var>característica</var> fuera -<code>feroz</code>, el mensaje <code>"¡No es una fiera!"</code> -sería impreso; ¡y sería -erróneo! Cuando se escribe código, se necesita tener en cuenta la -posibilidad que algunos argumentos será probado por <code>if</code> -<em>si</em> y escribir tu programa de acuerdo. -</p> -<hr> -<a name="Verdad-y-falsedad"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#else" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#nil-explicado" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Verdad-y-falsedad-en-Emacs-Lisp"></a> -<h2 class="section">3.9 Verdad y falsedad en Emacs Lisp</h2> -<a name="index-Verdad-y-mentira-en-Emacs-Lisp"></a> -<a name="index-Falsedad-y-verdad-en-Emacs-Lisp"></a> -<a name="index-nil"></a> - -<p>Hay un aspecto importante para el test de verdad en una expresión -<code>if</code> (<em>si</em>). Así, hemos hablado de ‘verdad’ y -‘mentira’ como valores de predicados como si fueran nuevos tipos de -objetos Emacs Lisp. En efecto, ‘falso’ es solo nuestro viejo amigo -<code>nil</code>. Cualquier otra es ‘verdadero’. -</p> -<p>La expresión chequea si verdad se interpreta como (<em>true</em>) -<em>verdadero</em> si el resultado de evaluarlo es un valor que no es -<code>nil</code>. En otras palabras, el resultado del test se considera -cierto si el valor devuelto es un número como 47, una cadena tal -como <code>"hola"</code>, o un símbolo (otro como <code>nil</code>) -tal como <code>flores</code>, o una lista (tan larga como eso no está -vacía) ¡o incluso un búffer! -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#nil-explicado">Una explicación de <code>nil</code></a></td><td> </td><td align="left" valign="top"> <code>nil</code> tiene dos significados. -</td></tr> -</table> - -<hr> -<a name="nil-explicado"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Verdad-y-falsedad" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Verdad-y-falsedad" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#save_002dexcursion" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-explicacion-de-nil"></a> -<h3 class="unnumberedsubsec">Una explicación de <code>nil</code></h3> - -<p>Antes de ilustrar un test para verdad, se necesita una explicación -de <code>nil</code>. -</p> -<p>En Emacs Lisp, el símbolo <code>nil</code> tiene dos -significados. Primero, está el significado de la lista -vacía. Segundo, está el valor de falso y es el valor -devuelto cuando el test test-verdadero-o-falso salga -falso. <code>nil</code>. Tan lejos como el intérprete Lisp es concebido, -<code>()</code> y <code>nil</code> son el mismo. Los humanos, sin embargo, tienden -a usar <code>nil</code> para falso y <code>()</code> para la lista -vacía. -</p> -<p>En Emacs Lisp, cualquier valor que no es <code>nil</code> — no es una -lista vacía — es considerado verdad. Esto significa -que si una evaluación devuelve alguna cosa que no es una lista -vacía, una expresión <code>if</code> devuelve verdad. Por -ejemplo, si un número es puesto en el slot para el test, será -evaluado y devolverá por sí mismo, desde lo que hacen -los números cuando se evalúan. En este condicional, la expresión -<code>if</code> devuelve verdad. La expresión se chequea como falso solo -cuando <code>nil</code>, una lista vacía, es devuelta -evaluando la expresión. -</p> -<p>Se puede ver esto evaluando las dos expresiones en los siguientes ejemplos. -</p> -<p>En el primer ejemplo, número 4 es evaluado como el test en la -expresión <code>if</code> y se devuelve por sí mismo; por -consiguiente, la then-part de la expresión es evaluada y devuelta: -‘<samp>true</samp>’ aparece en el área echo. En el segundo ejemplo, -<code>nil</code> indica falso; por consiguiente, el else-part de la -expresión es evaluada y devuelta: ‘<samp>false</samp>’ aparece en el área echo. -</p> -<div class="smallexample"> -<pre class="smallexample">(if 4 - 'true - 'false) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(if nil - 'true - 'false) -</pre></div> - -<p>Incidentalmente, si algún otro valor útil no está disponible -para un test que devuelve cierto, entonces el intérprete Lisp -retornará el símbolo <code>t</code> para cierto. Por -ejemplo, la expresión <code>(> 5 4)</code> devuelve <code>t</code> cuando se -evalúa, como puedes ver evaluándolo en el camino usual: -</p> -<div class="smallexample"> -<pre class="smallexample">(> 5 4) -</pre></div> - -<p>Por otro lado, esta función devuelve <code>nil</code> si el test es falso. -</p> -<div class="smallexample"> -<pre class="smallexample">(> 4 5) -</pre></div> - -<hr> -<a name="save_002dexcursion"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#nil-explicado" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Punto-y-marca" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="save_002dexcursion-1"></a> -<h2 class="section">3.10 <code>save-excursion</code></h2> -<a name="index-save_002dexcursion"></a> -<a name="index-Region_002c-que-es"></a> -<a name="index-Preservando-punto_002c-marca_002c-y-buffer"></a> -<a name="index-Punto_002c-marca_002c-preservacion-de-buffer"></a> -<a name="index-punto"></a> -<a name="index-marca"></a> - -<p>La función <code>save-excursion</code> es la cuarta y última forma especial -que se discutirá en este capítulo. -</p> -<p>En Emacs Lisp hay programas usados para edición, la función -<code>save-excursion</code> es muy común. Eso guarda la posición de -punto y marca, ejecuta el cuerpo de la función, y entonces restaura -el punto y marca a sus posiciones previas si sus posiciones fueran -cambiadas. Su propósito primario es guardar que el usuario sea -sorprendido y molesto por movimientos inesperados de punto y marca. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Punto-y-marca">Punto y Marca</a></td><td> </td><td align="left" valign="top"> Una revisión de varias localizaciones. -</td></tr> -<tr><td align="left" valign="top"><a href="#Plantilla-para-save_002dexcursion">3.10.1 Plantilla para una expresión <code>save-excursion</code></a></td><td> </td><td align="left" valign="top"> Plantilla para save-excursion -</td></tr> -</table> - -<hr> -<a name="Punto-y-marca"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#save_002dexcursion" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#save_002dexcursion" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Plantilla-para-save_002dexcursion" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Punto-y-Marca"></a> -<h3 class="unnumberedsubsec">Punto y Marca</h3> - -<p>Antes de discutir <code>save-excursion</code>, sin embargo, puede ser útil -primero revisar que punto y marca están en GNU Emacs. <em>Punto</em> es -la posición actual del cursor. En cualquier lugar que el cursor se -posicione hay un punto. De manera más precisa, en terminales donde -el cursor parece estar en lo alto de un carácter, el punto está -inmediatamente antes del carácter. En Emacs Lisp, punto es un -entero. El primer carácter en un búffer es el número uno, el segundo -es el número dos, y así. La función <code>punto</code> -devuelve la posición actual del cursor como un número. Cada -búffer tiene su propio valor para el punto. -</p> -<p>La <em>marca</em> es otra posición en el búffer; su valor puede ser -asignado con un comando tal como <kbd>C-<SPC></kbd> -(<code>set-mark-command</code>). Si una marca ha sido asignada, se puede -usar el comando <kbd>C-x C-x</kbd> (<code>exchange-point-and-mark</code>) para -hacer que el cursor salte a la marca y asignar la marca para la -posición previa del punto. Además, si tu asignas otra marca, la -posición puede ser guardada por este camino. Se puede saltar al -cursor para una marca guardada escribiendo <kbd>C-u C-<SPC></kbd> una o -más veces. -</p> -<p>La parte del búffer entre el punto y la marca es llamada <em>la -región</em>. Numerosos comandos trabajan en la región, incluyendo -<code>center-region</code>, <code>count-lines-region</code>, <code>kill-region</code> y -<code>print-region</code>. -</p> -<p>La forma especial <code>save-excursion</code> salva las posiciones del punto -y la marca y restaura estas posiciones después del código con el -cuerpo de la forma especial es evaluada por el intérprete Lisp. De -este modo, si el punto fuera en el principio de una pieza de texto y -algún código movido apunta al fin del búffer, el -<code>save-excursion</code> no apuntaría a donde fué antes, -después las expresiones en el cuerpo de las que fueron evaluadas. -</p> -<p>En Emacs, una función frecuentemente mueve el punto como parte de -sus trabajos internos incluso aunque un usuario no espere esto. Por -ejemplo, <code>count-lines-region</code> se mueve al punto. Para prevenir al -usuario que se preocupe por el salto que es inesperado y (desde el punto -de vista del usuario) innecesario, <code>save-excursion</code> es con -frecuencia usado para punto y marca en la posición esperada por el -usuario. El uso de <code>save-excursion</code> es un buen guarda casas. -</p> -<p>Para estar seguro que la casa está limpia, <code>save-excursion</code> -restaura los valores de punto y marca incluso si alguna cosa va mal en -el código dentro de eso (o, para ser más preciso y usar la jerga -apropiada, “en caso de salida anormal”). Esta funcionalidad es muy -útil. -</p> -<p>Además grabando los valores de punto y marca, <code>save-excursion</code> -guarda la traza del actual buffer, y lo restaura, también. Esto -significa que puedes escribir código que cambiará el buffer y -tener que <code>save-excursion</code> vuelva al buffer original. Esto es como -<code>save-excursion</code> es usado en -<code>append-to-buffer</code>. (Véase la sección <a href="#append_002dto_002dbuffer">La Definición de <code>append-to-buffer</code></a>.) -</p> -<hr> -<a name="Plantilla-para-save_002dexcursion"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Punto-y-marca" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#save_002dexcursion" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Revisar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Plantilla-para-una-expresion-save_002dexcursion"></a> -<h3 class="subsection">3.10.1 Plantilla para una expresión <code>save-excursion</code></h3> - -<p>La plantilla para código usando <code>save-excursion</code> es simple: -</p> -<div class="smallexample"> -<pre class="smallexample">(save-excursion - <var>body</var>…) -</pre></div> - -<p>El cuerpo de la función es una o más expresiones que serán -evaluadas en secuencia por el intérprete Lisp. Si hay más de una -expresión en el cuerpo, el valor de la última será devuelto como -el valor de la función <code>save-excursion</code>. Las otras expresiones -en el cuerpo son evaluadas solo por sus efectos laterales; y -<code>save-excursion</code> en sí es usado solo por su efecto -lateral (que está restaurando las posiciones de punto y marca). -</p> -<p>Para más detalles, la siguiente plantilla explica <code>save-excursion</code> -</p> -<div class="smallexample"> -<pre class="smallexample">(save-excursion - <var>primera-expresion-en-el-cuerpo</var> - <var>segunda-expresion-en-el-cuerpo</var> - <var>tercera-expresion-en-el-cuerpo</var> - … - <var>ultima-expresion-en-el-cuerpo</var>) -</pre></div> - -<p>Una expresión, de acuerdo, puede ser un símbolo por -sí mismo o una lista. -</p> -<p>En código Emacs Lisp, una expresión <code>save-excursion</code> con -frecuencia ocurre el cuerpo de una expresión <code>let</code>. Eso se ve -como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(let <var>varlist</var> - (save-excursion - <var>body</var>…)) -</pre></div> - -<hr> -<a name="Revisar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Plantilla-para-save_002dexcursion" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-defun" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Revisar-2"></a> -<h2 class="section">3.11 Revisar</h2> - -<p>En los últimos pocos capítulos se han introducido un -número limpio de funciones y formas especiales. Aquí -se han descrito brevemente, con unas pocas funciones similares que no -han sido mencionadas todavía. -</p> -<dl compact="compact"> -<dt><code>eval-last-sexp</code></dt> -<dd><p>Evalúa la última expresión simbólica antes de la posición -actual del punto. El valor es impreso en el área echo a menos -que la función sea invocada con un argumento; en este caso, la salida -es impresa en el actual búffer. Este comando está normalmente -asociado a <kbd>C-x C-e</kbd>. -</p> -</dd> -<dt><code>defun</code></dt> -<dd><p>Definir función. Esta forma especial ha subido a cinco partes: el -nombre una plantilla para los argumentos que serán pasados a la -documentación de la función, una declaración interactiva -opcional, y el cuerpo de la definición. -</p> -<p>Por ejemplo, en las primeras versiones de Emacs, la definición de -función era como sigue. (Eso es ligeramente más complejo ahora que -si busca el primer caracter de espacio no en blanco en vez del primer -caracter visible.) -</p> -<div class="smallexample"> -<pre class="smallexample">(defun volver-a-indentacion () - "Mover el punto al primer caracter visible en linea." - (interactive) - (beginning-of-line 1) - (skip-chars-forward " \t")) -</pre></div> - - -</dd> -<dt><code>interactive</code></dt> -<dd><p>Declara al intérprete que la función puede ser usada -interactivamente. Esta forma especial puede ser seguida por una cadena -con una o más partes que pasan la información a los argumentos de -la función, en secuencia. Estas partes pueden también contar al -intérprete para mostrar la información. Parte de las cadenas son -separadas por nuevas líneas, ‘<samp>\n</samp>’. -</p> -<p>Caracteres de código común son: -</p> -<dl compact="compact"> -<dt><code>b</code></dt> -<dd><p>El nombre de un búffer existente. -</p> -</dd> -<dt><code>f</code></dt> -<dd><p>El nombre de un fichero existente -</p> -</dd> -<dt><code>p</code></dt> -<dd><p>El argumento prefijo numérico. (Nótese que esta ‘p’ es minúscula.) -</p> -</dd> -<dt><code>r</code></dt> -<dd><p>El Punto y la marca, como dos argumentos numéricos, el más -pequeño primero. Esta es la única letra que especifica dos -argumentos sucesivos en vez de uno. -</p></dd> -</dl> - -<p>See <a href="elisp.html#C_00f3digos-Interactivos">Caracteres de Código para ‘<samp>interactive</samp>’</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, -para una lista de caracteres de código. -</p> -</dd> -<dt><code>let</code></dt> -<dd><p>Declara que una lista de variables es para usarla con el cuerpo del -<code>let</code> y darles un valor inicial, bien <code>nil</code> o un valor -específico; entonces se evaluarán el resto de las -expresiones en el cuerpo del <code>let</code> y devolver el valor de la -última. Dentro del cuerpo del <code>let</code>, el intérprete Lisp no ve -los valores de las variables de los mismos nombres que son asociados -fuera del <code>let</code>. -</p> -<p>Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((foo (nombre-de-buffer)) - (bar (tamagno-de-buffer))) - (message - "Este buffer es %s y tiene %d caracteres." - foo bar)) -</pre></div> - -</dd> -<dt><code>save-excursion</code></dt> -<dd><p>Graba los valores de punto y marca y el actual búffer antes de evaluar -el cuerpo de esta forma especial. Restaura los valores de punto y -marca y el búffer después de esto. -</p> -<p>Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(message "Hay %d caracteres dentro de este buffer." - (- (point) - (save-excursion - (goto-char (point-min)) (point)))) -</pre></div> - -</dd> -<dt><code>if</code></dt> -<dd><p>Evalúa el primer argumento a la función; si es verdad, evalúa el -segundo argumento; lo demás evalúa el tercer argumento, si hay uno. -</p> -<p>La forma especial <code>if</code> es llamada <em>condicional</em>. Hay otros -condicionales en Emacs Lisp, pero <code>if</code> es quizás lo más -comúnmente usado. -</p> -<p>Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(if (= 22 version-de-emacs-mayor) - (message "Esta es la versión 22 de Emacs") - (message "Esta no es la versión 22 Emacs")) -</pre></div> - -</dd> -<dt><code><</code></dt> -<dt><code>></code></dt> -<dt><code><=</code></dt> -<dt><code>>=</code></dt> -<dd><p>La función <code><</code> chequea si su primer argumento es más pequeño -que su segundo argumento. Una función correspondiente, <code>></code>, -chequea si el primer argumento es mayor que el segundo. De otro modo, -<code><=</code> chequea si el primer argumento es menor o igual al segundo y -<code>>=</code> chequea si el primer argumento es mayor o igual al -segundo. En todos los casos, ambos argumentos deben ser números o -marcas (las marcas indican posiciones en búffers). -</p> -</dd> -<dt><code>=</code></dt> -<dd><p>La función <code>=</code> chequea si dos argumentos, ambos números o -marcadores, son iguales. -</p> -</dd> -<dt><code>equal</code></dt> -<dt><code>eq</code></dt> -<dd><p>Chequea si dos objetos son el mismo. <code>equal</code> usa un signicado de -la palabra ‘mismo’ y <code>eq</code> usa otro: <code>equal</code> devuelve cierto -si los dos objetos tienen una estructura y contenidos similares, tal -como dos copias del mismo libro. En una mano, <code>eq</code>, devuelve -cierto si ambos argumentos son actualmente el mismo objeto. -<a name="index-equal"></a> -<a name="index-eq"></a> -</p> -</dd> -<dt><code>string<</code></dt> -<dt><code>string-lessp</code></dt> -<dt><code>string=</code></dt> -<dt><code>string-equal</code></dt> -<dd><p>La función <code>string-lessp</code> chequea si su primer argumento es -más pequeño que el segundo. En resumen, el nombre alternativo para -la misma función (un <code>defalias</code>) es <code>string</code>. -</p> -<p>Los argumentos para <code>string-lessp</code> deben ser cadenas o -símbolos; la ordenación es lexicográfica, -así el caso es significativo. Los nombres impresos de -símbolos son usado en vez de símbolos por -sí mismos. -</p> -<a name="index-cadena-vacia-definida"></a> -<p>Una cadena vacía, ‘<samp>"\"</samp>’, es una cadena sin caracteres -dentro, es más pequeña que cualquier cadena de caracteres. -</p> -<p><code>string-equal</code> provee el test correpondiente para igualdad. Su -corto nombre alternativo es <code>string=</code>. No hay funciones test que -correponden a <var>></var>, <code>>=</code>. -</p> -</dd> -<dt><code>message</code></dt> -<dd><p>Imprime un mensaje en el área echo. El primer argumento es una -cadena que puede contener, ‘<samp>%s</samp>’, ‘<samp>%d</samp>’, o ‘<samp>%c</samp>’ para -imprimir el valor de argumentos que siguen la cadena. El argumento -usado por ‘<samp>%d</samp>’ debe ser un número. El argumento usado por -‘<samp>%c</samp>’ debe ser un número de código <small>ASCII</small>; eso será -impreso como el caracter con este código <small>ASCII</small>. (Otras varias -%-secuencias no han sido mencionadas.) -</p> -</dd> -<dt><code>setq</code></dt> -<dt><code>set</code></dt> -<dd><p>La función <code>setq</code> asigna el valor de su primer argumento al -valor del segundo argumento. El primer argumento está -automáticamente citado por <code>setq</code>. Eso hace lo mismo para los -pares de argumentos. Otra función, <code>set</code>, toma solo dos -argumentos y evalúa ambos de ellos antes de configurar el valor -devuelto por su primer argumento al valor devuelto por su segundo argumento. -</p> -</dd> -<dt><code>buffer-name</code></dt> -<dd><p>Sin un argumento, devuelve el nombre del búffer, como una cadena. -</p> -</dd> -<dt><code>buffer-file-name</code></dt> -<dd><p>Sin un argumento, devuelve el nombre del fichero si el búffer lo está -visitando. -</p> -</dd> -<dt><code>current-buffer</code></dt> -<dd><p>Devuelve el búffer en el que Emacs es activo; eso puede no ser el -búffer que es visible en la pantalla. -</p> -</dd> -<dt><code>other-buffer</code></dt> -<dd><p>Devuelve el búffer seleccionado más recientemente (otro que el -búffer pasado a <code>other-buffer</code> como un argumento y otro en vez -de el búffer actual). -</p> -</dd> -<dt><code>switch-to-buffer</code></dt> -<dd><p>Selecciona un búffer para que Emacs esté activo y lo muestre -en la ventana actual y así los usuarios puedan -mirarlo. Normalmente se empareja a <kbd>C-x b</kbd>. -</p> -</dd> -<dt><code>set-buffer</code></dt> -<dd><p>Cambia la atención de Emacs a un búffer en el que los programas se -ejecutarán. No altera lo que la ventana está mostrando. -</p> -</dd> -<dt><code>buffer-size</code></dt> -<dd><p>Devuelve el número de caracteres en el búffer actual. -</p> -</dd> -<dt><code>punto</code></dt> -<dd><p>Devuelve el valor de la actual posición del cursor, como un entero -contando el número de caracteres desde el principio del búffer. -</p> -</dd> -<dt><code>point-min</code></dt> -<dd><p>Devuelve el valor mínimo permisible del punto en el -búffer actual. Esto es 1, a menos que la contracción esté en efecto -</p> -</dd> -<dt><code>point-max</code></dt> -<dd><p>Devuelve el valor del máximo valor permisible del punto en el -búffer actual. Esto es el fin del búffer, a menos que la -contracción esté en efecto -</p></dd> -</dl> - -<hr> -<a name="Ejercicios-defun"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Revisar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicios"></a> -<h2 class="section">3.12 Ejercicios</h2> - -<ul> -<li> -Escribe una función no interactiva que doble el valor de su -argumento, un número. Luego haz la función interactiva. - -</li><li> -Escribe una función que chequee si el valor actual de -<code>fill-column</code> es más grande que el argumento pasado a la -función, y si es así, imprime un mensaje apropiado. -</li></ul> - -<hr> -<a name="Un-paseo-a-trav_00e9s-de-los-b_00faffers"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Escribiendo-funciones" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-defun" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Encontrando-m_00e1s" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Unas-pocas-funciones-de-buffer-relacionadas"></a> -<h1 class="chapter">4 Unas pocas funciones de buffer relacionadas</h1> - -<p>En este capítulo estudiamos en detalle varias de las -funciones usadas en GNU Emacs. Esto se llama un “paseo a -través”. Estas funciones son usadas como ejemplos de código Lisp, -pero no son ejemplos imaginarios; con la excepción del primero, la -definición de función simplificada, esta funciones muestran el -actual código usado en GNU Emacs. Se puede aprender mucho desde -estas definiciones. Las funciones descritas aquí están -todas relacionadas a búffers. Después, estudiaremos otras -funciones. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td><td> </td><td align="left" valign="top"> Cómo encontrar más información. -</td></tr> -<tr><td align="left" valign="top"><a href="#simplified_002dbeginning_002dof_002dbuffer">4.2 Una definición simplificada de <code>beginning-of-buffer</code></a></td><td> </td><td align="left" valign="top"> Muestra <code>goto-char</code>, - <code>point-min</code>, y <code>push-mark</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#mark_002dwhole_002dbuffer">4.3 La definición de <code>mark-whole-buffer</code></a></td><td> </td><td align="left" valign="top"> Casi lo mismo que <code>beginning-of-buffer</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#append_002dto_002dbuffer">4.4 La definición de <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Usa <code>save-excursion</code> y - <code>insert-buffer-substring</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisa-lo-relacionado-con-el-b_00faffer">4.5 Revisar</a></td><td> </td><td align="left" valign="top"> Revisa -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-de-b_00faffer">4.6 Ejercicios</a></td><td> </td><td align="left" valign="top"> Ejercicios de búffer -</td></tr> -</table> - -<hr> -<a name="Encontrando-m_00e1s"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#simplified_002dbeginning_002dof_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Encontrando-mas-informacion"></a> -<h2 class="section">4.1 Encontrando más información</h2> - -<a name="index-describe_002dfunction_002c-introducido"></a> -<a name="index-Encontrar-documentacion-de-la-funcion"></a> -<p>En este paseo, se describe cada nueva función como viene, algunas -veces en detalle y algunas veces brevemente. Si está interesado, se -puede obtener la documentación completa de cualquier función Emacs -Lisp en cualquier momento escribiendo <kbd>C-h f</kbd> y entonces el -nombre de la función (y entonces <RET>. De manera similar, se -puede obtener la documentación completa para una variable -escribiendo <kbd>C-h v</kbd>, después el nombre de la variable (y -entonces <RET>). -</p> -<a name="index-Encontrar-la-fuente-de-la-funcion"></a> -<p>También, en <code>describe-function</code>, se encontrará la localización -de la definición de la función. -</p> -<p>Poner el punto dentro del nombre del fichero que contiene la función -y presiona la tecla <RET>. En este caso, <RET> significa -<code>push-button</code> en vez de ‘return’ o ‘enter’. Emacs tomará -directamente a la definición de la función. -</p> - -<p>De manera más general, si quieres ver una función en su fichero -fuente original, se puede usar la función <code>find-tag</code> para -saltar dentro. <code>find-tag</code> funciona con una amplia variedad de -lenguajes, no solo Lisp, y C, y funciona con texto de no -programación también. Por ejemplo, <code>find-tag</code> saltará a los -varios nodos en el fichero fuente Texinfo de este documento. La -función <code>find-tag</code> depende de ‘tablas de etiquetas’ que graba -las localizaciones de las funciones, variables, y otros -ítems para los que <code>find-tag</code> salta. -</p> -<p>Para usar el comando <code>find-tag</code>, escribe <kbd>M-.</kbd> (por ej., -presionando la tecla <META>, o al menos escribe la tecla <ESC> -y entonces escribe la tecla punto), entonces, en la pantalla, se -escribe el nombre de la función cuyo código fuente se quiere ver, -tal como <code>mark-whole-buffer</code>, y luego escribe <RET>. Emacs -cambiará el búffer y mostrará el código fuente para la -función en la pantalla. Para volver al búffer actual, escribe -<kbd>C-x b <RET></kbd>. (En algunos teclados, la tecla <META> es -etiquetada con <ALT>.) -</p> -<a name="index-tabla-TAGS_002c-especificando"></a> -<a name="index-find_002dtag"></a> -<p>Dependiendo de cómo los valores iniciales por defecto de tu copia de -Emacs son asignados se puede también necesitar especificar la -posición de tu ‘tabla de tags’, que es un fichero llamado -‘<tt>TAGS</tt>’. Por ejemplo, si se está interesado en fuentes de Emacs, -la tabla de tags que se desea, si ya ha sido creada para -tí, estará en un subdirectorio del directorio -‘<tt>/usr/local/share/emacs</tt>’; de este modo se usaría el -comando <code>M-x visit-tags-table</code> y especifica una ruta tal como -‘<tt>/usr/local/share/emacs/22.1.1/lisp/TAGS</tt>’. Si la tabla tags no ha -sido creada, tendrás que crearla por tí mismo. Será -un fichero tal como ‘<tt>/usr/local/src/emacs/src/TAGS</tt>’. -</p> -<p>Para crear un fichero ‘<tt>TAGS</tt>’ en un directorio -específico, cambia a este directorio en Emacs usando -un comando <kbd>M-x cd</kbd>, o lista el directorio como <code>etags *.el</code> como el comando para ejecutar: -</p> -<div class="smallexample"> -<pre class="smallexample">M-x compile RET etags *.el RET -</pre></div> - -<p>Para más información, ver <a href="#etags">Crea tu propio fichero ‘<tt>TAGS</tt>’</a>. -</p> -<p>Después de llegar a estar más familiarizado con Emacs Lisp, -se encontrará frecuentemente usar <code>find-tag</code> para navegar tu -camino alrededor del código fuente; y se crearán tus propias tablas -‘<tt>TAGS</tt>’. -</p> -<a name="index-Libreria_002c-como-termino-para-_0060fichero_0027"></a> -<p>Incidentalmente, los ficheros que contienen código Lisp son -convencionalmente llamadas <em>librerías</em>. La -metáfora se deriva que una librería, tal como -la librería de leyes o una librería de -ingeniería, en vez de una librería -general. Cada librería, o fichero, contiene funciones -que se relacionan a un asunto particular o actividad, tal como -‘<tt>abbrev.el</tt>’ para manejar abreviaciones y otros atajos, y -‘<tt>help.el</tt>’ para la ayuda on-line. (Algunas veces varias -librerías proporcionan código para una actividad -simple, como varios ‘<tt>rmail…</tt>’ ficheros proveen código para -leer correos electrónicos.) En <cite>El Manual de GNU Emacs</cite>, tu -verás varias frases tales como “El comando <kbd>C-h p</kbd> te permite -buscar el estándar de las librerías Emacs Lisp por las -palabras claves. -</p> -<hr> -<a name="simplified_002dbeginning_002dof_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Encontrando-m_00e1s" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#mark_002dwhole_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-definicion-simplificada-de-beginning_002dof_002dbuffer"></a> -<h2 class="section">4.2 Una definición simplificada de <code>beginning-of-buffer</code></h2> -<a name="index-simplified_002dbeginning_002dof_002dbuffer"></a> - -<p>El comando <code>beginning-of-buffer</code> es una buena función para -empezar ya puedes tener cierta familiaridad con eso y es fácil de -comprender. Usado como un comando interactivo, -<code>beginning-of-buffer</code> mueve el cursor al principio del búffer, -dejando la marca en la posición previa. Eso es generalmente -asignados a <kbd>M-<</kbd>. -</p> -<p>En esta sección, se discutirá una versión ordenada de la -función que muestra como eso es lo usado más frecuentemente. Esta -función ordenada trabaja como se escribe, pero no contiene el -código para una función compleja. En otra sección, describiremos -la función entera. (Véase la sección <a href="#beginning_002dof_002dbuffer">Definición Completa de <code>beginnning-of-buffer</code></a>.) -</p> -<p>Antes de mirar en el código, permítenos considerar que -la definición de función tiene que contener: eso debe incluir una -expresión que crea la función interactiva así puede -ser llamado escribiendo <kbd>M-x beginning-of-buffer</kbd> o escribiendo -unos atajos tales como <kbd>M-<</kbd>; debe incluir código para dejar una -marca en la posición original en el búffer; y debe incluir -código el cursor al principio del búffer. -</p> -<p>Aquí está el texto completo la versión ordenada de -la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun simplified-beginning-of-buffer () - "Mover punto al principio del bufer; dejar marca en la posición previa." - (interactive) - (push-mark) - (goto-char (point-min))) -</pre></div> - -<p>Como todas las definiciones de función, esta definición tiene -cinco partes siguiendo la forma especial <code>defun</code>: -</p> -<ol> -<li> -El nombre: en este ejemplo, <code>simplified-beginning-of-buffer</code>. - -</li><li> -Una lista de los argumentos: en este ejemplo, una lista -vacía, <code>()</code>, - -</li><li> -La cadena de documentación. - -</li><li> -La expresión interactive. - -</li><li> -El cuerpo. -</li></ol> - -<p>En esta definición de función, la lista de argumentos está -vacía; esto significa que esta función no requiere -argumentos. (Cuando se busca la definición para la función -completa, se verá que puede pasarse un argumento opcional.) -</p> -<p>La expresión interactiva cuenta a Emacs que la función se pretende -ser usada interactivamente. En este ejemplo, <code>interactive</code> no -tiene un argumento porque <code>simplified-beginning-of-buffer</code> no se -requiere. -</p> -<p>El cuerpo de la función consiste de dos líneas: -</p> -<div class="smallexample"> -<pre class="smallexample">(push-mark) -(goto-char (point-min)) -</pre></div> - -<p>La primera de estas líneas es la expresión, -<code>(push-mark)</code>. Cuando esta expresión es evaluado por el -intérprete Lisp, eso asigna una marca en la posición actual del -cursor, siempre y cuando esto pueda ser. La posición de esta marca -está guardada en el anillo de marcas. -</p> -<p>La siguiente línea es <code>(goto-char -(point-min))</code>. Esta expresión salta el cursor al punto -mínimo en el búffer, esto es, para el comienzo del -búffer (o al principio de la porción accesible del búffer si eso -está encogido. Véase la sección <a href="#Encogiendo-y-extendiendo">Encogiendo y extendiendo</a>.) -</p> -<p>El comando <code>push-mark</code> estable una marca en el lugar donde el -cursor fué localizado antes que fuera movido al principio del -búffer por la expresión <code>(goto-char -(point-min))</code>. Consiguientemente, puedes, si lo deseas, volver donde -estabas originalmente escribiendo <kbd>C-x C-x</kbd>. -</p> -<p>¡Esto es todo lo que hay para la definición de función! -</p> -<a name="index-describe_002dfunction"></a> -<p>Cuando se lee código como este y vuelve a una función no familiar, -tal como <code>goto-char</code>, se puede encontrar que se hace usando el -comando <code>describe-function</code>. Para usar este comando, escribe -<kbd>C-h f</kbd> y entonces escribe en el nombre de la función y presiona -<RET>. El comando <code>describe-function</code> imprimirá la -documentaciń de la cadena de la función en una ventana -‘<tt>*Help*</tt>’. Por ejemplo, la documentación para <code>goto-char</code> es: -</p> -<div class="smallexample"> -<pre class="smallexample">Asignar punto a POSITION, un número o marca -Empezando el buffer es la posición (point-min), y el final es -(point-max). -</pre></div> - -<p>La función es un argumento es la posición deseada. -</p> -<p>(La consola para <code>describe-function</code> te ofrecerá el -símbolo abajo o precediendo al cursor, así -se puede guardar escribiendo al posicionar el cursor a la derecha o -después de la función y entonces escribir <kbd>C-h f <RET></kbd>.) -</p> -<p>La definición de función <code>end-of-buffer</code> está escrito en el -mismo modo que la definición <code>beginnig-of-buffer</code> excepto que -el cuerpo de la función contenga la expresión <code>(goto-char -(point-max))</code> en lugar de <code>(goto-char (point-min))</code> -</p> -<hr> -<a name="mark_002dwhole_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#simplified_002dbeginning_002dof_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#resumen-de-mark_002dwhole_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-definicion-de-mark_002dwhole_002dbuffer"></a> -<h2 class="section">4.3 La definición de <code>mark-whole-buffer</code></h2> -<a name="index-mark_002dwhole_002dbuffer"></a> - -<p>La función <code>mark-whole-buffer</code> no es tan difícil de -comprender que la función <code>simplified-beginning-of-buffer</code>. En -este caso, sin embargo, se verá la función completa, no una -versión ordenada. -</p> -<p>La función <code>mark-whole-buffer</code> no está comúnmente usada -como la función <code>beginning-of-buffer</code>, pero eso no es útil: -eso marca un búffer completo como una región poniendo el punto al -principio y una marca al fin del búffer. Eso está generalmente -asociado a <kbd>C-x h</kbd>. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#resumen-de-mark_002dwhole_002dbuffer">Un resumen de <code>mark-whole-buffer</code></a></td><td> </td><td align="left" valign="top"> resumen de mark-whole-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#Cuerpo-de-mark_002dwhole_002dbuffer">4.3.1 Cuerpo de <code>mark-whole-buffer</code></a></td><td> </td><td align="left" valign="top"> Solo tres líneas de código. -</td></tr> -</table> - -<hr> -<a name="resumen-de-mark_002dwhole_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#mark_002dwhole_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#mark_002dwhole_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Cuerpo-de-mark_002dwhole_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-resumen-de-mark_002dwhole_002dbuffer"></a> -<h3 class="unnumberedsubsec">Un resumen de <code>mark-whole-buffer</code></h3> - -<p>En GNU Emacs 22, el código para la función completa se parece a: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun mark-whole-buffer () - "Pon el punto al principio y marca el fin del búffer. -Probablemante no deberías usar esta función en - programas Lisp; normalmente un error para una función Lisp usa - cualquier subrrutina que usa o asigna la marca." - (interactive) - (push-mark (point)) - (push-mark (point-max) nil t) - (goto-char (point-min))) -</pre></div> - -<p>Como todas las otras funciones, la función <code>mark-whole-buffer</code> -se ajusta dentro de la plantilla para una definición. La plantilla -se parece a esta: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun <var>name-of-function</var> (<var>argument-list</var>) - "<var>documentation</var>…" - (<var>interactive-expression</var>…) - <var>body</var>…) -</pre></div> - -<p>Aquí está cómo la función trabaja: el nombre de la -función es <code>mark-whole-buffer</code>; eso es seguida por un argumento -de lista vacía, ‘<samp>()</samp>’, que significa que la -función no requiere argumentos. La documentación viene la siguiente. -</p> -<p>La siguiente línea es una expresión -<code>(interactive)</code> que cuenta a Emacs que la función será usada -interactivamente. Estos detalles son similares a la función -<code>simplified-beginning-of-buffer</code> descrita en la sección previa -</p> -<hr> -<a name="Cuerpo-de-mark_002dwhole_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#resumen-de-mark_002dwhole_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#mark_002dwhole_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#append_002dto_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Cuerpo-de-mark_002dwhole_002dbuffer-1"></a> -<h3 class="subsection">4.3.1 Cuerpo de <code>mark-whole-buffer</code></h3> - -<p>El cuerpo de la función <code>mark-whole-buffer</code> consiste en tres -líneas de código: -</p> -<div class="smallexample"> -<pre class="smallexample">(push-mark (point)) -(push-mark (point-max) nil t) -(goto-char (point-min)) -</pre></div> - -<p>El primero de estas líneas es la expresión, -<code>(push-mark (point))</code>. -</p> -<p>Esta línea hace exactamente el mismo trabajo que la -primera línea del cuerpo de la función -<code>simplified-beginning-of-buffer</code>, que está escrita -<code>(push-mark)</code>. En ambos casos, el intérprete Lisp asigna una -marca en la posición actual del cursor. -</p> -<p>No sé por qué en la expresión <code>mark-whole-buffer</code> está -escrito <code>(push-mark (point))</code> y en la expresión -<code>beginning-of-buffer</code> está escrito <code>(push-mark)</code>. Quizás -quien escribió el código no sabía que los argumentos -para <code>push-mark</code> son opcionales y que si <code>push-mark</code> no se -pasa como argumento, la función automáticamente asigna la marca en -la localización del punto por defecto. O quizás la expresión -fué escrita así como para parelizar la estructura de -la siguiente línea. En cualquier caso, la -línea causa que Emacs determine la posición del -punto y asigne una marca allí. -</p> -<p>En las primeras versiones de GNU Emacs, la siguiente -línea de <code>mark-whole-buffer</code> fué <code>(push-mark -(point-max))</code>. Esta expresión asigna una marca en el punto en el -búffer que tiene el número más alto. Esto será el fin del -búffer (o, si el búffer es encogida, el fin de la porción -accesible del búffer. Véase la sección <a href="#Encogiendo-y-extendiendo">Encogiendo y extendiendo</a>, para más acerca de encoger). Después esta marca ha sido -asignada, la marca previa, uno asigna un punto, pero no se asigna largo, -pero Emacs recuerda su posición, solo como todas las otras marcas -recientes son siempre recordadas. Esto significa que se puede, si lo -deseas, vuelve a esta posición escribiendo <kbd>C-u C-<SPC></kbd> dos -veces. -</p> -<p>En GNU Emacs 22, el <code>(point-max)</code> es ligeramente más -complicado. La línea lee -</p> -<div class="smallexample"> -<pre class="smallexample">(push-mark (point-max) nil t) -</pre></div> - -<p>La expresión funciona cerca de lo mismo que antes. Eso asigna una marca -en el lugar numerado más alto que se puede en el búffer. Sin -embargo, en esta versión, <code>push-mark</code> tiene dos argumentos -adicionales. El segundo argumento para <code>push-mark</code> es -<code>nil</code>. Esto cuenta la función que -<em>mostraría</em> un mensaje que dice ‘Marca asignada’ -cuando eso empuja la marca. El tercer argumento es <code>t</code>. Esto -cuenta <code>push-mark</code> para activar la marca cuando el modo Transient -Mark está activado. Transient Mark mode ilumina la región de marca -activa. Con frecuencia desactivada -</p> -<p>Finalmente, la última línea de la función es -<code>(goto-char (point-min))</code>. Esto es escrito exactamente el mismo -camino camino como está escrito <code>beginning-of-buffer</code>. La -expresión mueve el cursor al mínimo punto en el -búffer, que es, al principio del búfferr (o para el principio de -la porción accesible del búffer). Como un resultado de esto, punto -está emplazado al principio del búffer y la marca está asignada al -fin del búffer. El búffer completo es, más allá, la región. -</p> -<hr> -<a name="append_002dto_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Cuerpo-de-mark_002dwhole_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#resumen-de-append_002dto_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-definicion-de-append_002dto_002dbuffer"></a> -<h2 class="section">4.4 La definición de <code>append-to-buffer</code></h2> -<a name="index-append_002dto_002dbuffer"></a> - -<p>El comando <code>append-to-buffer</code> es más complejo que el comando -<code>mark-whole-buffer</code>. Lo que hace es copiar la región (que es, -la parte del búffer entre punto y marca) desde el buffer actual a un -búffer específico. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#resumen-de-append_002dto_002dbuffer">Un resumen de <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> resumen de append-to-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#append-interactivo">4.4.1 La expresión interactiva <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Una expresión interactiva de dos partes. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-append_002dto_002dbuffer">4.4.2 El cuerpo de <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Incorpora una expresión <code>let</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#append-save_002dexcursion">4.4.3 <code>save-excursion</code> en <code>append-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Cómo <code>save-excursion</code> trabaja. -</td></tr> -</table> - -<hr> -<a name="resumen-de-append_002dto_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#append_002dto_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#append_002dto_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#append-interactivo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-resumen-de-append_002dto_002dbuffer"></a> -<h3 class="unnumberedsubsec">Un resumen de <code>append-to-buffer</code></h3> - -<a name="index-insert_002dbuffer_002dsubstring"></a> -<p>El comando <code>append-to-buffer</code> usa la función -<code>insert-buffer-substring</code> para copiar la -región. <code>insert-buffer-substring</code> es descrita por su nombre: -eso toma una cadena de caracteres desde parte de un búffer, una -“subcadena”, y las inserta dentro de otro búffer. -</p> -<p>La mayoría de <code>append-to-buffer</code> se refiere con la -configuración de las condiciones para <code>insert-buffer-substring</code> -para trabajar: el código debe especificar ambos el búffer para el -que el texto irá, la ventana viene y va, y la región que será copiada. -</p> -<p>Aquí está el texto completo de la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun append-to-buffer (buffer start end) - "Introduce al búffer específico el texto de la - región. Esto es insertado de este búffer antes de su punto. -</pre><pre class="smallexample"> -</pre><pre class="smallexample">Cuando se llama desde un programa, se dan tres argumentos: -BUFFER (o nombre del búffer), START y END. -START y END especifica la porción del búffer actual para ser copiado." - (interactive - (list (read-buffer "Append to buffer: " (other-buffer - (current-buffer) t)) - (region-beginning) (region-end))) -</pre><pre class="smallexample"> (let ((oldbuf (current-buffer))) - (save-excursion - (let* ((append-to (get-buffer-create buffer)) - (windows (get-buffer-window-list append-to t t)) - point) - (set-buffer append-to) - (setq point (point)) - (barf-if-buffer-read-only) - (insert-buffer-substring oldbuf start end) - (dolist (window windows) - (when (= (window-point window) point) - (set-window-point window (point)))))))) -</pre></div> - -<p>La función puede ser comprendida buscando como series de plantillas -rellenas -</p> -<p>La plantilla de fuera es para la definición de la función. En esta -función, se ve como esto (con varios slots rellenos): -</p> -<div class="smallexample"> -<pre class="smallexample">(defun append-to-buffer (buffer start end) - "<var>documentacion</var>…" - (interactive …) - <var>cuerpo</var>…) -</pre></div> - -<p>La primera línea de la función incluye su nombre y los -tres argumentos. Los argumentos son el <code>búffer</code> que el texto -será copiado, y el <code>start</code> y <code>end</code> de la región en el -buffer actual que será copiado. -</p> -<p>La siguiente parte de la función es la documentación, que es claro -y completo. Como es convencional, los tres argumentos son escritos en -mayúsculas así se notificarán fácilmente. Incluso -mejor, son descritas en el mismo orden como en la lista de argumentos. -</p> -<p>Nótese que la documentación distingue entre un búffer y su -nombre. (La función puede manejar otro.) -</p> -<hr> -<a name="append-interactivo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#resumen-de-append_002dto_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#append_002dto_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-append_002dto_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-expresion-interactiva-append_002dto_002dbuffer"></a> -<h3 class="subsection">4.4.1 La expresión interactiva <code>append-to-buffer</code></h3> - -<p>Desde que la función <code>append-to-buffer</code> será usada -interactivamente, la función debe tener una expresión -<code>interactive</code>. (Para una revisión de <code>interactive</code>, ver -<a href="#Interactive">Creando una Función Interactive</a>.) La -expresión se lee de la siguiente manera: -</p> -<div class="smallexample"> -<pre class="smallexample">(interactive - (list (read-buffer - "Agrega al buffer: " - (other-buffer (current-buffer) t)) - (region-beginning) - (region-end))) -</pre></div> - -<p>Esta expresión no es una con letras separadas por partes, como se -describe antes. En vez de eso, empieza una lista con estas partes: -</p> -<p>La primera parte de la lista es una expresión para leer el nombre de -un búffer y lo devuelve como una cadena. Esto es -<code>read-buffer</code>. La función requiere una consola como su primer -argumento, ‘<samp>"Asocia al buffer: "</samp>’. Su segundo argumento cuenta el -comando que valora para proporciona si no especifica cualquier cosa. -</p> -<p>En este caso este segundo argumento es una expresión conteniendo la -función <code>other-buffer</code>, una excepción, y una ‘<samp>t</samp>’, para verdad. -</p> -<p>El primer argumento para <code>other-buffer</code>, la excepción, es -todavía otra función, <code>other-buffer</code>. Esto es no -yendo a ser devuelto. El segundo argumento es el símbolo -para verdad, <code>t</code>. Esto cuenta <code>other-buffer</code> que puede -mostrar búffers visibles (excepto en este caso, eso no mostrará el -búffer actual, que tiene sentido). -</p> -<p>La expresión se ve como: -</p> -<div class="smallexample"> -<pre class="smallexample">(other-buffer (current-buffer) t) -</pre></div> - -<p>El segundo y tercer argumento de la expresión <code>list</code> son -<code>(region-beginning)</code> y <code>(region-end)</code>. Estas dos funciones -especifican el principio el y el final del texto que se adjunta. -</p> -<p>Originalmente, el comando usaba las letras ‘<samp>B</samp>’ y ‘<samp>r</samp>’. La -expresión completa <code>interactive</code> es así: -</p> -<div class="smallexample"> -<pre class="smallexample">(interactive "BAsociar al buffer: \nr") -</pre></div> - -<p>Pero cuando esto fué hecho, el valor por defecto del búffer cambió -a ser invisible. Esto no se quería. -</p> -<p>(La consola estaba separada del segundo argumento con una nueva -línea, ‘<samp>\n</samp>’. Estaba seguido por un ‘<samp>r</samp>’ que -contaba a Emacs emparejar los dos argumentos que siguen el -símbolo <code>buffer</code> en la lista de argumentos de la -función (que es, <code>start</code> y <code>end</code>) para los valores de -punto y marca. Este argumento trabajó bien.) -</p> -<hr> -<a name="cuerpo-append_002dto_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#append-interactivo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#append_002dto_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#append-save_002dexcursion" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-cuerpo-de-append_002dto_002dbuffer"></a> -<h3 class="subsection">4.4.2 El cuerpo de <code>append-to-buffer</code></h3> - - -<p>El cuerpo de la función <code>append-to-buffer</code> empieza con <code>let</code>. -</p> -<p>Como se ha visto antes (véase la sección <a href="#let"><code>let</code></a>), el propósito de -una expresión <code>let</code> es crear y dar valores iniciales a una o -más variable que solo serán usada con el cuerpo del -<code>let</code>. Esto significa que tal variable no será confuso con -cualquier variable del mismo nombre fuera de la expresión <code>let</code>. -</p> -<p>Podemos ver como la expresión <code>let</code> se ajusta dentro de la -función como un todo mostrando una plantilla para -<code>append-to-buffer</code> con la expresión <code>let</code> en -línea: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun append-to-buffer (buffer start end) - "<var>documentacion</var>…" - (interactive …) - (let ((<var>variable</var> <var>valor</var>)) - <var>cuerpo</var>…) -</pre></div> - -<p>La expresión <code>let</code> tiene tres elementos: -</p> -<ol> -<li> -El símbolo <code>let</code>; - -</li><li> -Una varlist conteniendo, en este caso, una lista simple de dos -elementos, <code>(<var>variable</var> <var>value</var>)</code>; - -</li><li> -El cuerpo de la expresión <code>let</code>. -</li></ol> - -<p>En la función <code>append-to-buffer</code>, la varlist se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(oldbuf (current-buffer)) -</pre></div> - -<p>En esta parte de la expresión <code>let</code>, una variable, -<code>oldbuf</code> es emparejada al valor devuelto por la expresión -<code>(current-buffer)</code>. La variable, <code>oldbuf</code>, es usada para -guardar la traza del búffer en el que tu estás trabajando y desde -el que se copiará. -</p> -<p>El elemento o elementos de una varlist son rodeados por un conjunto de -paréntesis así el intérprete Lisp puede distinguir -la varlist desde el cuerpo del <code>let</code>. Como consecuencia, la lista -de dos elementos con la varlist está rodeados por un circunscrito -conjunto de paréntesis. Las líneas se ven -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((oldbuf (current-buffer))) - … ) -</pre></div> - -<p>Los dos paréntesis antes de <code>oldbuf</code> podrían -sorprenderte si no fuera porque los primeros paréntesis antes de -<code>oldbuf</code> marcan el límite de la varlist y el segundo -paréntesis marca el principio de la lista de dos elementos, -<code>(oldbuf (current-buffer))</code>. -</p> -<hr> -<a name="append-save_002dexcursion"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-append_002dto_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#append_002dto_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Revisa-lo-relacionado-con-el-b_00faffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="save_002dexcursion-en-append_002dto_002dbuffer"></a> -<h3 class="subsection">4.4.3 <code>save-excursion</code> en <code>append-to-buffer</code></h3> - -<p>El cuerpo de la expresión <code>let</code> en <code>append-to-buffer</code> -consiste de una expresión <code>save-excursion</code>. -</p> -<p>La función <code>save-excursion</code> guarda las localizaciones de punto y -la marca, y las restaura a estas posiciones después de las expresiones -en el cuerpo de la ejecución completa -<code>save-excursion</code>. Además, <code>save-excursion</code> completa -la ejecución. Además, <code>save-excursion</code> guarda la traza del -búffer original, y lo restaura. Esto es cómo <code>save-excursion</code> -que se usa en <code>append-to-buffer</code>. -</p> -<a name="index-Indentacin-para-formatear"></a> -<a name="index-Convencion-formateando"></a> -<p>Incidentalmente, no se valora nada aquí que una -función Lisp es normalmente formateada así que cada -cosa que es encerrada en conjunto multilínea que es -indentada más a la derecha que el primer símbolo. En -esta definición de función, el <code>let</code> es indentado más que -<code>defun</code>, y el <code>save-excursion</code> es indentado más que el -<code>let</code>, como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun … - … - … - (let… - (save-excursion - … -</pre></div> - -<p>Esta convención formatea que sea fácil de ver que las -líneas en el cuerpo de <code>save-excursion</code>, solo -como <code>save-excurion</code> por sí mismo están -encerradas por los paréntesis asociados con el <code>let</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((oldbuf (current-buffer))) - (save-excursion - … - (set-buffer …) - (insert-buffer-substring oldbuf start end) - …)) -</pre></div> - -<p>El uso de la función <code>save-excursion</code> puede ser vista como un -proceso de rellenar slots de una plantilla: -</p> -<div class="smallexample"> -<pre class="smallexample">(save-excursion - <var>primera-expresion-en-cuerpo</var> - <var>segunda-expresion-en-cuerpo</var> - … - <var>ultima-expresion-en-cuerpo</var>) -</pre></div> - -<p>En esta función, el cuerpo de <code>save-excursion</code> contiene solo -una expresión, la expresión <code>let*</code>. Se conoce una función -<code>let</code>. La función <code>let*</code> es diferente. Eso tiene un -‘<samp>*</samp>’ en su nombre. Eso permite a Emacs asignar cada variable de su -varlist en secuencia, una después de otra. -</p> -<p>Su funcionalidad crítica es que las variable después -en la varlist puedan hacer uso de los valores para los que Emacs asigna -variables pronto en la varlist. Véase la sección <a href="#fwd_002dpara-let">La expresión <code>let*</code></a>. -</p> -<p>Se obviarán funciones como <code>let*</code> y se focalizará en dos: la -función <code>set-buffer</code> y la función -<code>insert-buffer-substring</code>. -</p> -<p>En antaño, la expresión <code>set-buffer</code> era simple: -</p> -<div class="smallexample"> -<pre class="smallexample">(set-buffer (get-buffer-create buffer)) -</pre></div> - -<p>pero ahora eso es -</p> -<div class="smallexample"> -<pre class="smallexample">(set-buffer append-to) -</pre></div> - -<p><code>append-to</code> se asigna a <code>(get-buffer-create-buffer)</code> pronto -en la expresión <code>let*</code>. Esta asociación extra no -sería necesaria excepto para este <code>append-to</code> es -usado después en la varlist como un argumento para -<code>get-buffer-window-list</code>. -</p> - -<p>La definición de la función <code>append-to-buffer</code> inserta texto -desde el búffer en el que estás actualmente a un buffer -nombrado. Eso sucede que <code>insert-buffer-substring</code> copia texto -desde otro búffer al búffer actual, solo el inverso — que es -porque la definición <code>append-to-buffer</code> empieza con un -<code>let</code> que asocia el símbolo local <code>oldbuf</code> al -valor devuelto por <code>current-buffer</code>. -</p> -<p>La expresión <code>insert-buffer-substring</code> se ve como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(insert-buffer-substring oldbuf start end) -</pre></div> - -<p>La función <code>insert-buffer-substring</code> copia una cadena -<em>from</em> al búffer especificado como su primer argumento e -inserta la cadena dentro del búffer presente. En este caso, el -argumento para <code>insert-buffer-substring</code> es el valor de la -variable creada y asociada por el <code>let</code>, llama al valor de -<code>oldbuf</code>, que fué el búffer actual cuando tu diste el comando -<code>append-to-buffer</code>. -</p> -<p>Después de que <code>insert-buffer-substring</code> ha hecho su trabajo, -<code>save-excursion</code> restaurará la acción al búffer original y -<code>append-to-buffer</code> habrá hecho su trabajo. -</p> -<p>Escrito en forma esquelética, los trabajos del cuerpo se ven como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(let (<var>bind-</var><code>oldbuf</code><var>-to-value-of-</var><code>current-buffer</code>) - (save-excursion ; <span class="roman">Guarda la traza del búffer.</span> - <var>change-buffer</var> - <var>insert-substring-from-</var><code>oldbuf</code><var>-into-buffer</var>) - - <var>change-back-to-original-buffer-when-finished</var> -<var>let-the-local-meaning-of-</var><code>oldbuf</code><var>-disappear-when-finished</var> -</pre></div> - -<p>En resumen, <code>append-to-buffer</code> funciona como sigue: se guarda el -valor del búffer actual en la variable llamada <code>oldbuf</code>. Se obtiene -el nuevo búffer (creando uno si necesita ser) y cambia la atención -de Emacs a eso. Usando el valor de <code>oldbuf</code>, inserta la región -del texto desde el viejo búffer dentro del nuevo búffer; y entonces -usando <code>save-excursion</code>, trae atrás a tu búffer original. -</p> -<p>Buscando <code>append-to-buffer</code>, se ha explorado una función limpia -compleja. Eso muestra como usar <code>let</code> y <code>save-excursion</code>, y -como cambiar y volver desde otro buffer. Muchas definiciones de -función usan <code>let</code>, <code>save-excursion</code>, y <code>set-buffer</code> -de este modo. -</p> -<hr> -<a name="Revisa-lo-relacionado-con-el-b_00faffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#append-save_002dexcursion" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-de-b_00faffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Revisar-3"></a> -<h2 class="section">4.5 Revisar</h2> - -<p>Aquí está un breve resumen de varias funciones -discutidas en este capítulo. -</p> -<dl compact="compact"> -<dt><code>describe-function</code></dt> -<dt><code>describe-variable</code></dt> -<dd><p>Imprime la documentación para una función o -variable. Convencionalmente asociada a <kbd>C-h f</kbd> y <kbd>C-h v</kbd>. -</p> -</dd> -<dt><code>find-tag</code></dt> -<dd><p>Encuentra el fichero que contiene la fuente para una función o -variable y cambia buffer a él, posicionando el punto al principio -del ítem. Convencionalmente emparejado a <kbd>M-.</kbd> (esto -es un período seguiendo la tecla <META>). -</p> -</dd> -<dt><code>save-excursion</code></dt> -<dd><p>Guarda la localización de punto y marca y restaura sus valores -después de los argumentos para <code>save-excursion</code> y han sido -evaluados. También, recuerda el buffer actual y devuélvelo. -</p> -</dd> -<dt><code>push-mark</code></dt> -<dd><p>Asigna la marca en una localización y graba el valor de la marca -previa en el anillo de la marca. La marca es una localización en el -búffer que guarda su posición relativa incluso si el texto es -añadido o borrado desde el búffer. -</p> -</dd> -<dt><code>goto-char</code></dt> -<dd><p>Asigna punto a la localización especificada por el valor del -argumento, que puede ser un número, una marca, o una expresión que -devuelve el número de una posición, tal como <code>(point-min)</code>. -</p> -</dd> -<dt><code>insert-buffer-substring</code></dt> -<dd><p>Copia una región de texto desde un búffer que es pasado a la -función como un argumento e inserta la región dentro del búffer -actual. -</p> -</dd> -<dt><code>mark-whole-buffer</code></dt> -<dd><p>Marca el búffer completo como una región. Normalmente asignado a -<kbd>C-x h</kbd>. -</p> -</dd> -<dt><code>set-buffer</code></dt> -<dd><p>Cambia la atención de Emacs a otro búffer, pero no cambies la -ventana siendo mostrada. Usado cuando el programa en vez de un humano -trabaja en un búffer diferente. -</p> -</dd> -<dt><code>get-buffer-create</code></dt> -<dt><code>get-buffer</code></dt> -<dd><p>Encuentra un búffer nombrado o crea uno si un búffer de este -nombre no existe. La función <code>get-buffer</code> devuelve <code>nil</code> -si el nombre del búffer no existe. -</p></dd> -</dl> - -<hr> -<a name="Ejercicios-de-b_00faffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Revisa-lo-relacionado-con-el-b_00faffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicios-2"></a> -<h2 class="section">4.6 Ejercicios</h2> - -<ul> -<li> -Escribe tu propia definición de función -<code>simplified-end-of-buffer</code>; entonces testea para ver si funciona. - -</li><li> -Usa <code>if</code> y <code>get-buffer</code> para escribir una función que -imprime un mensaje contando si un buffer existe. - -</li><li> -Usando <code>find-tag</code>, encuentra la fuente para la función -<code>copy-to-buffer</code> -</li></ul> - -<hr> -<a name="M_00e1s-complejidad"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-de-b_00faffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#copy_002dto_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Unas-pocas-funciones-mas-complejas"></a> -<h1 class="chapter">5 Unas pocas funciones más complejas</h1> - -<p>En este capítulo, se construye lo que se aprendió en -los capítulos previos mirando en funciones más -complejas. La función <code>copy-to-buffer</code> ilustra el uso de -expresiones <code>save-excursion</code> en una definición, mientras la -función <code>insert-buffer</code> ilustra el uso de un asterisco en una -expresión <code>interactive</code>, uso de <code>o</code>, y la importante -distinción entre un nombre y el objeto para el que el nombre se -refiere. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#copy_002dto_002dbuffer">5.1 La definición de <code>copy-to-buffer</code></a></td><td> </td><td align="left" valign="top"> Con <code>set-buffer</code>, - <code>get-buffer-create</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#insert_002dbuffer">5.2 La definición de <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Solo lectura, y con <code>or</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#beginning_002dof_002dbuffer">5.3 Definición completa de <code>beginning-of-buffer</code></a></td><td> </td><td align="left" valign="top"> Muestra <code>goto-char</code>, <code>point-min</code>, y - <code>push-mark</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisar-el-segundo-b_00faffer-relacionado">5.4 Revisar</a></td><td> </td><td align="left" valign="top"> Revisar el segundo búffer - relacionado -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-opcional">5.5 Ejercicio de argumento <code>opcional</code></a></td><td> </td><td align="left" valign="top"> Ejercicio opcional -</td></tr> -</table> - -<hr> -<a name="copy_002dto_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-definicion-de-copy_002dto_002dbuffer"></a> -<h2 class="section">5.1 La definición de <code>copy-to-buffer</code></h2> -<a name="index-copy_002dto_002dbuffer"></a> - -<p>Después de comprender cómo se trabaja <code>append-to-buffer</code>, es -fácil para comprender <code>copy-to-buffer</code>. Esta función copia -texto dentro de un búffer, pero en vez de añadir al segundo -búffer, se reemplaza a todo el texto previo en el segundo búffer. -</p> -<p>El cuerpo de <code>copy-to-buffer</code> se ve como esto, -</p> -<div class="smallexample"> -<pre class="smallexample">… -(interactive "BCopy to buffer: \nr") -(let ((oldbuf (current-buffer))) - (with-current-buffer (get-buffer-create buffer) - (barf-if-buffer-read-only) - (erase-buffer) - (save-excursion - (insert-buffer-substring oldbuf start end))))) -</pre></div> - -<p>La función <code>copy-to-buffer</code> tiene una expresión simple -<code>interactive</code> en vez de <code>append-to-buffer</code>. -</p> -<p>La definición entonces dice: -</p> -<div class="smallexample"> -<pre class="smallexample">(with-current-buffer (get-buffer-create buffer) … -</pre></div> - -<p>Primero, mira en la expresión interna más temprana; que es -evaluada primero. Esta expresión empieza con <code>get-buffer-create -buffer</code>. La función cuenta al ordenador para usar el búffer con el -nombre específicado como uno para el que estás -copiando, o si tal búffer no existe, créalo. Entonces, la función -<code>with-current-buffer</code> evalúa su cuerpo con este búffer -temporalmente al actual. -</p> -<p>(Esto demuestra otro camino para cambiar la atención del ordenador -pero no los usuarios. La función <code>append-to-buffer</code> muestra -como hacer lo mismo con <code>save-excursion</code> y -<code>set-buffer</code>. <code>with-current-buffer</code> es uno nuevo, y -argumentablemente fácil, mecanismo.) -</p> -<p>La función <code>barf-if-buffer-read-only</code> envía un -mensaje de error diciendo al búffer es de solo lectura si no se -puede modificar. -</p> -<p>La siguiente línea tiene la función -<code>erase-buffer</code> como sus únicos contenidos. Este función borra -el búffer. -</p> -<p>Finalmente, las últimas dos líneas contienen la -expresión <code>save-excursion</code> con <code>insert-buffer-substring</code> -como su cuerpo. La expresión <code>insert-buffer-substring</code> copia el -texto desde el búffer en el que se está (y no se ha visto el -ordenador puesta su atención, así no se sabe que este -búffer es ahora llamado <code>oldbuf</code>). -</p> -<p>De manera incidental, esto es lo que significa por ‘reemplazo’. Para -reemplazar texto Emacs se borra el texto previo y entonces se inserta el -nuevo texto. -</p> -<p>El código fuente, del cuerpo de <code>copy-to-buffer</code> se parece a -esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(let (<var>bind-</var><code>oldbuf</code><var>-to-value-of-</var><code>current-buffer</code>) - (<var>with-the-buffer-you-are-copying-to</var> - (<var>but-do-not-erase-or-copy-to-a-read-only-buffer</var>) - (erase-buffer) - (save-excursion - <var>insert-substring-from-</var><code>oldbuf</code><var>-into-buffer</var>))) -</pre></div> - -<hr> -<a name="insert_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#copy_002dto_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#c_00f3digo-insert_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-definicion-de-insert_002dbuffer"></a> -<h2 class="section">5.2 La definición de <code>insert-buffer</code></h2> -<a name="index-insert_002dbuffer"></a> - -<p><code>insert-buffer</code> es todavía una función -relacionada con el búffer. Este comando copia otro búffer -<em>dentro</em> del búffer actual. Es lo inverso de -<code>append-to-buffer</code> o <code>copy-to-buffer</code>, desde que se copia -una región de texto <em>desde</em> el búffer actual a otro -búffer. -</p> -<p>Aquí hay una discusión basada en el código -original. El código era simplificado en 2003 y es duro de comprender. -</p> -<p>(Véase la sección <a href="#Nuevo-insert_002dbuffer">Nuevo Cuerpo para <code>insert-buffer</code></a>, -para ver una discusión del nuevo cuerpo.) -</p> -<p>Además, este código ilustra el uso de <code>interactive</code> con un -búffer que podría ser <em>read-only</em> y la -distinción entre el nombre de un objeto y el objeto actualmente referido. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#c_00f3digo-insert_002dbuffer">El código para <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> código insert-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#insert_002dbuffer-interactivo">5.2.1 La expresión interactiva en <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Cuando tu puedes leer, pero no escribir. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-insert_002dbuffer">5.2.2 El cuerpo de la función <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> El cuerpo tiene un <code>or</code> y un <code>let</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#si-y-o">5.2.3 <code>insert-buffer</code> con un <code>if</code> en vez de un <code>or</code></a></td><td> </td><td align="left" valign="top"> Usando un <code>if</code> en vez de un <code>or</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Insertar-o">5.2.4 El <code>or</code> en el cuerpo</a></td><td> </td><td align="left" valign="top"> Cómo la expresión <code>or</code> funciona. -</td></tr> -<tr><td align="left" valign="top"><a href="#Insertar-let">5.2.5 La expresión <code>let</code> en <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Dos expresiones <code>save-excursion</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Nuevo-insert_002dbuffer">5.2.6 Nuevo cuerpo para <code>insert-buffer</code></a></td><td> </td><td align="left" valign="top"> Nuevo insert-buffer -</td></tr> -</table> - -<hr> -<a name="c_00f3digo-insert_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer-interactivo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-codigo-para-insert_002dbuffer"></a> -<h3 class="unnumberedsubsec">El código para <code>insert-buffer</code></h3> - -<p>Aquí está el primer código -</p> -<div class="smallexample"> -<pre class="smallexample">(defun insert-buffer (buffer) - "Inserta después del punto los contenidos del BUFFER. -Pon la marca después del texto insertado. -El BUFFER puede ser un buffer un nombre de buffer." - (interactive "*bInsert buffer: ") -</pre><pre class="smallexample"> (or (bufferp buffer) - (setq buffer (get-buffer buffer))) - (let (start end newmark) - (save-excursion - (save-excursion - (set-buffer buffer) - (setq start (point-min) end (point-max))) -</pre><pre class="smallexample"> (insert-buffer-substring buffer start end) - (setq newmark (point))) - (push-mark newmark))) -</pre></div> - -<p>Como con otras definiciones de función, se puede usar una plantilla -para visión de la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun insert-buffer (buffer) - "<var>documentation</var>…" - (interactive "*bInsert buffer: ") - <var>body</var>…) -</pre></div> - -<hr> -<a name="insert_002dbuffer-interactivo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#c_00f3digo-insert_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#B_00faffer-solo-lectura" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-expresion-interactiva-en-insert_002dbuffer"></a> -<h3 class="subsection">5.2.1 La expresión interactiva en <code>insert-buffer</code></h3> -<a name="index-interactive_002c-ejemplo-de-uso"></a> - -<p>En <code>insert-buffer</code>, el argumetno para la declaración -<code>interactive</code> tiene dos partes, un asterisco, ‘<samp>*</samp>’, y -‘<samp>bInserta un buffer: </samp>’. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#B_00faffer-solo-lectura">Un búffer de solo lectura</a></td><td> </td><td align="left" valign="top"> Cuando un buffer no puede ser modificado. -</td></tr> -<tr><td align="left" valign="top"><a href="#b-para-interactivo">‘<samp>b</samp>’ en una expresión interactiva</a></td><td> </td><td align="left" valign="top"> Un buffer existe o además su nombre. -</td></tr> -</table> - -<hr> -<a name="B_00faffer-solo-lectura"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer-interactivo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer-interactivo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#b-para-interactivo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-buffer-de-solo-lectura"></a> -<h4 class="unnumberedsubsubsec">Un búffer de solo lectura</h4> -<a name="index-Buffer-solo-lectura"></a> -<a name="index-Asterisco-para-buffer-de-solo-lectura"></a> -<a name="index-_002a-para-buffer-solo-lectura"></a> - -<p>El asterisco se utliza en la situación cuando el búffer actual es un -búffer de solo lectura — un búffer que no puede ser modificado. Si -<code>insert-buffer</code> es llamado cuando el búffer actual es de solo -lectura, un mensaje a este efecto está impreso en el área echo y -el terminal puede avisar; no se permite insertar cualquier cosa dentro -del búffer. El asterisco no necesita ser seguido por una nueva -línea para separarse desde el siguiente argumento. -</p> -<hr> -<a name="b-para-interactivo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#B_00faffer-solo-lectura" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer-interactivo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-insert_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="b-en-una-expresion-interactiva"></a> -<h4 class="unnumberedsubsubsec">‘<samp>b</samp>’ en una expresión interactiva</h4> - -<p>El siguiente argumento en la expresión interactiva empieza con una -tecla minúscula ‘<samp>b</samp>’. (Esto es diferente desde el código para -<code>append-to-buffer</code>, que usa una mayúscula -‘<samp>B</samp>’. Véase la sección <a href="#append_002dto_002dbuffer">La Definición de <code>append-to-buffer</code></a>.) La tecla minúscula cuenta al intérprete -Lisp que el argumento para <code>insert-buffer</code> sería un -buffer existente o sino su nombre. (La mayúscula ‘<samp>B</samp>’ provee -para la posibilidad que el búffer no existe.) Emacs te mostrará en -pantalla el nombre del búffer, ofreciendo un búffer por defecto, -con la compleción de nombre habilitado. Si el búffer no existe, se -recibe un mensaje que dice “No concuerda”; tu terminal te avisa también. -</p> -<p>El nuevo y simplificado código genera una lista -<code>interactive</code>. Eso usa las funciones -<code>barf-if-buffer-read-only</code> y <code>read-buffer</code> con las que -estamos ya familiarizados y la forma especial <code>progn</code> con los que -no. (Eso será descrito después). -</p> -<hr> -<a name="cuerpo-insert_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#b-para-interactivo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#si-y-o" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-cuerpo-de-la-funcion-insert_002dbuffer"></a> -<h3 class="subsection">5.2.2 El cuerpo de la función <code>insert-buffer</code></h3> - -<p>El cuerpo de la función <code>insert-buffer</code> tiene dos partes -principales: una expresión <code>or</code> y una expresión -<code>let</code>. El propósito de la expresión <code>or</code> es asegurar que -el argumento <code>buffer</code> es emparejado a un búffer y no solo el -nombre de un búffer. El cuerpo de la expresión <code>let</code> contiene -el código que copia los otros búffers dentro del búffer. -</p> -<p>En el "outline" (esquema), las dos expresiones se ajustan dentro de la -función <code>insert-buffer</code> como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun insert-buffer (buffer) - "<var>documentation</var>…" - (interactive "*bInsertar buffer: ") - (or … - … -</pre><pre class="smallexample"> (let (<var>varlist</var>) - <var>body-of-</var><code>let</code>… ) -</pre></div> - -<p>Para comprender como la expresión <code>or</code> asegura que el argumento -<code>buffer</code> es emparejado a un buffer y no al nombre de un búffer, -es primero necesario comprender la función <code>or</code>. -</p> -<p>Antes de hacer esto, permíteme reescribir esta parte de -la función usando <code>if</code> así puedes ver que es -hecho en una manera que será familiar. -</p> -<hr> -<a name="si-y-o"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-insert_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Insertar-o" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="insert_002dbuffer-con-un-if-en-vez-de-un-or"></a> -<h3 class="subsection">5.2.3 <code>insert-buffer</code> con un <code>if</code> en vez de un <code>or</code></h3> - -<p>El trabajo que debe ser hecho y asegura el valor de <code>buffer</code> es -un búffer en sí mismo y no el nombre de un búffer. Si -el valor es el nombre, entonces el búffer en sí debe ser -obtenido. -</p> -<p>Te puedes imaginar a tí mismo en una conferencia donde -un acomodador está observando una lista con tu nombre dentro y -mirándote: el acomodador sabe “asociar” tu nombre, pero no a -tí; pero cuando el acomodador te encuentra y te toma el -brazo, el acomodador llega a “asociarte” a tí. -</p> -<p>En Lisp, se podría describir esta situación -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (not (holding-on-to-guest)) - (find-and-take-arm-of-guest)) -</pre></div> - -<p>Se quiere hacer la misma cosa con un búffer — si no tenemos el -búffer en sí, queremos tenerlo. -</p> -<p>Usando un predicado llamado <code>bufferp</code> que nos cuenta si tenemos -un búffer (en vez de su nombre), se puede escribir el código como -este: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (not (bufferp buffer)) ; <span class="roman">if-part</span> - (setq buffer (get-buffer buffer))) ; <span class="roman">then-part</span> -</pre></div> - -<p>Aquí, el true-or-false-test de la expresión <code>if</code> -es <code>(not (bufferp buffer))</code>; y la then-part es la expresión -<code>(setq buffer <span class="nolinebreak">(get-buffer</span> buffer))</code>. -</p> -<p>En el test, la función <code>bufferp</code> devuelve cierto si su -argumento es un búffer — pero falso si su argumento es el nombre del -búffer. (El último carácter del nombre de la función -<code>bufferp</code> es el carácter ‘<samp>p</samp>’; como se vió antes, tal uso de -‘<samp>p</samp>’ es una convención que indica que la función es un -predicado, que es un término que significa que la función -determinará si alguna propiedad es verdadera o falsa. Véase la sección <a href="#Tipo-incorrecto-de-argumento">Usando el objeto de tipo incorrecto como un argumento</a>.) -</p> -<p>La función <code>not</code> precede la expresión <code>(bufferp -buffer)</code>, así el true-or-false-test se ve como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(not (bufferp buffer)) -</pre></div> - -<p><code>no</code> es una función que devuelve cierto si su argumento es falso -y falso si su argumento es verdadero. Así si -<code>(bufferp buffer)</code> devuelve cierto, la expresión <code>no</code> -devuelve falso y vice-versa: que es “no cierto” es falso que es “no -falso” es verdadero. -</p> -<p>Usando este test, la expresión <code>if</code> trabaja como sigue: cuando -el valor de la variable <code>buffer</code> está actualmente en un -búffer en vez de su nombre, el test true-or-false-test devuelve -false y la expresión <code>if</code> no evalúa la parte then-part. Esto -está bien, desde que no necesita para hacer cualquier cosa para la -variable <code>buffer</code> si es realmente un búffer. -</p> -<p>Por otro lado, cuando el valor de <code>buffer</code> no es un buffer en -sí, pero el nombre de un buffer, el true-or-false-test -devuelve cierto y la then-part de la expresión es evaluada. En este -caso, la then-part es <code>(setq buffer (get-buffer buffer))</code>. Esta -expresión usa la función <code>get-buffer</code> para devolver un buffer -actual en sí, dado su nombre. El <code>setq</code> entonces -asigna la variable <code>buffer</code> al valor del buffer en -sí, reemplazando su valor previo (que era el nombre del -buffer). -</p> -<hr> -<a name="Insertar-o"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#si-y-o" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Insertar-let" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-or-en-el-cuerpo"></a> -<h3 class="subsection">5.2.4 El <code>or</code> en el cuerpo</h3> - -<p>El propósito de la expresión <code>or</code> en la función -<code>insert-buffer</code> es asegurar que el argumento <code>buffer</code> está -asociado a un búffer y no solo al nombre de un búffer. La sección -previa muestra como el trabajo podría haber sido hecho -usando una expresión <code>if</code>. Sin embargo, la función -<code>insert-buffer</code> actualmente usa <code>or</code>. Para comprender esto, -es necesario comprender como <code>or</code> trabaja. -</p> -<a name="index-or"></a> -<p>Una función <code>or</code> puede tener cualquier número de -argumentos. Eso evalúa cada argumento en turno y devuelve el valor -del primero de sus argumentos que no es <code>nil</code>. También, y esto -es una funcionalidad crucial de <code>or</code>, eso no evalúa cualquier -argumentos subsiguientes después devolviendo el primer valor -no-<code>nil</code>. -</p> -<p>La expresión <code>or</code> se ve como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(or (bufferp buffer) - (setq buffer (get-buffer buffer))) -</pre></div> - -<p>El primer argumento a <code>or</code> es la expresión <code>(bufferp -buffer)</code>. Esta expresión devuelve cierto (un valor no-<code>nil</code>) si -el búffer es actualmente un búffer, y no solo el nombre de un -búffer. En la expresión <code>or</code>, si este es el caso, la -expresión <code>or</code> devuelve esto el valor cierto y no evalúa la -siguiente expresión — y esto es bueno para nosotros, desde que -nosotros no queremos hacer cualquier cosa al valor de <code>buffer</code> si -eso es realmente un búffer. -</p> -<p>Por otro lado, si el valor de <code>(bufferp buffer)</code> es <code>nil</code>, -que será si el valor de <code>buffer</code> es el nombre de un buffer, el -intérprete Lisp evalúa el siguiente elemento de la -expresión. Esta es la expresión <code>(setq buffer (get-buffer -buffer))</code>. Esta expresión devuelve un valor no-<code>nil</code>, que es el -valor para el que asigna la variable <code>buffer</code> — y este valor es -un búffer en sí, no el nombre de un búffer. -</p> -<p>El resultado de todo esto es que el símbolo -<code>buffer</code> es siempre asociado a un búffer en sí en -vez del nombre de un búffer. Toda es necesario porque la función -<code>set-buffer</code> en una línea siguiente trabaja con un -buffer en sí, no con el nombre de un búffer. -</p> -<p>Incidentalmente, usando <code>or</code>, la situación con el acomodador se -vería así: -</p> -<div class="smallexample"> -<pre class="smallexample">(or (holding-on-to-guest) (find-and-take-arm-of-guest)) -</pre></div> - -<hr> -<a name="Insertar-let"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Insertar-o" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Nuevo-insert_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-expresion-let-en-insert_002dbuffer"></a> -<h3 class="subsection">5.2.5 La expresión <code>let</code> en <code>insert-buffer</code></h3> - -<p>Después asegurando que la variable <code>buffer</code> se refiere a un -buffer en sí y no solo al nombre de un buffer, la -función <code>insert-buffer</code> continúa con una expresión -<code>let</code>. Esto especifica tres variables locales, <code>start</code>, -<code>end</code> y <code>newmark</code> y los asocia al valor inicial -<code>nil</code>. Estas variables son usadas dentro del resto de <code>let</code> -y temporalmente se oculta con cualquier otra ocurrencia de variables -del mismo nombre en Emacs hasta el fin del <code>let</code>. -</p> -<p>El cuerpo del <code>let</code> contiene dos expresiones -<code>save-excursion</code>. Primero, miraremos la expresión -<code>save-excursion</code> en detalle. La expresión se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(save-excursion - (set-buffer buffer) - (setq start (point-min) end (point-max))) -</pre></div> - -<p>La expresión <code>(set-buffer buffer)</code> cambia la atención de -Emacs desde el búffer actual a uno desde el que el texto será -copiado. En este búffer las variables <code>start</code> y <code>end</code> se -asignadan al principio y al fin del búffer, usando los comandos -<code>point-min</code> y <code>point-max</code>. Note que tenemos -aquí una ilustración de cómo <code>setq</code> es capaz de -asignar dos variables en la misma expresión. El primer argumento de -<code>setq</code> es asignar al valor del segundo, y su tercer argumento -está asignado al valor del cuarto. -</p> -<p>Después el cuerpo del <code>save-excursion</code> propio es evaluado, el -<code>save-excursion</code> restaura el búffer original, pero <code>start</code> -y <code>end</code> permanece asignado a los valores del principio y fin del -búffer en el que el texto será copiado. -</p> -<p>La expresión por fuera <code>save-excursion</code> se ve como: -</p> -<div class="smallexample"> -<pre class="smallexample">(save-excursion - (<var>inner-</var><code>save-excursion</code><var>-expression</var> - (<var>go-to-new-buffer-and-set-</var><code>start</code><var>-and-</var><code>end</code>) - (insert-buffer-substring buffer start end) - (setq newmark (point))) -</pre></div> - -<p>La función <code>insert-buffer-substring</code> copia el texto -<em>dento</em> del búffer <em>desde</em> la región indicada por -<code>start</code> y <code>end</code> en el <code>búffer</code>. Desde el total del -segundo búffer cae entre <code>start</code> y <code>end</code>, el todo del -segundo búffer es copiado dentro del búffer que estás -editando. Lo siguiente, el valor del punto, que será al fin del -texto insertado, es grabado en la variable <code>newmark</code>. -</p> -<p>Después el cuerpo de <code>save-excursion</code> es evaluado, punto y -marca son recolocados a sus lugares originales. -</p> -<p>Sin embargo, es conveniente localizar una marca al fin del texto -nuevamente insertado y localizar el punto al principio. La variable -<code>newmark</code> graba el fin del texto insertado. En la última -línea de la expresión <code>let</code>, la expresión de la -función <code>(push-mark newmark)</code> asigna una marca a esta -posición. (La posición previa de la marca está -todavía accesible; está grabado en la marca del anillo -y se puede regresar a eso con <kbd>C-u C-<SPC></kbd>.) Mientras tanto, -el punto está localizado al principio del texto insertado, que -está donde estaba antes de ser llamado la función que inserta, la -posición de lo que estaba guardado por la primera <code>save-excursion</code>. -</p> -<p>La expresión <code>let</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(let (start end newmark) - (save-excursion - (save-excursion - (set-buffer buffer) - (setq start (point-min) end (point-max))) - (insert-buffer-substring buffer start end) - (setq newmark (point))) - (push-mark newmark)) -</pre></div> - -<p>Como la función <code>append-to-buffer</code>, la función -<code>insert-buffer</code> usa <code>let</code>, <code>save-excursion</code> y -<code>set-buffer</code>. Además, la función ilustra un camino para usar -<code>o</code>. Toda estas funciones están construyendo el bloque que -se encontrarán y usarán una y otra vez. -</p> -<hr> -<a name="Nuevo-insert_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Insertar-let" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#insert_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Nuevo-cuerpo-para-insert_002dbuffer"></a> -<h3 class="subsection">5.2.6 Nuevo cuerpo para <code>insert-buffer</code></h3> -<a name="index-insert_002dbuffer_002c-nueva-version-del-cuerpo"></a> -<a name="index-nueva-version-cuerpo-para-insert_002dbuffer"></a> - -<p>El cuerpo en la versión de GNU Emacs 22 es más confuso que en el -original. -</p> -<p>Consiste de dos expresiones -</p> -<div class="smallexample"> -<pre class="smallexample"> (push-mark - (save-excursion - (insert-buffer-substring (get-buffer buffer)) - (point))) - - nil -</pre></div> - -<p>excepto, y esto es lo que los novicios confunden, un trabajo muy -importante es hecho dentro de la expresión <code>push-mark</code>. -</p> -<p>La función <code>get-buffer</code> devuelve un búffer con el nombre -proporcionado. Se tomará nota de que la función <em>no</em> se -llama <code>get-buffer-create</code>; eso no crea un búffer si uno no -existe ya. El búffer devuelto por <code>get-buffer</code>, un búffer -existente, es pasado a <code>insert-buffer-substring</code>, que inserta el -total del búffer (desde que no se especificón ninguna cosa -más). -</p> -<p>La posición dentro del buffer es insertado es grabado por -<code>push-mark</code>. Entonces la función devuelve <code>nil</code>, el valor -de su último comando. Pon otro camino, la función -<code>insert-buffer</code> existe solo para producir un efecto lateral, -insertando otro buffer, no para devolver cualquier valor. -</p> -<hr> -<a name="beginning_002dof_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Nuevo-insert_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos-opcionales" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Definicion-completa-de-beginning_002dof_002dbuffer"></a> -<h2 class="section">5.3 Definición completa de <code>beginning-of-buffer</code></h2> -<a name="index-beginning_002dof_002dbuffer"></a> - -<p>La estructura básica de la función <code>beginning-of-buffer</code> ya -ha sido discutida. (Véase la sección <a href="#simplified_002dbeginning_002dof_002dbuffer">Una Definición Simplificada <code>beginning-of-buffer</code></a>). Esta sección -describe la parte compleja de la definición. -</p> -<p>Como se describe previamente, cuando se invoca sin un argumento, -<code>beginning-of-buffer</code> mueve el cursor al principio del búffer -(en realidad, al principio de la porción accesible del búffer), -dejando la marca en la posición previa. Sin embargo, cuando el -comando es invocado con un número entre uno y diez, la función -considera que número será una fracción del tamaño del -búffer, medido en decenas, y Emacs mueve el cursor en esta -fracción del camino desde el principio del búffer. De este modo, -se puede o bien llamar a esta función con la tecla comando <kbd>M-<</kbd>, -que moverá el cursor al principio del búffer, o con una tecla tal -como <kbd>C-u 7 M-<</kbd> que moverá el cursor a un punto 70% del camino -a través del búffer. Si un número más grande de diez es usado -para el argumento que se mueve al final del búffer. -</p> -<p>La función <code>beginning-of-buffer</code> puede ser llamada con o sin -argumentos. El uso del argumento es opcional. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Argumentos-opcionales">5.3.1 Argumentos opcionales</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#beginning_002dof_002dbuffer-opt-arg">5.3.2 <code>beginning-of-buffer</code> con un argumento</a></td><td> </td><td align="left" valign="top"> Ejemplo con argumento opcional. -</td></tr> -<tr><td align="left" valign="top"><a href="#Completo-beginning_002dof_002dbuffer">5.3.3 El <code>beginning-of-buffer</code> completo</a></td><td> </td><td align="left" valign="top"> Completo beginning-of-buffer -</td></tr> -</table> - -<hr> -<a name="Argumentos-opcionales"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer-opt-arg" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Argumentos-opcionales-1"></a> -<h3 class="subsection">5.3.1 Argumentos opcionales</h3> - -<p>A menos que se cuente de otro modo, Lisp espera que una función con -un argumento en su definición de función se llame con un valor -para este argumento. Si esto no ocurre, se obtiene un error y un -mensaje que dice ‘<samp>Número de argumentos erróneo</samp>’. -</p> -<a name="index-Argumentos-Opcionales"></a> -<a name="index-Palabra-Clave"></a> -<a name="index-opcional"></a> -<p>Sin embargo, los argumentos opcionales son una funcionalidad de Lisp: -una <em>palabra clave</em> particular es usada para contar al -intérprete Lisp que un argumento es opcional. La palabra clave es -<code>&optional</code>. (El ‘<samp>&</samp>’ en frente de ‘<samp>opcional</samp>’ es parte -de la palabra clave.) En una definición de función, si un -argumento sigue a la palabra clave <code>&optional</code>, ningún valor -necesita ser pasado a este argumento cuando la función se llama. -</p> -<p>La primera línea de la definición de función de -<code>beginning-of-buffer</code> tiene lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun beginning-of-buffer (&optional arg) -</pre></div> - -<p>En el "outline" (esquema), la función completa se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun beginning-of-buffer (&optional arg) - "<var>documentation</var>…" - (interactive "P") - (or (<var>is-the-argument-a-cons-cell</var> arg) - (and <var>are-both-transient-mark-mode-and-mark-active-true</var>) - (push-mark)) - (let (<var>determine-size-and-set-it</var>) - (goto-char - (<var>if-there-is-an-argument</var> - <var>figure-out-where-to-go</var> - <var>else-go-to</var> - (point-min)))) - <var>do-nicety</var> -</pre></div> - -<p>La función es similar a la función -<code>simplified-beginning-of-buffer</code> excepto que la expresión -<code>interactive</code> tiene <code>"P"</code> como un argumento y la función -<code>goto-char</code> es seguida por una expresión if-then-else que -figura donde poner el cursor si hay un argumento que no es un cons cell. -</p> -<p>(Puesto que no se explica un cons cell en muchos -capítulos, por favor, considere ignorar la función -<code>consp</code>. <a href="#Implementaci_00f3n-de-listas">Cómo las Listas son Implementadas</a>, y <a href="elisp.html#Tipo-de-Cons-Cell">Cons Cell y Tipos de Listas</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>). -</p> -<p>El <code>"P"</code> en la expresión <code>interactive</code> cuenta a Emacs -cómo pasar un argumento prefijo, si hay uno, a la función en forma -plana. Un argumento prefijo se crea escribiendo la tecla <META> -seguida por un número, o escribiendo <kbd>C-u</kbd> y entonces un -número. (Si no escribes un número, <kbd>C-u</kbd> por defecto a un cons -cell con un 4. Una minúscula <code>"p"</code> en la expresión -<code>interactive</code> causa a la función convertir un argumento prefijo -a un número.) -</p> -<p>El true-or-false-test de la expresión <code>if</code> se ve compleja, pero -no lo es: se chequea si <code>arg</code> tiene un valor que no es <code>nil</code> -y si es un cons cell. (Esto es lo que <code>consp</code> hace; chequea si su -argumento es un cons cell.) Si <code>arg</code> tiene un valor que no es -<code>nil</code> (y no es un cons cell.), que será el caso si -<code>beginning-of-buffer</code> se llama con un argumento, entonces este -true-or-false-test devolverá cierto y la then-part de la expresión -<code>if</code> falsa. Por otro lado, si <code>beginning-of-bufer</code> no se -llama con un argumento, el valor de <code>arg</code> será <code>nil</code> y la -else-part de la expresión <code>if</code> se evaluará. La else-part es -simple <code>point-min</code>, y esto es lo de fuera, la expresión -<code>goto-char</code> es <code>(goto-char (point-min))</code>, que es cómo se -vió la función <code>beginning-of-buffer</code> en su forma -simplificada. -</p> -<hr> -<a name="beginning_002dof_002dbuffer-opt-arg"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Argumentos-opcionales" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Desenmara_00f1ar-beginning_002dof_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="beginning_002dof_002dbuffer-con-un-argumento"></a> -<h3 class="subsection">5.3.2 <code>beginning-of-buffer</code> con un argumento</h3> - -<p>Cuando <code>beginning-of-buffer</code> se llama con un argumento, una -expresión es evaluada que calcula que valor pasa a -<code>goto-char</code>. Esto es incluso complicado a primera vista. Eso -incluye una expresión <code>if</code> propia y mucha aritmética. Se ve -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (> (buffer-size) 10000) - ;; <span class="roman">¡Evitar sobrecarga para grandes tamaños de búffer!</span> - (* (prefix-numeric-value arg) - (/ size 10)) - (/ - (+ 10 - (* - size (prefix-numeric-value arg))) 10))) -</pre></div> - -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Desenmara_00f1ar-beginning_002dof_002dbuffer">Desenmarañar <code>beginning-of-buffer</code></a></td><td> </td><td align="left" valign="top"> Desenmarañar beginning-of-buffer -</td></tr> -<tr><td align="left" valign="top"><a href="#El-caso-del-buffer-largo">Qué ocurre en un búffer largo</a></td><td> </td><td align="left" valign="top"> El caso del buffer largo -</td></tr> -<tr><td align="left" valign="top"><a href="#Peque_00f1o-caso-de-b_00faffer">Qué ocurre en un búffer pequeño</a></td><td> </td><td align="left" valign="top"> Pequeño caso de búffer -</td></tr> -</table> - -<hr> -<a name="Desenmara_00f1ar-beginning_002dof_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer-opt-arg" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer-opt-arg" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#El-caso-del-buffer-largo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Desenmaranar-beginning_002dof_002dbuffer"></a> -<h4 class="unnumberedsubsubsec">Desenmarañar <code>beginning-of-buffer</code></h4> - -<p>Como otras expresiones que se ven complejas, la expresión -condicional con <code>beginning-of-buffer</code> puede ser desenredada -mirándola por partes de una plantilla, en este caso, la plantilla -par una expresión if-then-else. En forma esquelética, la -expresión se ve así: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (<var>buffer-is-large</var> - <var>divide-buffer-size-by-10-and-multiply-by-arg</var> - <var>else-use-alternate-calculation</var> -</pre></div> - -<p>El true-or-fase-test de esta expresión <code>if</code> propia chequea el -tamaño del buffer. La razón para esto es que la versión vieja de -Emacs 18 usaba números que no son más grandes que 8 millones o -así y en la computación que seguía, el -programador temía que Emacs podría -intentar usar a través de largos números si el búffer fuera -largo. El término ‘sobrecarga’, que se mencionó en el comentario, -significa que los números son grandes. Las versiones más recientes -de Emacs usan números largos, pero este código no ha sido tocado, -solo porque la gente ahora mira en búffers que están lejos, tan -lejos como antes. -</p> -<p>Hay dos casos: si el búffer es largo, o si no. -</p> -<hr> -<a name="El-caso-del-buffer-largo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Desenmara_00f1ar-beginning_002dof_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer-opt-arg" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Peque_00f1o-caso-de-b_00faffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Que-ocurre-en-un-buffer-largo"></a> -<h4 class="unnumberedsubsubsec">Qué ocurre en un búffer largo</h4> - -<p>En <code>beginning-of-buffer</code>, la expresión propia <code>if</code> chequea -si el tamaño del búffer es mayor que 10000 caracteres. Para hacer -esto, se usa la función <code>></code> y la computación de <code>size</code> -que viene desde la expresión let. -</p> -<p>Hace tiempo, se usaba la función <code>buffer-size</code>. No solo esta -función era llamada varias veces, eso daba el tamaño del búffer -completo, no la parte accesible. La computación tiene mucho más -sentido cuando se maneja solo la parte accesible. (Véase la sección <a href="#Encogiendo-y-extendiendo">Encogiendo y extendiendo</a>, para más información en -focalizar la atención para una parte ‘accesible’.) -</p> -<p>La línea se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (> size 10000) -</pre></div> - -<p>Cuando el búffer es largo, el then-part de la expresión <code>if</code> -se evalúa. Eso se lee así (después de ser formateado -para una fácil lectura): -</p> -<div class="smallexample"> -<pre class="smallexample">(* - (prefix-numeric-value arg) - (/ size 10)) -</pre></div> - -<p>Esta expresión es una multiplicación, con dos argumentos para la -función <code>*</code>. -</p> -<p>El primer argumento es <code>(prefix-numeric-value arg)</code>. Cuando -<code>"P"</code> se usa como argumento para <code>interactive</code>, el valor -pasado para la función como argumento es un “argumento prefijo -crudo”, y no un número. (Es un número en una lista). Para -desarrollar la aritmética, una conversión es necesaria, y -<code>prefix-numeric-value</code> hace el trabajo. -</p> -<a name="index-_002f-_0028division_0029"></a> -<a name="index-Division"></a> -<p>El segundo argumento es <code>(/ size 10)</code>. Esta expresión divide el -valor numérico por diez — el valor numérico del tamaño de la -porción accesible del búffer. Esto produce un número que cuenta -cuántos caracteres crean una decena del tamaño del búffer. (En Lisp, -<code>/</code> es usado para división, solo como <code>*</code> es usado para -multiplicación.) -</p> -<p>En la expresión de la multiplicación como un todo, esta cantidad -se multiplica por el valor del argumento prefijo — la -multiplicación se parece a: -</p> -<div class="smallexample"> -<pre class="smallexample">(* <var>numeric-value-of-prefix-arg</var> - <var>number-of-characters-in-one-tenth-of-the-accessible-buffer</var>) -</pre></div> - -<p>Si, por ejemplo, el argumento prefijo es ‘<samp>7</samp>’, el valor one-tenth -será multiplicado por 7 para dar una posición del 70% del camino. -</p> -<p>El resultado de todo esto es que si la porción accesible del búffer -es largo, la expresión <code>goto-char</code> se lee esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(goto-char (* (prefix-numeric-value arg) - (/ size 10))) -</pre></div> - -<p>Esto pone el cursor donde se quiere. -</p> -<hr> -<a name="Peque_00f1o-caso-de-b_00faffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#El-caso-del-buffer-largo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer-opt-arg" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Completo-beginning_002dof_002dbuffer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Que-ocurre-en-un-buffer-pequeno"></a> -<h4 class="unnumberedsubsubsec">Qué ocurre en un búffer pequeño</h4> - -<p>Si el búffer contiene poco más de 10000 caracteres, una -computación ligeramente diferente es medida. Se podría -pensar que esto no es necesario, desde que la primera computación -podría hacer el trabajo. Sin embargo, en un búffer -pequeño, el primer método puede no poner el cursor en la -línea exactamente deseada; el segundo método hace un -trabajo mejor. -</p> -<p>El código se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(/ (+ 10 (* size (prefix-numeric-value arg))) 10)) -</pre></div> - -<p>Este es el código en el que se ve qué ocurre descubriendo como las -funciones se embeben entre paréntesis. Eso es fácil de leer si se -reformatea con cada expresión indentada más profundamente que la -expresión que encierra: -</p> -<div class="smallexample"> -<pre class="smallexample"> (/ - (+ 10 - (* - size - (prefix-numeric-value arg))) - 10)) -</pre></div> - -<p>Mirando los paréntesis, se ve que la operación propia es -<code>(prefix-numeric-value arg)</code>, que convierte el argumento plano -para un número. En la siguiente expresión, este número es -multiplicado por el tamaño de la porción accesible del búffer: -</p> -<div class="smallexample"> -<pre class="smallexample">(* size (prefix-numeric-value arg)) -</pre></div> - -<p>Esta multiplicación crea un número que puede ser más largo que -el tamaño del buffer — siete veces más larga si el argumento es -7, por ejemplo. Diez se aãnade a éste nũmero y finalmente el -número es dividido por 10 para proporcionar un valor que es un -carácter más largo que la posición de porcentaje en el búffer. -</p> -<p>El número que resulta de todo esto se pasa a <code>goto-char</code> y -el cursor se mueve a este punto. -</p> -<hr> -<a name="Completo-beginning_002dof_002dbuffer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Peque_00f1o-caso-de-b_00faffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#beginning_002dof_002dbuffer" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Revisar-el-segundo-b_00faffer-relacionado" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-beginning_002dof_002dbuffer-completo"></a> -<h3 class="subsection">5.3.3 El <code>beginning-of-buffer</code> completo</h3> - -<p>Aquí está el texto completo de la función -<code>beginning-of-buffer</code>: -</p><br> - -<div class="smallexample"> -<pre class="smallexample">(defun beginning-of-buffer (&optional arg) - "Mueve el punto al principio del buffer; -deja marca en la posición previa. -Con prefijo \\[universal-argument], -no se asigna una marca en la posición previa. -Con el argumento numérico N, pon el -punto N/10 del camino desde el principio. - -Si el búffer está encogido -este comando usa el principio y tamaño -de la parte accesible del búffer. -</pre><pre class="smallexample"> -</pre><pre class="smallexample">¡No use este comando en programas Lisp! -\(goto-char (point-min)) es rápido -y evita poseer la marca." - (interactive "P") - (or (consp arg) - (and transient-mark-mode mark-active) - (push-mark)) -</pre><pre class="smallexample"> (let ((size (- (point-max) (point-min)))) - (goto-char (if (and arg (not (consp arg))) - (+ (point-min) - (if (> size 10000) - ;; ¡Evita sobrecarga para grandes tamaños de búffer! - (* (prefix-numeric-value arg) - (/ size 10)) - (/ (+ 10 (* size (prefix-numeric-value arg))) - 10))) - (point-min)))) - (if arg (forward-line 1))) -</pre></div> - - -<p>Excepto por dos pequeños puntos, la discusión previa muestra -cómo esta función trabaja. El primer punto trata un detalle en la -cadena de documentación, y el segundo concierne la última -línea de la función. -</p> -<p>En la cadena de documentación, hay referencia a una expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">\\[universal-argument] -</pre></div> - -<p>Un ‘<samp>\\</samp>’ es usado antes de la primera llave de esta -expresión. Este ‘<samp>\\</samp>’ le cuenta al intérprete Lisp sustituir -qué clave está actualmente emparejada a los ‘<samp>[…]</samp>’. En el -caso de <code>universal-argument</code>, que es normalmente <kbd>C-u</kbd>, pero -eso podría ser diferente. (See <a href="elisp.html#Consejos-de-Documentaci_00f3n">Consejos para Cadenas de Documentación</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, para más información.) -</p> -<p>Finalmente, la última línea del comando -<code>beginning-of-buffer</code> dice mover el punto al principio de la -siguiente línea si el comando es invocado con un argumento: -</p> -<div class="smallexample"> -<pre class="smallexample">(if arg (forward-line 1))) -</pre></div> - -<p>Esto pone el cursor al principio de la primera línea -después de las apropiadas decenas de posiciones en el búffer. Esto -significa que el cursor está siempre localizado <em>al menos</em> las -decenas solicitadas del camino a través del búffer, que es un bien -que es, quizás, no necesario, pero que, si no ocurrió, -estaría seguro de dibujar rumores. -</p> -<p>Por otro lado, eso significa que si se especifica el comando con un -<kbd>C-u</kbd>, sin un número, que es decir, si el ‘prefijo de argumento -plano’ es simplemente un cons cell, entonces el comando te pone al -principio de la segunda línea … no sé si este se -pretende ningún trato con el código para evitar que esto ocurre. -</p> -<hr> -<a name="Revisar-el-segundo-b_00faffer-relacionado"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Completo-beginning_002dof_002dbuffer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-opcional" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Revisar-1"></a> -<h2 class="section">5.4 Revisar</h2> - -<p>Aquí hay un breve resumen de los asuntos cubierto en -este capítulo. -</p> -<dl compact="compact"> -<dt><code>or</code></dt> -<dd><p>Evalúa cada argumento en secuencia, y devuelve el valor del primer -argumento que no es <code>nil</code>, si ninguno devuelve un valor que no es -<code>nil</code>, devuelve <code>nil</code>. En breve, devuelve el primer valor de -verdad de los argumento; devuelve un valor cierto si un <em>or</em> -cualquier de los otros son verdad. -</p> -</dd> -<dt><code>and</code></dt> -<dd><p>Evalúa cada argumento en secuencia, y si cualquiera es <code>nil</code>, -devuelve <code>nil</code>; si ninguno es <code>nil</code>, devuelve el valor del -último argumento. En breve, devuelve un valor cierto solo si todos -los argumentos cierto; devuelve un valor cierto si un <em>and</em> cada -uno de los otros son ciertos. -</p> -</dd> -<dt><code>&optional</code></dt> -<dd><p>Una palabra clave usaba para indicar que un argumento a una -definición de función es opcional; esto significa que la función -puede ser evaluado sin el argumento, si se desea. -</p> -</dd> -<dt><code>prefix-numeric-value</code></dt> -<dd><p>Convierte el ‘argumento prefijo plano’ producido por -<code>(interactive "P")</code> a un valor numérico. -</p> -</dd> -<dt><code>forward-line</code></dt> -<dd><p>Mueve el punto hacia delante al principio de la siguiente -línea, o si el argumento es más de uno, hacia delante -varias líneas. Si eso no se puede mover tan lejos -hacia delante como se puede, <code>forward-line</code> va hacia delante tan -lejos como se puede y entonces devuelve un contaje del número de -líneas adicionales que no pudo moverse. -</p> -</dd> -<dt><code>erase-buffer</code></dt> -<dd><p>Borra todos los contenidos del búffer actual. -</p> -</dd> -<dt><code>bufferp</code></dt> -<dd><p>Devuelve <code>t</code> si su argumento es un búffer; de otro modo -devuelve <code>nil</code>. -</p></dd> -</dl> - -<hr> -<a name="Ejercicio-opcional"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Revisar-el-segundo-b_00faffer-relacionado" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio-de-argumento-opcional"></a> -<h2 class="section">5.5 Ejercicio de argumento <code>opcional</code></h2> - -<p>Escribe una función interactiva con un argumento opcional que -chequee si su argumento, un número, es mayor o igual, o al menos, -menos que el valor de <code>fill-column</code>, y lo escribe, en un -mensaje. Sin embargo, si no se pasa un argumento a la función, usa -56 como un valor por defecto. -</p> -<hr> -<a name="Encogiendo-y-extendiendo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#M_00e1s-complejidad" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-opcional" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ventajas-de-encoger" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Encogiendo-y-extendiendo-1"></a> -<h1 class="chapter">6 Encogiendo y extendiendo</h1> -<a name="index-Focalizando-atencion-_0028encogiendo_0029"></a> -<a name="index-Encogiendo"></a> -<a name="index-Ampliando"></a> - -<p>Encoger es una funcionalidad de Emacs que hace posible focalizar en -una parte específica de un búffer, y funcionar sin -cambiar accidentalmente otras partes. Encoger normalmente se -deshabilita puesto que puede confundir a novatos. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Ventajas-de-encoger">Las ventajas de encoger</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#save_002drestriction">6.1 La forma especial <code>save-restriction</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#what_002dline">6.2 <code>what-line</code></a></td><td> </td><td align="left" valign="top"> El número de la línea que - apunta está activa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-narrow">6.3 Ejercicio de encoger</a></td><td> </td><td align="left" valign="top"> Ejercicio narrow -</td></tr> -</table> - -<hr> -<a name="Ventajas-de-encoger"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#save_002drestriction" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Las-ventajas-de-encoger"></a> -<h2 class="unnumberedsec">Las ventajas de encoger</h2> - -<p>Con encoger, el resto del búffer se hace invisible, como si no -estuviera. Esto es una ventaja si, por ejemplo, se quiere reemplazar -una palabra en una parte del búffer pero no otro: se encoge la parte -que se quiere y el reemplazo se trae solo en esta sección, no en -el resto del búffer. Las búsquedas solo funcionarán con una -región encogida, no fuera de una, así si tu estás -arreglando una parte de un documento, se puede guardar en -sí desde encontrar partes accidentalmente que no -necesitas arreglar encongiendo solo la región que quieres. (La tecla -asociada a <code>narrow-to-region</code> es <kbd>C-x n n</kbd>.) -</p> -<p>Sin embargo, encoger hace que el resto del búffer sea invisible, -esto puede asustar a gente quien inadvertidamente invoca a encoger y -pensar que se ha borrado una parte de su fichero. Más allá, el -comando <code>undo</code> (que es normalmente emparejado a <kbd>C-x u</kbd>) no -se deja encoger, así las personas pueden llegar a estar -bastante desesperadas si no conocen que ellas pueden volver al resto -de un búffer para visibilizarlo con el comando <code>widen</code>. (El -emparejamiento de la tecla para <code>widen</code> es <kbd>C-x n w</kbd>.) -</p> -<p>Encoger es tan útil al intérprete Lisp como para las personas. Con -frecuencia, una función Emacs Lisp está diseñada para trabajar -en solo parte de un búffer; o de manera conversa, una función -Emacs Lisp necesita trabajar en todo un búffer que ha sido -encogido. La función <code>what-line</code>, por ejemplo, borra el -encogimiento desde un búffer, si eso tiene cualquier encogimiento y -cuando eso ha finalizado su trabajo, restaura el encogimiento -que haya. Por otro lado, la función <code>count-lines</code>, que es -llamada por <code>what-line</code>, usa el encogimiento para restringirse a -sí misma solo a la porción del búffer en el que -se está interesado y entonces restaura la situación previa. -</p> -<hr> -<a name="save_002drestriction"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ventajas-de-encoger" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#what_002dline" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-forma-especial-save_002drestriction"></a> -<h2 class="section">6.1 La forma especial <code>save-restriction</code></h2> -<a name="index-save_002drestriction"></a> - -<p>En Emacs Lisp, se puede usar la forma especial <code>save-restriction</code> -para guardar la traza siempre que el encogimiento esté en -efecto. Cuando el intérprete Lisp se encuentra con -<code>save-restriction</code>, eso ejecuta el código en el cuerpo de la -expresión <code>save-restriction</code>, y entonces deshace cualquier -cambio para encoger lo que el código causó. Si, por ejemplo, el -búffer está encogido y el código que sigue al comando -<code>save-restriction</code> devuelve el búffer para su región -encogida. En el comando <code>what-line</code>, cualquier encogimiento del -búffer que se puede tener se deshace por el comando <code>widen</code> que -inmediatamente sigue el comando <code>save-restriction</code>. Cualquier -encogimiento original es restaurado solo antes de la compleción de -la función. -</p> -<p>La plantilla para una expresión <code>save-restriction</code> es simple: -</p> -<div class="smallexample"> -<pre class="smallexample">(save-restriction - <var>body</var>… ) -</pre></div> - -<p>El cuerpo del <code>save-restriction</code> es una o más expresiones que -serán evaluadas en secuencia por el intérprete Lisp. -</p> -<p>Finalmente, un punto a anotar: cuando se usa tanto -<code>save-excursion</code> y <code>save-restriction</code>, uno correcto -después del otro, deberías usar <code>save-excursion</code> -fuera. Si se escribe en el orden inverso, se podría -fallar para grabar el encogimiento en el búffer para el que Emacs -cambia después de llamar a <code>save-excursion</code>. De este modo, cuando -se escribe junto a <code>save-excursion</code> y <code>save-restriction</code> -sería escrito así: -</p> -<div class="smallexample"> -<pre class="smallexample">(save-excursion - (save-restriction - <var>body</var>…)) -</pre></div> - -<p>En otras circunstancias, cuando no se escribe junto, las formas -especiales <code>save-excursion</code> y <code>save-restriction</code> deben ser -escritas en el orden apropiado para la función. -</p> -<p>Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample"> (save-restriction - (widen) - (save-excursion - <var>body</var>…)) -</pre></div> - - -<hr> -<a name="what_002dline"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#save_002drestriction" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-narrow" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="what_002dline-1"></a> -<h2 class="section">6.2 <code>what-line</code></h2> -<a name="index-what_002dline"></a> -<a name="index-Extendiendo_002c-ejemplo-de"></a> - -<p>El comando <code>what-line</code> cuenta el número de la -línea en la que el cursor se ha localizado. La -función ilustra el uso de los comandos <code>save-restriction</code> y -<code>save-excursion</code>. Aquí está el texto original de -la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun what-line () - "Imprime el número de línea actual (en el búffer) - del punto." - (interactive) - (save-restriction - (widen) - (save-excursion - (beginning-of-line) - (message "Línea %d" - (1+ (count-lines 1 (point))))))) -</pre></div> - -<p>(En versiones recientes de GNU Emacs, la función <code>what-line</code> se -ha expandido para contar el número de líneas en un -búffer encogido tan bien como el número de líneas en -un búffer ampliado. La versión reciente es más compleja que la -versión que se muestra. Alguien sintiéndose venturoso, -podría querer mirarla después de entender como esta -versión funciona. Probablemente se necesitará usar <kbd>C-h f</kbd> -(<code>describe-function</code>). La versión nueva usa un condicional para -determinar si el búffer se ha encogido. -</p> -<p>(También, eso usa <code>line-number-at-pos</code>, que otras expresiones -simples, tales como <code>(goto-char (point-min))</code>, mueve el punto al -principio de la línea actual con <code>(forward-line 0)</code> -en vez de <code>beginning-of-line</code>.) -</p> -<p>La función <code>what-line</code> como se muestra aquí tiene -una línea de documentación y es interactiva, como se -esperaría. Las dos líneas siguientes usan -las funciones <code>save-restriction</code> y <code>widen</code>. -</p> -<p>La forma especial <code>save-restriction</code> nota que encogiendo es en -efecto, si cualquiera, en el buffer actual y restaura que encogiendo -después del código en el cuerpo del <code>save-restriction</code> ha -sido evaluada. -</p> -<p>La forma especial <code>save-restriction</code> es seguida por -<code>widen</code>. Esta función deshace cualquier distancia del actual -búffer que puede haber tenido cuando <code>what-line</code> se llame. (La -distancia que había es la distancia que -<code>save-restriction</code> recuerda.) Esta ampliación se hace posible -para la línea contando comandos a contar desde el -principio del búffer. De otro modo, se habría -limitado para contar con la región accesible. Cualquier distancia -original se restaura solo antes de la compleción de la función -por la forma especial <code>save-restriction</code>. -</p> -<p>La llamada a <code>widen</code> es seguida por <code>save-excursion</code>, que -guarda la posición del cursor (por ej., el punto) y de la marca, y -la restaura después el código en el cuerpo del -<code>save-excursion</code> usa la función <code>beginning-of-line</code> para -mover el punto. -</p> -<p>(Nótese que la expresión <code>(widen)</code> viene entre las formas -especiales <code>save-restriction</code> y <code>save-excursion</code>. Cuando se -escribe las dos expresiones <code>save- …</code> en secuencia, escribe -<code>save-excursion</code> finalmente.) -</p> -<p>Las últimas dos líneas de la función -<code>what-line</code> son funciones para contar el número de -líneas en el búffer y entonces imprimir el número en -el área echo. -</p> -<div class="smallexample"> -<pre class="smallexample">(message "Line %d" - (1+ (count-lines 1 (point))))))) -</pre></div> - -<p>La función <code>message</code> imprime un mensaje de una -línea abajo de la pantalla Emacs. El primer argumento -está dentro de marcas de cita y está impreso como una cadena de -caracteres. Sin embargo, se puede contener una expresión ‘<samp>%d</samp>’ -para imprimir un argumento siguiente. ‘<samp>%d</samp>’ imprime el argumento -como un decimal, así el mensaje dirá alguna cosa tal -como ‘<samp>Línea 243</samp>’. -</p> -<p>El número que está impreso en lugar de ‘<samp>%d</samp>’ está computada -por la última línea de la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(1+ (count-lines 1 (point))) -</pre></div> - - -<p>Lo que esto hace es contar las líneas entre la primera -posición del búffer indicada por el <code>1</code>, y el -<code>(point)</code>, y entonces se añade uno a este número. (La función -<code>1+</code> añade uno a su argumento.) Se añade a eso porque -la línea 2 tiene solo una línea antes, y -<code>count-lines</code> cuenta solo las líneas <em>antes</em> -de la línea actual. -</p> -<p>Después de que <code>count-lines</code> ha hecho su trabajo, y el mensaje -ha sido impreso en el área echo, la función <code>save-excursion</code> -restaura punto y marca a sus posiciones originales; y -<code>save-restriction</code> restaura la contracción original, si la hay. -</p> -<hr> -<a name="Ejercicio-narrow"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#what_002dline" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio-de-encoger"></a> -<h2 class="section">6.3 Ejercicio de encoger</h2> - -<p>Escribe una función que mostrará los primeros 60 caracteres del -búffer actual, incluso si se ha encogido el búffer a su mitad -así que la primera línea es -inaccesible. Restaura punto, marca y encogimiento. Para este -ejercicio, se necesita usa un popurri entero de funciones, incluyendo -<code>save-restriction</code>, <code>widen</code>, <code>goto-char</code>, -<code>point-min</code>, <code>message</code>, y <code>buffer-substring</code>. -</p> -<a name="index-Propiedades_002c-mencion-de-buffer_002dsubstring_002dno_002dproperties"></a> -<p>(<code>buffer-substring</code> es una función previamente no mencionada -que tendrá que investigarla cada cual por uno mismo; o quizás -tendrá que usarse <code>buffer-substring-no-properties</code> o -<code>filter-buffer-substring</code> …, o todavía otras -funciones. Las propiedades de texto son una funcionalidad que de otro -modo no serían discutidas aquí. -See <a href="elisp.html#Propiedades-de-Texto">Propiedades de Texto</a> in <cite>El Manual de Referencia de Emacs Lisp</cite>.) -</p> -<p>Además, ¿realmente se necesita <code>goto-char</code> o -<code>point-min</code>? -¿O se puede escribir la función sin ellos? -</p> -<hr> -<a name="Car-cdr-y-cons"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Encogiendo-y-extendiendo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-narrow" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Nombres-extra_00f1os" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="car_002c-cdr_002c-cons_003a-Funciones-fundamentales"></a> -<h1 class="chapter">7 <code>car</code>, <code>cdr</code>, <code>cons</code>: Funciones fundamentales</h1> -<a name="index-car_002c-introducido"></a> -<a name="index-cdr_002c-introducido"></a> - -<p>En Lisp, <code>car</code>, <code>cdr</code>, y <code>cons</code> son funciones -fundamentales. La función <code>cons</code> es usada para construir -listas, y las funciones <code>car</code> y <code>cdr</code> son usadas para -tomarlas aparte. -</p> -<p>En el paseo guiado a través de la función -<code>copy-region-as-kill</code>, se verá <code>cons</code> tan bien como dos -variantes de <code>cdr</code>, llamadas <code>setcdr</code> y -<code>nthcdr</code>. (Véase la sección <a href="#copy_002dregion_002das_002dkill"><code>copy-region-as-kill</code></a>.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Nombres-extra_00f1os">Nombres extraños</a></td><td> </td><td align="left" valign="top"> Un lado histórico: ¿por qué - los nombres extraños? -</td></tr> -<tr><td align="left" valign="top"><a href="#car-y-cdr">7.1 <code>car</code> y <code>cdr</code></a></td><td> </td><td align="left" valign="top"> Funciones para extraer parte de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#cons">7.2 <code>cons</code></a></td><td> </td><td align="left" valign="top"> Construyendo una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#nthcdr">7.3 <code>nthcdr</code></a></td><td> </td><td align="left" valign="top"> Llamando <code>cdr</code> repetidamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#nth">7.4 <code>nth</code></a></td><td> </td><td align="left" valign="top"> nth -</td></tr> -<tr><td align="left" valign="top"><a href="#setcar">7.5 <code>setcar</code></a></td><td> </td><td align="left" valign="top"> Cambiando el primer elemento de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#setcdr">7.6 <code>setcdr</code></a></td><td> </td><td align="left" valign="top"> Cambiando el resto de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-cons">7.7 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio cons -</td></tr> -</table> - -<hr> -<a name="Nombres-extra_00f1os"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#car-y-cdr" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Nombres-extranos"></a> -<h2 class="unnumberedsec">Nombres extraños</h2> - -<p>El nombre de la función <code>cons</code> es razonable: es una -abreviación de la palabra ‘constructo’. Los orígenes -de los nombres <code>car</code> y <code>cdr</code>, por otro lado, son -esotéricos: <code>car</code> es un acrónimo de la frase ‘Contenidos de -la parte de la Dirección del Registro’; y <code>cdr</code> (pronunciado -‘could-er’) es un acrónimo de la frase ‘Contenidos del Decremento -del Registro’. Estas frases se refieren a piezas -específicas de hardware en el ordenador en el que el -Lisp original fué desarrollado. El resto de frases han sido -completamente irrelevantes por más de 25 años a cualquiera -pensando acerca de Lisp. Ninguno, excepto unos pocos académicos -valientes han empezado a usar nombres más razonables para estas -funciones, los viejos términos están todavía en -uso. En particular, los términos usados en el código fuente Emacs -Lisp, que usaremos en esta introducción. -</p> -<hr> -<a name="car-y-cdr"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Nombres-extra_00f1os" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#cons" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="car-y-cdr-1"></a> -<h2 class="section">7.1 <code>car</code> y <code>cdr</code></h2> - -<p>El <small>CAR</small> de una lista es, bastante simple, el primer -ítem en la lista. De este modo, el <small>CAR</small> de la lista -<code>(rosa violeta margarita botóndeoro)</code> es <code>rosa</code>. -</p> -<p>Si está leyendo en Info y en GNU Emacs, se puede ver esto evaluando -lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(car '(rosa violeta margarita botóndeoro)) -</pre></div> - -<p>Después de evaluar la expresión, <code>rosa</code> aparecerá en el -área echo. -</p> -<p>Claramente, un nombre más razonable para la función <code>car</code> -sería <code>first</code> y esto es con frecuencia lo que se -sugiere. -</p> -<p><code>car</code> no elimina el primer ítem de la lista; solo -se informa de lo que hay. Después de que <code>car</code> se haya aplicado a -una lista, la lista es todavía la misma que era. En la -jerga, <code>car</code> es ‘no-destructiva’. Esta funcionalidad deja de ser -importante. -</p> -<p>El <small>CDR</small> de una lista es el resto de la lista, que es, la función -<code>cdr</code> que devuelve la parte de la lista que sigue el primer -ítem. De este modo, mientras el <small>CAR</small> de la lista -<code>'(rosa violeta margarita botóndeoro)</code> es <code>rosa</code>, el resto -de la lista, el valor devuelto por la función <code>cdr</code>, es -<code>(violeta margarita botóndeoro)</code>. -</p> -<p>Se puede ver esto evaluando lo siguiente del modo usual: -</p> -<div class="smallexample"> -<pre class="smallexample">(cdr '(rosa violeta margarita botóndeoro)) -</pre></div> - -<p>Cuando se evalúa esto, <code>(violeta margarita botóndeoro)</code> -aparecerá en el área echo. -</p> -<p>Al igual que <code>car</code>, <code>cdr</code> no elimina los elementos desde la -lista — solo devuelve un informe de lo que el segundo y subsiguientes -elementos son. -</p> -<p>En el ejemplo, la lista de flores se cita. Si no, el intérprete Lisp -intentaría evaluar la lista llamando a <code>rosa</code> como -una función. En este ejemplo, no queremos hacer esto. -</p> -<p>Claramente, un nombre más razonable para <code>cdr</code> -sería <code>rest</code>. -</p> -<p>(Hay una lección aquí: cuando se nombran nuevas -funciones, considere muy cuidadosamente lo que se está haciendo, ya -que puede estar pegadas con los nombres largos que se esperan. La -razón es que este documento perpetúa estos nombres que el -código fuente de Emacs Lisp usa, y si no los usaba, se -estaría un duro rato leyendo el código; pero, por -favor, se debe intentar evitar usar estos términos por uno -mismo. Las personas que vengan después se lo agradecerán. -</p> -<p>Cuando <code>car</code> y <code>cdr</code> se aplica a una lista hecha de -símbolos, tal como la lista <code>(pino roble abeto -arce)</code>, el elemento de la lista devuelta por la función <code>car</code> -es el símbolo <code>pino</code> sin cualquier paréntesis -alrededor. <code>pino</code> es el primer elemento en la lista. Sin embargo, -el <small>CDR</small> de la lista es una lista por sí misma, -<code>(roble abeto arce)</code>, como se puede ver evaluando las siguientes -expresiones en el modo usual: -</p> -<div class="smallexample"> -<pre class="smallexample">(car '(pino roble abeto arce)) - -(cdr '(pino roble abeto arce)) -</pre></div> - -<p>Por otro lado, en una lista de listas, el primer elemento es en -sí mismo una lista. <code>char</code> devuelve este primer -elemento como una lista. Por ejemplo, la siguiente lista contiene tres -sublistas, una lista de carnívoros, una lista de -herbívoros y una lista de mamíferos: -</p> -<div class="smallexample"> -<pre class="smallexample">(car '((leon tigre leopardo) - (gacela antilope cebra) - (ballena delfin foca))) -</pre></div> - -<p>En este ejemplo, el primer elemento de <small>CAR</small> de la lista es la -lista de carnívoros, <code>(leon tigre leopardo)</code>, y el -resto de la lista es <code>((gacela antilope cebra) -(ballena delfin foca))</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(cdr '((leon tigre leopardo) - (gacela antilope cebra) - (ballena delfin))) -</pre></div> - -<p>Es un valor decir de nuevo que <code>car</code> y <code>cdr</code> son no -destructivos — esto es, no se modifican o cambian listas para las -que ser aplicados. Esto es muy importante por cómo son usados. -</p> -<p>También, en el primer capítulo, en la discusión -acerca de átomos, yo dije que en Lisp, “ciertos tipos de átomos, -tales como un array, pueden separarse en partes; pero el mecanismo de -hacer esto es diferente del mecanismo de separar una lista. Desde -que Lisp se conoce, los átomos de una lista son indivisibles.” -(Véase la sección <a href="#g_t_00c1tomos-Lisp">Átomos Lisp</a>.) El <code>car</code> y el <code>cdr</code> son funciones que -son usadas para dividir listas y son consideradas fundamentales para -Lisp. Puesto que no pueden dividir o ganar acceso a las partes de un array, -un array es considerado un átomo. De otro modo, la otra -función fundamental, <code>cons</code>, se puede poner cerca o construir -una lista, pero no un array. (Los arrays son manejados por funciones de -array específicas. See <a href="elisp.html#Arrays">Arrays</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>.) -</p> -<hr> -<a name="cons"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#car-y-cdr" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Construir-una-lista" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="cons-1"></a> -<h2 class="section">7.2 <code>cons</code></h2> -<a name="index-cons_002c-introducido"></a> - -<p>La función <code>cons</code> construye listas; eso es lo inverso de -<code>car</code> y <code>cdr</code>. Por ejemplo, <code>cons</code> puede usarse para -crear una lista de cuatro elementos desde los tres elementos de la -lista, <code>(abeto roble arce)</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(cons 'pino '(abeto roble arce)) -</pre></div> - -<p>Después de evaluar esto, se verá lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(pino abeto roble arce) -</pre></div> - -<p>aparece en el área echo. <code>cons</code> causa la creación de una -nueva lista en el que el elemento es seguido por los elementos de la -lista original. -</p> -<p>Con frecuencia decimos que ‘<code>cons</code> pone un nuevo elemento al -principio de una lista; adjunta o empuja el elemento dentro de la lista’, -pero esta frase puede ser incorrecta, puesto que <code>cons</code> no cambia -a una lista existente, pero crea una nueva. -</p> -<p>Como <code>car</code> y <code>cdr</code>, <code>cons</code> es no destructivo. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Construir-una-lista">Construir una lista</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#length">7.2.1 Encuentra el tamaño de una lista: <code>length</code></a></td><td> </td><td align="left" valign="top"> Cómo encontrar el tamaño de una lista. -</td></tr> -</table> - -<hr> -<a name="Construir-una-lista"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#cons" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#length" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Construir-una-lista-1"></a> -<h3 class="unnumberedsubsec">Construir una lista</h3> - -<p><code>cons</code> debe tener una lista para adjuntar a<a name="DOCF9" href="#FOOT9">(9)</a> No se puede -empezar desde absolutamente nada. Si se está construyendo una lista, -se necesita proveer al menos una lista vacía al -principio. Aquí hay una serie de expresiones <code>cons</code> -que construyen una lista de flores. Si está leyendo esto en Info en -GNU Emacs, se puede evaluar cada una de las expresiones en el camino -usual; el valor es impreso en este texto después de ‘<samp>⇒</samp>’, -que puede leer como ‘evalúas para’. -</p> -<div class="smallexample"> -<pre class="smallexample">(cons 'botóndeoro ()) - ⇒ (botóndeoro) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cons 'margarita '(botóndeoro)) - ⇒ (margarita botóndeoro) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cons 'violeta '(margarita botóndeoro)) - ⇒ (violeta margarita botóndeoro) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cons 'rosa '(violeta margarita botóndeoro)) - ⇒ (rosa violeta margarita botóndeoro) -</pre></div> - -<p>En el primer ejemplo, la lista vacía se muestra como -<code>()</code> y después se construye una lista de <code>botóndeoro</code> -seguida por la lista vacía. Como se puede ver, la lista -vacía no se muestra en la lista que fué -construida. Todo lo que se ve es <code>(botóndeoro)</code>. La lista -vacía no cuenta como un elemento de una lista porque -no hay nada en una lista vacía. Generalmente hablando, -una lista vacía es invisible. -</p> -<p>El segundo ejemplo, <code>(cons 'margarita '(botóndeoro))</code> construye -una nueva lista de dos elemento poniendo <code>margarita</code> en frente de -<code>botóndeoro</code>; y el tercer ejemplo construye una lista de tres -elementos poniendo <code>violeta</code> en frente de <code>margarita</code> y -<code>botóndeoro</code>. -</p> -<hr> -<a name="length"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Construir-una-lista" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#nthcdr" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Encuentra-el-tamano-de-una-lista_003a-length"></a> -<h3 class="subsection">7.2.1 Encuentra el tamaño de una lista: <code>length</code></h3> -<a name="index-length"></a> - -<p>Se pueden encontrar cuántos elementos hay en una lista usando la -función Lisp <code>length</code>, como en los siguientes ejemplos: -</p> -<div class="smallexample"> -<pre class="smallexample">(length '(botóndeoro)) - ⇒ 1 -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(length '(margarita botóndeoro)) - ⇒ 2 -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(length (cons 'violeta '(margarita botóndeoro))) - ⇒ 3 -</pre></div> - -<p>En el tercer ejemplo, la función <code>cons</code> es usada para construir -una lista de tres elementos que entonces se pasa a la función -<code>length</code> como su argumento. -</p> -<p>Se puede también usar <code>length</code> para contar el número de -elementos en una lista vacía: -</p> -<div class="smallexample"> -<pre class="smallexample">(length ()) - ⇒ 0 -</pre></div> - -<p>Como se esperaría, el número de elementos en una lista -vacía es cero. -</p> -<p>Un experimento interesante es encontrar qué ocurre si se intenta -encontrar el tamaño de una no lista en todo; que es, si se intenta -llamar a <code>length</code> sin darle un argumento, incluso una lista no -vacía: -</p> -<div class="smallexample"> -<pre class="smallexample">(length ) -</pre></div> - -<p>Lo que se ve, si se evalúa esto, es el mensaje de error -</p> -<div class="smallexample"> -<pre class="smallexample">Lisp error: (wrong-number-of-arguments length 0) -</pre></div> - -<p>Esto significa que la función recibe el número incorrecto de -argumentos, cero, cuando se espera algún otro número de -argumentos. En este caso, se espera un argumento, el argumento de una -lista cuyo tamaño de la función se está midiendo. (Nótese que -<em>una</em> lista es <em>un</em> argumento, incluso si la lista tiene -muchos elementos dentro.) -</p> -<p>La parte del mensaje de error que dice ‘<samp>length</samp>’ es el nombre de la -función. -</p> - -<hr> -<a name="nthcdr"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#length" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#nth" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="nthcdr-1"></a> -<h2 class="section">7.3 <code>nthcdr</code></h2> -<a name="index-nthcdr"></a> - -<p>La función <code>nthcdr</code> está asociada con la función -<code>cdr</code>. Que lo que hace es tomar la <small>CDR</small> de una lista repetidamente. -</p> -<p>Si se toma el <small>CDR</small> de la lista <code>(pino roble abeto arce)</code>, -será devuelta la lista <code>(roble abeto arce)</code>. Si se repite esto en -lo que se devolvió, se devolverá lista lista <code>(abeto -arce)</code>. (De acuerdo, se repite <small>CDR</small> en la lista original solo se -dará <small>CDR</small> desde la función que no cambia la lista. Se necesita -evaluar el <small>CDR</small> del <small>CDR</small> y así.) Si se contiúa -esto, finalmente será devuelta una lista vacía, que en -este caso, en vez de ser mostrada como <code>()</code> es mostrado como -<code>nil</code>. -</p> -<p>Para revisar, aquí hay una serie de <small>CDR</small>s repetidos, -el siguiente ‘<samp>⇒</samp>’ muestra lo que se devuelve. -</p> -<div class="smallexample"> -<pre class="smallexample">(cdr '(pino roble abeto arce)) - ⇒(roble abeto arce) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cdr '(roble abeto arce)) - ⇒ (abeto arce) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cdr '(abeto arce)) - ⇒(arce) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cdr '(arce)) - ⇒ nil -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cdr 'nil) - ⇒ nil -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(cdr ()) - ⇒ nil -</pre></div> - -<p>También se pueden hacer varios <small>CDR</small>s sin imprimir los valores -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(cdr (cdr '(pino roble abeto arce))) - ⇒ (abeto arce) -</pre></div> - -<p>En este ejemplo, el intérprete Lisp evalúa la lista propia -dentro. La lista de dentro está entre comillas, así solo -pasa la lista del <code>cdr</code> más interno. Este <code>cdr</code> -pasa una lista hecho del segundo y subsiguientes elementos de la lista -al <code>cdr</code> más externo, que produce una lista compuesta del tercer y -subsiguientes elementos de la lista original. En este ejemplo, la -función <code>cdr</code> se repite y devuelve una lista que consiste de -la lista original sin sus primeros dos elementos. -</p> -<p>La función <code>nthcdr</code> hace lo mismo que repitiendo la llamada a -<code>cdr</code>. En el siguiente ejemplo, el segundo argumento se pasa a la -función <code>nthcdr</code>, a través con la lista, y el valor devuelto -es la lista sin sus primeros dos ítems, que son -exactamente los mismos dos <code>cdr</code> en la lista: -</p> -<div class="smallexample"> -<pre class="smallexample">(nthcdr 2 '(pino roble abeto arce)) - ⇒ (abeto arce) -</pre></div> - -<p>Usando la lista original de cuatro elementos, se puede ver qué -ocurre cuando varios argumentos numéricos son pasados a <code>nthcdr</code>, -incluyendo 0, 1, y 5: -</p> -<div class="smallexample"> -<pre class="smallexample">;; <span class="roman">Deja la lista como estaba.</span> -(nthcdr 0 '(pine fir oak maple)) - ⇒ (pino roble abeto arce) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; <span class="roman">Devuelve una copia sin el primer elemento.</span> -(nthcdr 1 '(pine fir oak maple)) - ⇒ (fir oak maple) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; <span class="roman">Devuelve una copia de la lista sin tres elementos.</span> -(nthcdr 3 '(pine fir oak maple)) - ⇒ (maple) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; <span class="roman">Devuelve la lista faltando los cuatro elementos.</span> -(nthcdr 4 '(pine fir oak maple)) - ⇒ nil -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; <span class="roman">Devuelve una copia sin los elementos.</span> -(nthcdr 5 '(pine fir oak maple)) - ⇒ nil -</pre></div> - -<hr> -<a name="nth"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#nthcdr" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#setcar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="nth-1"></a> -<h2 class="section">7.4 <code>nth</code></h2> -<a name="index-nth"></a> - -<p>La función <code>nthcdr</code> toma el <small>CDR</small> de una lista -repetidamente. La función <code>nth</code> toma el <small>CAR</small> del resultado -devuelto por <code>nthcdr</code>. Devuelve el elemento Nth de la lista. -</p> -<p>De este modo, si no fuera definido en C para velocidad, la -definición de <code>nth</code> sería: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun nth (n list) - "Devuelve el elemento Nth de Lista. -N cuenta desde cero. Si Lista no es larga, nil es devuelto". - (car (nthcdr n list))) -</pre></div> - -<p>(Originalmente, <code>nth</code> fué definido en Emacs Lisp en -‘<tt>subr.el</tt>’, pero su definición fué rehecha en C en los 1980s.) -</p> -<p>La función <code>nth</code> devuelve un elemento simple de una lista. Esto -puede ser muy conveniente. -</p> -<p>Nótese que los elementos son numerados desde cero, no desde uno. Es -decir, el primer elemento de una lista, su <small>CAR</small> es el elemento -cero. Esto se llama contar en ‘base cero’ y con frecuencia las -personas tienen la costumbre del que el primer elemento en una lista -sea el número uno, eso es ‘basado en uno’. -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(nth 0 '("uno" "dos" "tres")) - ⇒ "uno" - -(nth 1 '("uno" "dos" "tres")) - ⇒ "dos" -</pre></div> - -<p>Es valorable mencionar que <code>nth</code>, como <code>nthcdr</code> y -<code>cdr</code>, no cambia la lista original — la función no es -destructiva. En contraste con las funciones <code>setcar</code> y -<code>setcdr</code>. -</p> -<hr> -<a name="setcar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#nth" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#setcdr" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="setcar-1"></a> -<h2 class="section">7.5 <code>setcar</code></h2> -<a name="index-setcar"></a> - -<p>Como se podría adivinar desde sus nombres, las funciones -<code>setcar</code> y <code>setcdr</code> asignan el <small>CAR</small> o la <small>CDR</small> de una -lista a un nuevo valor. Ellos actualmente cambia la lista original, no -como <code>car</code> y <code>cdr</code> que deja la lista original como -estaba. Un camino para encontrar cómo esto funciona es -experimentar. Se comenzará con la función <code>setcar</code>. -</p> -<p>Primero, podemos crear una lista y entonces asignar el valor de una -variable a la lista usando la función -<code>setq</code>. Aquí hay una lista de animales: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(antilope jirafa leon tigre)) -</pre></div> - -<p>Si está leyendo esto en Info dentro de GNU Emacs, se puede evaluar -esta expresión del modo usual, posicionando el cursor después de -la expresión y escribiendo <kbd>C-x C-e</kbd>. Esto es una de las -ventajas de tener el intérprete construido dentro del entorno de -computación. Incidentalmente, cuando no hay nada en la -línea después del paréntesis final, tal como un -comentario, el punto puede estar en la siguiente -línea. De este modo, si tu cursor está en la primera -columna de la siguiente línea, no se necesita mover. En -realidad, Emacs permite cualquier cantidad de espacio en blanco -después del paréntesis final.) -</p> -<p>Cuando se evalúa la variable <code>animal</code>, vemos que está -asociada a la lista <code>(antelope giraffer lion tiger)</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">animales - ⇒ (antilope jirafa leon tigre) -</pre></div> - -<p>Por otro lado, la variable <code>animales</code> apunta a la lista -<code>(antilope jirafa leon tigre)</code>. -</p> -<p>Lo siguiente, es evaluar la función <code>setcar</code> mientras le pasa -dos argumentos, la variable <code>animales</code> y el símbolo -citado <code>hipopotamo</code>; esto se hace escribiendo la lista de tres -elementos <code>(setcar animales 'hipopotamo)</code> y entonces evaluando -en el modo usual: -</p> -<div class="smallexample"> -<pre class="smallexample">(setcar animales 'hipopotamo) -</pre></div> - -<p>Después de evaluar esta expresión, evalúa la variable -<code>animales</code> de nuevo. Se puede ver que la lista de animales ha -cambiado: -</p> -<div class="smallexample"> -<pre class="smallexample">animales - ⇒ (hipopótamo jirafa leon tigre) -</pre></div> - -<p>El primer elemento en la lista, <code>antilope</code> se reemplaza por -<code>hipopotamo</code>. -</p> -<p>Así se puede ver que <code>setcar</code> no añadió un -nuevo elemento a la lista como <code>cons</code> tendría; eso -reemplazó <code>antílope</code> con <code>hipopótamo</code>; eso -<em>cambió</em> la lista. -</p> -<hr> -<a name="setcdr"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#setcar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-cons" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="setcdr-1"></a> -<h2 class="section">7.6 <code>setcdr</code></h2> -<a name="index-setcdr"></a> - -<p>La función <code>setcdr</code> es similar a la función <code>setcar</code>, -excepto que la función reemplaza el segundo y subsiguientes -elementos de una lista en vez del primer elemento. -</p> -<p>(Para ver cómo se cambia el último elemento de una lista, mira hacia -delante a la <a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a>, -que usa las funciones <code>nthcdr</code> y <code>setcdr</code>.) -</p> -<p>Para ver cómo esto funciona, asigna el valor de la variable a una -lista de animales domesticados evaluando la siguiente expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales-domesticos '(caballo vaca oveja cabra)) -</pre></div> - -<p>Si ahora se evalúa la lista, lo que se devuelve es <code>(caballo -vaca oveja cabra)</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">animales-domesticos - ⇒ (caballo vaca oveja cabra) -</pre></div> - -<p>Lo siguiente, evalúa <code>setcdr</code> con dos argumentos, el nombre de la -variable que tiene una lista como su valor, y la lista para la que el -<small>CDR</small> de la primera lista sea asignada; -</p> -<div class="smallexample"> -<pre class="smallexample">(setcdr animales-domesticos '(gato perro)) -</pre></div> - -<p>Si se evalúa esta expresión, la lista <code>(gato perro)</code> aparecerá -en el área echo. Este es el valor devuelto por la función. El -resultado en el que estamos interesados es el “efecto lateral”, que -se puede ver evaluando la variable <code>domesticated-animals</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">animales-domesticos - ⇒ (caballo gato perro) -</pre></div> - -<p>En realidad, la lista es cambiada desde <code>(caballo vaca oveja cabra)</code> -a <code>(caballo gato perro)</code>. El <small>CDR</small> de la lista es cambiada desde -<code>(vaca oveja cabra)</code> a <code>(gato perro)</code>. -</p> -<hr> -<a name="Ejercicio-cons"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#setcdr" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio-2"></a> -<h2 class="section">7.7 Ejercicio</h2> - -<p>Construye una lista de cuatro pájaros evaluando varias expresiones -con <code>cons</code>. Encuentra que ocurre cuando <code>cons</code> una lista -dentro de sí. Reemplaza el primer elemento de la lista -de cuatro pájaros con un pez. Reemplaza el resto de esta lista con -una lista de otro pez. -</p> -<hr> -<a name="Cortando-y-almacenando-texto"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Car-cdr-y-cons" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-cons" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Almacenando-Texto" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Cortando-y-almacenando-texto-1"></a> -<h1 class="chapter">8 Cortando y almacenando texto</h1> -<a name="index-Cortando-y-almacenando-texto"></a> -<a name="index-Almacenando-y-cortando-texto"></a> -<a name="index-Cortando-texto"></a> -<a name="index-Copiando-texto"></a> -<a name="index-Borrando-texto"></a> -<a name="index-Borrando-texto-1"></a> - -<p>Siempre y cuando se corte o pegue texto de un búffer con un comando -‘kill’ en GNU Emacs, se almacenará dentro de una lista que se puede -traer con un comando ‘yank’. -</p> -<p>(El uso de la palabra ‘kill’ <em>matar, cortar</em> en Emacs para -procesos que específicamente <em>no</em> destruyen los -valores de las entidades es un accidente histórico desafortunado. Una -palabra mucho más apropiada debería ser ‘clip’ -<em>cortar</em> puesto que es lo que los comandos de corte hacen; ellos -cortan texto fuera de un búffer y lo ponen dentro del almacenamiento -desde el que puede traerse. Con frecuencia ha sido tentada de -reemplazar globalmente todas las ocurrencia de ‘kill’ <em>matar, -cortar</em> en las fuentes de Emacs con ‘clip’ <em>cortar</em> y todas las -ocurrencias de ‘killed’ <em>cortado, muerto</em> con ‘clipped’ -<em>cortado</em>.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Almacenando-Texto">Almacenando texto en una lista</a></td><td> </td><td align="left" valign="top"> El texto está almacenado en una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#zap_002dto_002dchar">8.1 <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> Cortando texto a un carácter. -</td></tr> -<tr><td align="left" valign="top"><a href="#kill_002dregion">8.2 <code>kill-region</code></a></td><td> </td><td align="left" valign="top"> Cortando texto de una región. -</td></tr> -<tr><td align="left" valign="top"><a href="#copy_002dregion_002das_002dkill">8.3 <code>copy-region-as-kill</code></a></td><td> </td><td align="left" valign="top"> Una definición para copiar texto. -</td></tr> -<tr><td align="left" valign="top"><a href="#Disgresi_00f3n-dentro-de-C">8.4 Disgresión dentro de C</a></td><td> </td><td align="left" valign="top"> Nota menor en macros del lenguaje de - programación C. -</td></tr> -<tr><td align="left" valign="top"><a href="#defvar">8.5 Inicializando una variable con <code>defvar</code></a></td><td> </td><td align="left" valign="top"> Cómo dar a una variable un valor inicial. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisi_00f3n-de-cons-y-search_002dfwd">8.6 Revisar</a></td><td> </td><td align="left" valign="top"> Revisión de cons y search-fwd -</td></tr> -<tr><td align="left" valign="top"><a href="#Buscar-ejercicios">8.7 Buscando ejercicios</a></td><td> </td><td align="left" valign="top"> Buscar ejercicios -</td></tr> -</table> - -<hr> -<a name="Almacenando-Texto"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Almacenando-texto-en-una-lista"></a> -<h2 class="unnumberedsec">Almacenando texto en una lista</h2> - -<p>Cuando el texto se corta de un búffer, es almacenado en una -lista. Piezas sucesivas de texto se almacenan en la lista -sucesivamente, así la lista podría verse -así: -</p> -<div class="smallexample"> -<pre class="smallexample">("una pieza de texto" "pieza previa") -</pre></div> - -<p>La función <code>cons</code> puede usarse para crear una nueva lista -desde una pieza de texto (un ‘átomo’, para usar la jerga) y una -lista existente, como esta: -</p> -<div class="smallexample"> -<pre class="smallexample">(cons "otra pieza" - '("una pieza de texto" "pieza previa")) -</pre></div> - -<p>Si se evalúa esta expresión, una lista de tres elementos -aparecerá en el área echo: -</p> -<div class="smallexample"> -<pre class="smallexample">("otra pieza" "una pieza de texto" "pieza previa") -</pre></div> - -<p>Con las funciones <code>car</code> y <code>nthcdr</code>, se puede recuperar -siempre la pieza de texto que se quiere. Por ejemplo, en el siguiente -código, <code>nthcdr 1 …</code> devuelve la lista con el primer -ítem eliminado; y el <code>car</code> devuelve el primer -elemento de este resto — el segundo elemento de la lista -original: -</p> -<div class="smallexample"> -<pre class="smallexample">(car (nthcdr 1 '("otra pieza" - "una pieza de texto" - "pieza previa"))) - ⇒ "una pieza de texto" -</pre></div> - -<p>Las funciones actuales en Emacs son más complejas que esto, de -acuerdo. El código para cortar y recuperar texto tiene que ser -escrito de modo que Emacs pueda ver qué elemento en la lista se -quiere — el primer, segundo, tercer o cualquier otro. Además, -cuando tiene el fin de la lista, Emacs daría el primer -elemento de la lista, en lugar de nada. -</p> -<p>La lista que maneja las piezas de texto se llama <em>kill ring</em> -(anillo de la muerte). Este capítulo lidera una -descripción del anillo de la muerte y como eso se usa por la -primera traza de cómo la función <code>zap-to-char</code> funciona. Esta -función usa (o ‘llama’) a una función que invoca a otra función -que manipula el anillo de la muerte. De este modo, antes de lograr las -montañas, se escalan las colinas. -</p> -<p>Un capítulo subsiguiente describe cómo el texto que se -corta desde el búffer se recupera. Véase la sección <a href="#Pegando">Pegando Texto</a>. -</p> -<hr> -<a name="zap_002dto_002dchar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Almacenando-Texto" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Completar-zap_002dto_002dchar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="zap_002dto_002dchar-1"></a> -<h2 class="section">8.1 <code>zap-to-char</code></h2> -<a name="index-zap_002dto_002dchar"></a> - -<p>La función <code>zap-to-char</code> cambió poco entre GNU Emacs -versión 19 y GNU Emacs versión 22. Sin embargo, <code>zap-to-char</code> -llama a otra función, <code>kill-region</code>, que se reescribió más. -</p> -<p>La función <code>kill-region</code> en Emacs 19 es compleja, pero no usa -código que es importante en este momento. Se obviará. -</p> -<p>La función <code>kill-region</code> en Emacs 22 es más de fácil leer -que la misma función en Emacs 19 e introduce un concepto muy -importante, que el error maneja. Nosotros pasearemos a través de la -función. -</p> -<p>Pero primero, déjanos ver en la función interactive <code>zap-to-char</code>. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Completar-zap_002dto_002dchar">La implementación completa <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> La implementación completa. -</td></tr> -<tr><td align="left" valign="top"><a href="#zap_002dto_002dchar-interactivo">8.1.1 La expresión <code>interactive</code></a></td><td> </td><td align="left" valign="top"> Una expresión interactiva de tres partes. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-zap_002dto_002dchar">8.1.2 El cuerpo de <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> Un resumen corto -</td></tr> -<tr><td align="left" valign="top"><a href="#search_002dforward">8.1.3 La función <code>search-forward</code></a></td><td> </td><td align="left" valign="top"> Cómo buscar una cadena. -</td></tr> -<tr><td align="left" valign="top"><a href="#progn">8.1.4 La forma especial <code>progn</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Resumiendo-zap_002dto_002dchar">8.1.5 Resumiendo <code>zap-to-char</code></a></td><td> </td><td align="left" valign="top"> Usando <code>point</code> y <code>search-forward</code>. -</td></tr> -</table> - -<hr> -<a name="Completar-zap_002dto_002dchar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar-interactivo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-implementacion-completa-zap_002dto_002dchar"></a> -<h3 class="unnumberedsubsec">La implementación completa <code>zap-to-char</code></h3> - -<p>La función <code>zap-to-char</code> elimina el texto en la región entre -la localización del curso (por ej. punto) para incluir la siguiente -ocurrencia de un caracter específico. El texto que -<code>zap-to-char</code> borra es puesto en el kill ring <em>anillo de la -muerte</em>; y puede ser recuperado desde el kill ring <em>anillo de la -muerte</em> escribiendo <kbd>C-y</kbd> (<code>yank</code>). Si el comando dado es un -argumento, eso borra texto a través de este número de -ocurrencias. De este modo, si el cursor estuviera al principio de esta -frase y el carácter fuera ‘<samp>s</samp>’, ‘<samp>De este modo</samp>’ -sería borrado. Si el argumento fueran dos, ‘<samp>De este -modo, si el cursor</samp>’ se borrase, y incluiría la ‘<samp>s</samp>’ -en el ‘<samp>cursor</samp>’. -</p> -<p>Si el carácter específico no encuentra <code>zap-to-char</code> -dirá “Búsqueda fallida”, eso cuenta el carácter que se -escribió, y no eliminó cualquier texto. -</p> -<p>En orden para determinar cuánto texto eliminar <code>zap-to-char</code> usa -una función de búsqueda. Las búsquedas son usadas extensivamente -en el código que manipula texto, y focalizará la atención en -ellos tan bien como el comando de borrado. -</p> - -<p>Aquí está el texto completo de la versión 22 de la -función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun zap-to-char (arg char) - "Corta e incluye ARG'th ocurrencia de CHAR -En caso de ser ignorada si `case-fold-search' es no nulo en el - búffer actual. -Para ir atrás si ARG es negativo; error si CHAR no se encuentra." - (interactive "p\ncZap to char: ") - (if (char-table-p translation-table-for-input) - (setq char (or (aref translation-table-for-input char) char))) - (kill-region (point) (progn - (search-forward (char-to-string char) - nil nil arg) - (point)))) -</pre></div> - -<p>La documentación es en línea. Se necesita conocer el -significado de la jerga de la palabra ‘kill’. -</p> -<hr> -<a name="zap_002dto_002dchar-interactivo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Completar-zap_002dto_002dchar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-zap_002dto_002dchar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-expresion-interactive"></a> -<h3 class="subsection">8.1.1 La expresión <code>interactive</code></h3> - -<p>La expresión interactiva en el comando <code>zap-to-char</code> se ve -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(interactive "p\ncZap to char: ") -</pre></div> - -<p>La parte con comillas, <code>"p\ncZap to char: "</code> <em>Cortar a -caracter</em>, especifica dos cosas diferentes. Primero, y más simple es -el ‘<samp>p</samp>’. Este parte se separa desde la siguiente parte por una -nueva línea, ‘<samp>\n</samp>’. El ‘<samp>p</samp>’ significa que la -parte del primero argumento a la función será pasando el valor de -un ‘prefijo procesado’. El argumento prefijo es pasado escribiendo -<kbd>C-u</kbd> y un número, o <kbd>M-</kbd> y un número. Si la función es -llamada interactivamente sin un prefijo, el número que se pasa es 1. -</p> -<p>La segunda parte de <code>"p\ncZap a caracter: "</code> es ‘<samp>cZap a -carácter:</samp>’. En esta parte, la tecla baja ‘<samp>c</samp>’ indica que -<code>interactive</code> espera una consola que el argumento será un -caracter. La consola sigue el ‘<samp>c</samp>’ y es la cadena ‘<samp>Zap a -caracter: </samp>’ (con un espacio después del punto y coma para hacerlo -bien). -</p> -<p>Todo lo que se hace es preparar los argumentos para <code>zap-to-char</code> -así están en el tipo correcto, y dan al usuario un -prompt. -</p> -<p>En un búffer de solo lectura, la función <code>zap-to-char</code> copia -el texto al anillo de la muerte, no se elimina. El área echo muestra -un mensaje diciendo que el búffer es de solo lectura. También, la -terminal avisa con un pitido. -</p> -<hr> -<a name="cuerpo-zap_002dto_002dchar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar-interactivo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#search_002dforward" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-cuerpo-de-zap_002dto_002dchar"></a> -<h3 class="subsection">8.1.2 El cuerpo de <code>zap-to-char</code></h3> - -<p>El cuerpo de la función <code>zap-to-char</code> contiene el código que -mata (que se borra/corta) el texto en la región desde la posición -actual del cursor e incluyendo el carácter especificado. -</p> -<p>La primera parte del código se ve como: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (char-table-p translation-table-for-input) - (setq char (or (aref translation-table-for-input char) char))) -(kill-region (point) (progn - (search-forward (char-to-string char) nil nil arg) - (point))) -</pre></div> - -<p><code>char-table-p</code> es una función prescrita no vista. Eso determina -si sus argumentos son una tabla de caracteres. Así, se -asigna el carácter pasado a <code>zap-to-char</code> a uno de ellos, si -este carácter existe, o al carácter en sí. (Esto -llega a ser importante para ciertos caracteres en lenguajes no -Europeos. La función <code>aref</code> extrae un elemento desde un -array. Eso es una función específica de array que no -está descrita en este documento. See <a href="elisp.html#Array">Arrays</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>.) -</p> -<p>Lo que devuelve <code>(point)</code> es la posición actual del cursor. -</p> -<p>La siguiente parte del código es una expresión usando -<code>progn</code>. El cuerpo del <code>progn</code> se basa en llamadas a -<code>search-forward</code> y <code>point</code>. -</p> -<p>Es fácil comprender cómo <code>progn</code> funciona después de aprender -acerca de <code>search-forward</code>, así se verá en -<code>search-forward</code> y entonces en <code>progn</code>. -</p> -<hr> -<a name="search_002dforward"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-zap_002dto_002dchar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#progn" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-search_002dforward"></a> -<h3 class="subsection">8.1.3 La función <code>search-forward</code></h3> -<a name="index-search_002dforward"></a> - -<p>La función <code>search-forward</code> se usa para localizar el -zapped-for-character en <code>zap-to-char</code>. Si la búsqueda es -exitosa, <code>search-forward</code> deja el punto inmediatamente después -del último carácter en la cadena objetivo. (En <code>zap-to-char</code>, -la cadena objetivo es solo un carácter largo. <code>zap-to-char</code> usa -la función <code>char-to-string</code> para asegurar que el ordenador -trata este carácter como una cadena). Si la búsqueda es hacia -atrás, <code>search-forward</code> deja el punto solo antes del primer -carácter en el objetivo. También, <code>search-forward</code> devuelve -<code>t</code> para verdad. (Moviendo el punto allí es un -‘efecto lateral’.) -</p> -<p>En <code>zap-to-char</code>, la función <code>search-forward</code> se ve -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(search-forward (char-to-string char) nil nil arg) -</pre></div> - -<p>La función <code>search-forward</code> toma cuatro argumentos: -</p> -<ol> -<li> -El primer argumento es el objetivo, para el que es buscado. Esto debe -ser una cadena, tal como ‘<samp>"z"</samp>’. - -<p>Cuando eso ocurre, el argumento pasado a <code>zap-to-char</code> es un -caracter simple. Debido a la forma en la que los ordenadores son -construidos, el intérprete Lisp puede tratar un caracter simple -siendo diferente desde una cadena de caracteres. Dentro del ordenador, -un caracter simple tiene un formato electrónico en vez de una cadena -de un caracter. (Un caracter simple puede con frecuencia ser grabado -en el ordenador usando exactamente un byte; pero una cadena puede ser -larga, y el ordenador necesita estar listo para esto.) Desde que la -función <code>search-forward</code> busca una cadena, el caracter que la -función <code>zap-to-char</code> recibe como argumento debe ser -convertida dentro del ordenador de un formato a otro; de otro modo, -la función <code>search-forward</code> fallará. La función -<code>char-to-string</code> es usada para hacer esta conversión. -</p> -</li><li> -El segundo argumento asocia la búsqueda; eso se especifica como -una posición en el búffer. En este caso, la búsqueda puede ir al -final del búffer, así no se asigna y el segundo -argumento es <code>nil</code>. - -</li><li> -El tercer argumento cuenta la función que haría si la -búsqueda cae — eso puede señalar un error (e imprimir un -mensaje) o puede devolver <code>nil</code>. Un <code>nil</code> como tercer -argumento hace que la función señale un error cuando la búsqueda -falla. - -</li><li> -El cuarto argumento <code>search-forward</code> es el contaje repetido — -cuántas ocurrencias de la cadena para buscar. Este argumento es -opcional y si la función es llamada sin un contaje repetido, este -argumento pasa el valor 1. Si este argumento es negativo, la -búsqueda va hacia atrás. -</li></ol> - -<p>En la forma de plantilla, una expresión <code>search-forward</code> se ve -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(search-forward "<var>cadena-a-buscar</var>" - <var>limite-de-busqueda</var> - <var>que-hacer-si-la-busqueda-falla</var> - <var>repetir-contaje</var>) -</pre></div> - -<p>Lo siguiente es echar un vistazo a <code>progn</code>. -</p> -<hr> -<a name="progn"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#search_002dforward" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Resumiendo-zap_002dto_002dchar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-forma-especial-progn"></a> -<h3 class="subsection">8.1.4 La forma especial <code>progn</code></h3> -<a name="index-progn"></a> - -<p><code>progn</code> es una forma especial que causa que cada uno de sus -argumentos puedan ser evaluados en secuencia y entonces devuelve el valor -del último. Las expresiones precedentes son evaluadas solo por los -efectos laterales que ellos desarrollan. Los valores producidos por -ellos son descartados. -</p> -<p>La plantilla para una expresión <code>progn</code> es muy simple: -</p> -<div class="smallexample"> -<pre class="smallexample">(progn - <var>body</var>…) -</pre></div> - -<p>En <code>zap-to-char</code>, la expresión <code>progn</code> tiene que hacer dos -cosas: poner el punto en la posición exacta; y devolver la -posición del punto de modo que <code>kill-region</code> conoce cómo de -lejos se copia. -</p> -<p>El primer argumento de <code>progn</code> es <code>search-forward</code>. Cuando -<code>search-forward</code> encuentra la cadena, la función deja el punto -inmediatamente después del último caracter en la cadena -objetivo. (En este caso la cadena objetivo es solo un carácter -largo.) Si la búsqueda es hacia atrás, <code>search-forward</code> deja -el punto justo antes del primer carácter en el objetivo. El -movimiento del punto es un efecto lateral. -</p> -<p>El segundo y último argumento de <code>progn</code> es la expresión -<code>(point)</code>. Esta expresión devuelve el valor del punto, que en -este caso será la localización para la que se ha movido por -<code>search-forward</code>. (En la fuente, una línea que -cuenta la función para ir al carácter previo, si se está yendo -hacia delante, se comentó en 1999; yo no recuerdo si esta -funcionalidad o no funcionalidad era siempre parte de las fuentes -distribuidas.) El valor de <code>point</code> se devuelve por la expresión -<code>progn</code> y se pasa a <code>kill-region</code> como el segundo argumento -de <code>kill-region</code> . -</p> -<hr> -<a name="Resumiendo-zap_002dto_002dchar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#progn" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#zap_002dto_002dchar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#kill_002dregion" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Resumiendo-zap_002dto_002dchar-1"></a> -<h3 class="subsection">8.1.5 Resumiendo <code>zap-to-char</code></h3> - -<p>Ahora que se ha visto cómo <code>search-forward</code> y <code>progn</code> -trabajan, se puede ver cómo la función <code>zap-to-char</code> -funciona como un todo. -</p> -<p>El primer argumento de <code>kill-region</code> es la posición del cursor -cuando el comando <code>zap-to-char</code> da — el valor del punto en este -momento. Con el <code>progn</code>, la búsqueda de la función mueve el -punto a solo después del zapped-to-character y <code>point</code> devuelve -el valor de localización. La función <code>kill-region</code> pone junto -a estos dos valores de punto, el primero como el principio de la -región y el segundo como el fin de la región, y borra la -región. -</p> -<p>La forma especial <code>progn</code> se necesita porque el comando -<code>kill-region</code> toma dos argumentos; y fallaría si -<code>search-forward</code> y expresiones <code>point</code> fueran escritas en -secuencia como dos argumentos adicionales. La expresión <code>progn</code> -es un argumento simple para <code>kill-region</code> y devuelve un valor -para que <code>kill-region</code> se necesite por su segundo argumento. -</p> -<hr> -<a name="kill_002dregion"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Resumiendo-zap_002dto_002dchar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Completa-kill_002dregion" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="kill_002dregion-1"></a> -<h2 class="section">8.2 <code>kill-region</code></h2> -<a name="index-kill_002dregion"></a> - -<p>La función <code>zap-to-char</code> usa la función -<code>kill-region</code>. Esta función corta texto desde una región y -copia este texto al kill ring <em>anillo de la muerte</em>, desde el que -puede ser recuperado. -</p> - -<p>Tanto la versión de Emacs 22 de esta función usa -<code>condition-case</code> y <code>copy-region-as-kill</code>, ambas se -explicarán. <code>condition-case</code> es una forma especial importante. -</p> -<p>En esencia, la función <code>kill-region</code> llama a -<code>condition-case</code>, que toma tres argumentos. En esta función, el -primer argumento no hace nada. El segundo argumento contiene el -código hace el trabajo cuando todo va bien. El tercer argumento -contiene el código que se llama en el evento de un error. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Completa-kill_002dregion">La definición completa <code>kill-region</code></a></td><td> </td><td align="left" valign="top"> La definición de función. -</td></tr> -<tr><td align="left" valign="top"><a href="#condition_002dcase">8.2.1 <code>condition-case</code></a></td><td> </td><td align="left" valign="top"> Tratando con un problema. -</td></tr> -<tr><td align="left" valign="top"><a href="#Macro-Lisp">8.2.2 Macro Lisp</a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="Completa-kill_002dregion"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#kill_002dregion" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#kill_002dregion" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#condition_002dcase" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-definicion-completa-kill_002dregion"></a> -<h3 class="unnumberedsubsec">La definición completa <code>kill-region</code></h3> - -<p>Ahora se puede volver a través del código <code>condition-case</code> en -un momento. Primero, se echa un vistazo a la definición de -<code>kill-region</code>, con comentarios añadidos: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun kill-region (beg end) - "Kill (\"corta\") texto entre punto y marca. -Esto borra el texto desde el búffer y lo guarda en anillo de la - muerte <em>kill ring</em>. -El comando \\[yank] puede recuperarse desde allí. … - " -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; • Desde materias de orden, pasa el punto primero. - (interactive (list (point) (mark))) - ;; • Y cuéntanos si no podemos cortar el texto. - ;; `a menos que' sea un `if' sin una then-part. - (unless (and beg end) - (error "La marca no está asignada ahora, así que - no hay región")) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; • `condition-case' toma tres argumentos - ;; Si el primer argumento es nulo, como aquí - ;; la información acerca del error no está - ;; almacenada para ser usada por otra función - (condition-case nil -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; • El segundo argumento a `condition-case' cuenta lo que el - ;; intérprete que hace cuando todo va bien. -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; Empieza con una función `let' que extrae la cadena - ;; y chequea si existe. Si es así (esto es lo - ;; que `when' chequea), eso llama a una función `if' que - ;; determina si el comando previo que era otra llamada - ;; si el comando previo fué otra llamada a `kill-region'; - ;; si lo era, entonces el siguiente texto se añade - ;; cuando se chequea), eso llama a una función `if' que - ;; determina si el comando previo era otra llamada a - ;; `kill-region'; si era eso, entonces el nuevo texto es - ;; añadido al texto previo; si no, entonces una función - ;; diferente, `kill-new' se llama. -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; La función `kill-append' concatena la nueva cadena y - ;; la vieja. La función `kill-new' inserta texto dentro de - ;; ítem en el kill ring <em>anillo de la muerte</em>. -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; `when' es un `if' sin una parte else. El segundo `when' - ;; de nuevo chequea si la cadena actual existe; - ;; por añadidura, eso chequea si el comando previo fuese - ;; otra llamada a `kill-region'. Si una u otra condición - ;; es verdadero, entonces eso configura el actual comando a - ;; ser `kill-region'. -</pre><pre class="smallexample"> (let ((string (filter-buffer-substring beg end t))) - (when string ;STRING is nil if BEG = END - ;; Add that string to the kill ring, one way or another. - (if (eq last-command 'kill-region) -</pre><pre class="smallexample"> ;; - `yank-handler' es un argumento opcional para - ;; `kill-region' que cuenta el `kill-append' y funciones - ;; `kill-new' como tratan con propiedades añadidas - ;; al texto, tal como `negrilla' o `itálica' - (kill-append string (< end beg) yank-handler) - (kill-new string nil yank-handler))) - (when (or string (eq last-command 'kill-region)) - (setq this-command 'kill-region)) - nil) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; • El tercer argumento a `condition-case' cuenta el intérprete - ;; qué hacer con un error. -</pre><pre class="smallexample"> ;; El tercer argumento tiene una parte de condiciones y una - ;; parte del cuerpo. - ;; Si las condiciones se encuentra (en este caso, - ;; si el texto o búffer son de solo lectura) - ;; entonces el cuerpo es ejecutado. -</pre><pre class="smallexample"> ;; La primera parte del tercer es el siguiente: - ((buffer-read-only text-read-only) ;; parte if - ;; … parte then-part - (copy-region-as-kill beg end) -</pre><pre class="smallexample"> ;; Lo siguiente, también como parte de la then-part, asigna this-command, así - ;; será asignado en un error - (setq this-command 'kill-region) - ;; Finalmente, en la then-part, envía un mensaje - ;; si se puede copiar el texto al anillo de la muerte - ;; <em>kill ring</em> sin señalar un error, pero no si no se puede. - -</pre><pre class="smallexample"> (if kill-read-only-ok - (progn (message "Lee solo texto copiado para el kill ring") nil) - (barf-if-buffer-read-only) - ;; If the buffer isn't read-only, the text is. - (signal 'text-read-only (list (current-buffer))))) -</pre></div> - - -<hr> -<a name="condition_002dcase"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Completa-kill_002dregion" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#kill_002dregion" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Macro-Lisp" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="condition_002dcase-1"></a> -<h3 class="subsection">8.2.1 <code>condition-case</code></h3> -<a name="index-condition_002dcase"></a> - -<p>Como se ha visto antes (véase la sección <a href="#Creando-errores">Genera un Mensaje de Error</a>), cuando el intérprete Emacs Lisp tiene problemas evaluando -una expresión, se provee de una ayuda; en jerga, se dice “signaling an -error” <em>señalando un error</em>. Normalmente, el ordenador para el -programa y te muestra un mensaje. -</p> -<p>Sin embargo, algunos programas garantizan acciones complicadas. Eso no -pararía en un error. En la función <code>kill-region</code>, -la mayoría parece un error que intentará cortar texto -que es de solo lectura y no puede ser eliminado. Así la -función <code>kill-region</code> contiene código para manejar esta -circunstancia. Este código, hace que el cuerpo de la función -<code>kill-region</code>, esté dentro de una forma especial -<code>condition-case</code>. -</p> -<p>La plantilla para <code>condition-case</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(condition-case - <var>var</var> - <var>bodyform</var> - <var>error-handler</var>…) -</pre></div> - -<p>El segundo argumento, <var>bodyform</var> es sencillo. La forma especial -<code>condition-case</code> causa que el intérprete Lisp evalúe el -código en <var>bodyform</var>. Si ningún error ocurre, la forma -especial devuelve el valor del código y produce efectos laterales, -si hay. -</p> -<p>En resumen, la parte <var>bodyform</var> de una expresión -<code>condition-case</code> determina qué ocurre cuando cualquier cosa -funciona correctamente. -</p> -<p>Sin embargo, si un error ocurre, entre sus otras acciones, la -función genera la señal de error que definirá uno o más -errores de nombres de condición. -</p> -<p>Un manejador de errores es el tercer argumento para -<code>condition-case</code>. Un manejador de errores tiene dos partes, un -<var>condition-name</var> y un <var>body</var>. Si la parte <var>condition-name</var> -tiene un manejador de errores encuentra un nombre de condición generado -por un error, entonces la parte del <var>body</var> del manejador de errores -se ejecuta. -</p> -<p>Como se esperaría, la parte <var>condition-name</var> de un -manejador de errores puede ser así, un nombre de -condición simple o una lista de nombres de condición. -</p> -<p>También, una expresión completa <code>condition-case</code> puede -contener más de un manejador de errores. Cuando un error ocurre, el -primer manejador aplicable se ejecuta. -</p> -<p>Finalmente, el primer argumento a la expresión -<code>condition-case</code>, es el argumento <var>var</var>, que es algunas veces -asignado a una variable que contiene información acerca del -error. Sin embargo, si este argumento es nulo, como es el caso en -<code>kill-region</code>, esta información se descarta. -</p> -<p>En breve, en la función <code>kill-region</code>, el código -<code>condition-case</code> funciona así: -</p> -<div class="smallexample"> -<pre class="smallexample"><var>Si no hay errores</var>, <var>ejecuta solo este código</var> - <var>pero</var>, <var>si hay errores</var>, <var>ejecuta este otro código</var>. -</pre></div> - - -<hr> -<a name="Macro-Lisp"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#condition_002dcase" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#kill_002dregion" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#copy_002dregion_002das_002dkill" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Macro-Lisp-1"></a> -<h3 class="subsection">8.2.2 Macro Lisp</h3> -<a name="index-Macro_002c-lisp"></a> -<a name="index-Macro-Lisp"></a> - -<p>La parte de la expresión <code>condition-case</code> que se evalúa en la -expectativa de que todo va bien si tiene un <code>when</code>. El código usa -<code>when</code> para determinar si la variable <code>string</code> (<em>cadena</em>) -apunta al texto que existe. -</p> -<p>Una expresión <code>when</code> es simplemente una conveniencia de -programadores. Eso es un <code>if</code> sin la posibilidad de una -cláusula else. En tu mente, se puede reemplazar <code>when</code> con -<code>if</code> y comprender de que va. Esto es lo que el intérprete Lisp hace. -</p> -<p>Técnicamente hablando, <code>when</code> es una macro Lisp. Una -<em>macro</em> Lisp permite definir una nueva construcción de control y -otras funcionalidades del lenguaje. Eso cuenta al intérprete cómo -computar otra expresión Lisp que dejará de computar el valor. En -este caso, la ‘otra expresión’ es una expresión <code>if</code>. -</p> -<p>La definición de función también tiene una macro <code>unless</code>; -que acompaña a <code>when</code>. La macro <code>unless</code> es un -<code>if</code> sin una cláusula then. -</p> -<p>Para más acerca de macros Lisp, ver <a href="elisp.html#Macros">Macros</a> in <cite>El Manual de Referencia de Emacs Lisp</cite>. El lenguaje de programación C -también provee macros. Estos son diferentes, pero también útiles. -</p> - -<p>Guardando la macro <code>when</code>, en la expresión -<code>condition-case</code>, cuando la cadena tiene contenido, entonces otra -expresión condicional se ejecuta. Esto es un <code>if</code> tanto con una -then-part y como con una else-part. -</p> -<div class="smallexample"> -<pre class="smallexample">(if (eq last-command 'kill-region) - (kill-append string (< end beg) yank-handler) - (kill-new string nil yank-handler)) -</pre></div> - -<p>La parte then (then-part) se evalúa si el comando previo fué otra -llamada para <code>kill-region</code>; si no, se evalúa la parte else -(else-part) -</p> -<p><code>yank-handler</code> es un argumento opcional para <code>kill-region</code> -que cuenta cómo las funciones <code>kill-append</code> y <code>kill-new</code> se -tratan con propiedades añadidas al texto, tal como ‘negrilla’ o -‘itálica’. -</p> -<p><code>last-command</code> es una variable que viene con Emacs y que no se ha -visto antes. Normalmente, siempre y cuando una función se ejecute, -Emacs asigna el valor de <code>last-command</code> al comando previo. -</p> -<p>En este segmento de la definición, la expresión <code>if</code> chequea -si el comando previo era <code>kill-region</code>. Si era eso, -</p> -<div class="smallexample"> -<pre class="smallexample">(kill-append string (< end beg) yank-handler) -</pre></div> - -<p>Se concatena una copia del nuevo texto cortado al texto cortado -previamente en el kill ring <em>anillo de la muerte</em>. -</p> -<hr> -<a name="copy_002dregion_002das_002dkill"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Macro-Lisp" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Completar-copy_002dregion_002das_002dkill" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="copy_002dregion_002das_002dkill-1"></a> -<h2 class="section">8.3 <code>copy-region-as-kill</code></h2> -<a name="index-copy_002dregion_002das_002dkill"></a> -<a name="index-nthcdr-1"></a> - -<p>La función <code>copy-region-as-kill</code> copia una región de texto -desde un búffer y (via <code>kill-append</code> o <code>kill-new</code>) lo -guarda en el <code>kill-ring</code>. -</p> -<p>Si se llama a <code>copy-region-as-kill</code> inmediatamente después de -un comando <code>kill-region</code>, Emacs inserta el texto nuevamente -copiado al texto copiado previamente. Esto significa que si se pega el -texto, se obtiene todo, tanto esto, como la operación previa. Por -otro lado, si algún otro comando precede la -<code>copy-region-as-kill</code>, la función copia el texto dentro de una -entrada separada el kill ring <em>anillo de la muerte</em>. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Completar-copy_002dregion_002das_002dkill">La definición de la función completa <code>copy-region-as-kill</code>.</a></td><td> </td><td align="left" valign="top"> La definición completa de función. -</td></tr> -<tr><td align="left" valign="top"><a href="#cuerpo-copy_002dregion_002das_002dkill">8.3.1 El cuerpo de <code>copy-region-as-kill</code></a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="Completar-copy_002dregion_002das_002dkill"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#copy_002dregion_002das_002dkill" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#copy_002dregion_002das_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-copy_002dregion_002das_002dkill" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-definicion-de-la-funcion-completa-copy_002dregion_002das_002dkill_002e"></a> -<h3 class="unnumberedsubsec">La definición de la función completa <code>copy-region-as-kill</code>.</h3> - -<p>Aquí está el texto completo de la versión 22 -de la función <code>copy-region-as-kill</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun copy-region-as-kill (beg end) - "Guarda la región como si estuviera cortada, pero no la cortes. -En el modo Marca de Tránsito <em>Transient Mark</em>, se desactiva la - marca. -Si `interprogram-cut-function' es no nulo, también se guarda el - texto para una sistema de ventanas de cortar y pegar." - (interactive "r") -</pre><pre class="smallexample"> (if (eq last-command 'kill-region) - (kill-append (filter-buffer-substring beg end) (< end beg)) - (kill-new (filter-buffer-substring beg end))) -</pre><pre class="smallexample"> (if transient-mark-mode - (setq deactivate-mark t)) - nil) -</pre></div> - -<p>De normal, esta función puede ser dividida dentro sus componentes: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun copy-region-as-kill (<var>argument-list</var>) - "<var>documentation</var>…" - (interactive "r") - <var>body</var>…) -</pre></div> - -<p>Los argumentos son <code>beg</code> y <code>end</code> y la función es -interactiva con <code>"r"</code>, así los dos argumentos deben -referirse al principio y al final de la región. Si ha estado -leyendo a través de este documento desde el principio, comprendiendo -estas partes de una función casi llegaría a ser rutina. -</p> -<p>La documentación es algo confusa a menos que se recuerde que la -palabra ‘kill’ <em>matar, cortar</em> tiene un significado diferente de la -usual. La ‘Marca Transitoria’ y <code>interprogram-cut-function</code> -comenta explicar ciertos efectos laterales. -</p> -<p>Después de que se ha asignado una marca, un búffer siempre -contiene una región. Si se desea se puede usar el modo Marca -Transitoria para iluminar la región temporalmente. (Nadie quiere -iluminar la región todo el rato, así el modo Marca -Transitoria subrraya solo en el momento apropiado. Muchas personas -desactivan el modo Marca Transitoria, así la región -nunca se ilumina.) -</p> -<p>También, un sistema de ventanas permite copiar, cortar y pegar entre -programas diferentes. En el sistema de X windows, por ejemplo, la -función <code>interprogram-cut-function</code> es <code>x-select-text</code>, -que funciona con el sistema de ventanas equivalente del kill ring de -Emacs. -</p> -<p>El cuerpo de la función <code>copy-region-as-kill</code> empieza con una -cláusula <code>if</code>. Lo que esta cláusula hace es distinguir entre -dos situaciones diferentes: si este comando se ejecuta o no -inmediatamente después de un comando previo <code>kill-region</code>. En -el primer caso, la nueva región se concatena al texto copiado -previamente. De otro modo, eso se inserta al principio del anillo de -la muerte <em>kill ring</em> como una pieza separada de texto desde la -pieza previa. -</p> -<p>Las dos líneas de la función previene la región -desde la iluminación si el modo Transient Mark <em>Marca -Transitoria</em> está activado. -</p> -<p>El cuerpo de <code>copy-region-as-kill</code> merece discusión en detalle. -</p> -<hr> -<a name="cuerpo-copy_002dregion_002das_002dkill"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Completar-copy_002dregion_002das_002dkill" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#copy_002dregion_002das_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#last_002dcommand-_0026-this_002dcommand" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-cuerpo-de-copy_002dregion_002das_002dkill"></a> -<h3 class="subsection">8.3.1 El cuerpo de <code>copy-region-as-kill</code></h3> - -<p>La función <code>copy-region-as-kil</code> funciona de un modo parecido a -la función <code>kill-region</code>. Ambas están escritas -de un modo que dos o más textos cortados en una fila combinan -su texto en una entrada simple. Si se pega el texto desde el -anillo de la muerte <em>kill ring</em>, se tiene todo en una -pieza. Más allá, los cortes de textos que se cortan hacia adelante -desde la posición actual del cursor se añaden al fin del texto -copiado previamente y comanda este texto copiado vaya hacia atrás al -principio del texto copiado previamente. De este modo, las palabras en -el texto están en el orden apropiado. -</p> -<p>Como <code>kill-region</code>, la función <code>copy-region-as-kill</code> hace -uso de la variable <code>last-command</code> que deja traza del comando de -Emacs previo. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#last_002dcommand-_0026-this_002dcommand"><code>last-command</code> y <code>this-command</code></a></td><td> </td><td align="left" valign="top"> last-command & this-command -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-kill_002dappend">La función <code>kill-append</code></a></td><td> </td><td align="left" valign="top"> Función kill-append -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></td><td> </td><td align="left" valign="top"> Función kill-new -</td></tr> -</table> - -<hr> -<a name="last_002dcommand-_0026-this_002dcommand"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-copy_002dregion_002das_002dkill" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-copy_002dregion_002das_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-kill_002dappend" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="last_002dcommand-y-this_002dcommand"></a> -<h4 class="unnumberedsubsubsec"><code>last-command</code> y <code>this-command</code></h4> - -<p>Normalmente, siempre y cuando una función se ejecuta, Emacs asigna -el valor de <code>this-command</code> a la función que se ejecuta (que en -este caso sería <code>copy-region-as-kill</code>). Al mismo -tiempo, Emacs asigna el valor de <code>last-command</code> al valor previo -de <code>this-command</code>. -</p> -<p>En la primera parte del cuerpo de la función -<code>copy-region-as-kill</code>, una expresión <code>if</code> determina si el -valor de <code>last-command</code> es <code>kill-region</code>. Si es -así, la then-part de la expresión <code>if</code> se -evalúa; eso usa la función <code>kill-append</code> para concatenar el -texto copiado en esta llamada a la función con el texto ya en el -primer elemento (el <small>CAR</small> del anillo de la muerte. Por otro lado, -si el valor de <code>last-command</code> no es <code>kill-region</code>, entonces -la función <code>copy-region-as-kill</code> adjunta un nuevo elemento al -anillo de la muerte <em>kill ring</em> usando la función -<code>kill-new</code>. -</p> -<p>La expresión <code>or</code> se ve así; usa <code>eq</code>: -</p> -<div class="smallexample"> -<pre class="smallexample"> (if (eq last-command 'kill-region) - ;; <span class="roman">parte then</span> - (kill-append (filter-buffer-substring beg end) (< end beg)) - ;; <span class="roman">parte else</span> - (kill-new (filter-buffer-substring beg end))) -</pre></div> - -<a name="index-filter_002dbuffer_002dsubstring"></a> -<p>(La función <code>filter-buffer-substring</code> devuelve una subcadena -filtrada del búffer, cualquiera. Opcionalmente — los argumentos no -están aquí, así nunca está hecho — -la función puede borrar el texto inicial o devolver el texto sin sus -propiedades; esta función es un reemplazo para la vieja función -<code>buffer-substring</code>, que viene antes que las propiedades del texto -fuesen implementadas.) -</p> -<a name="index-eq-_0028ejemplo-de-uso_0029"></a> -<p>La función <code>eq</code> chequea si su primer argumento es el mismo -objeto Lisp que su segundo argumento. La función <code>eq</code> es -similar a la función <code>equal</code> en esto que es usado para chequear -para igualdad, pero difiere en esto que determina si dos -representaciones son actualmente el mismo objeto dentro del ordenador, -pero con diferentes nombres. <code>equal</code> determina si la estructura y -contenidos de dos expresiones son la misma. -</p> -<p>Si el comando previo era <code>kill-region</code>, entonces el intérprete -Emacs Lisp llama a la función <code>kill-append</code> -</p> -<hr> -<a name="Funci_00f3n-kill_002dappend"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#last_002dcommand-_0026-this_002dcommand" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-copy_002dregion_002das_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-kill_002dnew" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-kill_002dappend"></a> -<h4 class="unnumberedsubsubsec">La función <code>kill-append</code></h4> -<a name="index-kill_002dappend"></a> - -<p>La función <code>kill-new</code> se ve como así: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun kill-append (string before-p &optional yank-handler) - "Inserta STRING al fin del último corte en el anillo de la muerte <em>kill ring</em>. -Si BEFORE-P es no nulo, inserta STRING. -… " - (let* ((cur (car kill-ring))) - (kill-new (if before-p (concat string cur) (concat cur string)) - (or (= (length cur) 0) - (equal yank-handler - (get-text-property 0 'yank-handler cur))) - yank-handler))) -</pre></div> - - -<p>La función <code>kill-append</code> es limpia. Usa la función -<code>kill-new</code>, que discutiremos en más detalle en un momento. -</p> -<p>(También, la función provee un argumento opcional llamado -<code>yank-handler</code>; cuando se invoque, este argumento cuenta a la -función cómo tratar con la propiedades añadidas al texto, tales -como ‘negrilla’ o ‘itálicas’.) -</p> -<p>Eso tiene una función <code>let*</code> para asignar el valor del primer -elemento del kill ring a <code>cur</code>. (No se sabe por qué la -función no usa <code>let</code>; solo un valor es asignado en la -expresión. ¿Quizás esto es un error que no produce -problemas? -</p> -<p>Considera el condicional que es uno de los dos argumentos para -<code>kill-new</code>. Eso usa <code>concat</code> para concatenar el nuevo texto -al <small>CAR</small> del anillo de la muerte <em>kill ring</em>. Si eso se -concatena atrás o delante depende de los resultados de una -expresión <code>if</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(if before-p ; <span class="roman">if-part</span> - (concat string cur) ; <span class="roman">then-part</span> - (concat cur string)) ; <span class="roman">else-part</span> -</pre></div> - -<p>Si la región cortada está antes que la región que se cortó en -el último comando, entonces debería ser puesto antes -que el material salvador en el anterior corte <em>kill</em>; y de manera -contraria, si el texto cortado sigue lo que fué cortado, eso -sería añadido después del texto previo. La -expresión <code>if</code> depende del predicado <code>before-p</code> para -decidir si el texto nuevamente salvado es puesto antes o después. -</p> -<p>El símbolo <code>before-p</code> es el nombre de uno de los -argumentos a <code>kill-append</code>. Cuando la función -<code>kill-append</code> se evalúa, se asocia al valor devuelto evaluando -el argumento actual. En este caso, esta es la expresión <code>(< end -beg)</code>. Esta expresión no determina directamente si el texto cortado -en este comando se localiza antes o después del texto cortado del -último comando; lo que hace es determinar si el valor de la variable -<code>end</code> es menor que el valor de la variable <code>beg</code>. Si es -así, significa que el usuario se encara al principio del -búffer. También, el resultado de evaluar la expresión del -predicado. <code>(< end beg)</code>, será verdadero y el texto se -concatena antes del texto previo. Por otro lado, si el valor de la -variable <code>end</code> es mayor que el valor del la variable <code>beg</code>, -el texto será concatenado después del texto previo. -</p> -<p>Cuando el texto nuevamente guardado se concatena, entonces la cadena -con el nuevo texto será concatenado antes del viejo texto: -</p> -<div class="smallexample"> -<pre class="smallexample">(concat string cur) -</pre></div> - -<p>Pero si el texto será añadido, eso será concatenado después -del viejo texto: -</p> -<div class="smallexample"> -<pre class="smallexample">(concat cur string)) -</pre></div> - -<p>Para comprender cómo funciona esto, primero se necesita revisar la -función <code>concat</code>. La función <code>concat</code> enlaza junto o une -dos cadenas de texto. El resultado es una cadena. Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(concat "abc" "def") - ⇒ "abcdef" -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(concat "nuevo " - (car '("primer elemento" "segundo elemento"))) - ⇒ "nuevo primer elemento" - -(concat (car - '("primer elemento" "segundo elemento")) " modificado") - ⇒ "primer elemento modificado" -</pre></div> - -<p>Ahora puede tener sentido <code>kill-append</code>: eso modifica los -contenidos del anillo de la muerte <em>kill ring</em>. El anillo de la -muerte <em>kill ring</em> es una lista, en la que cada elemento es texto -guardado. La función <code>kill-append</code> usa la función -<code>kill-new</code> que usa la función <code>setcar</code>. -</p> -<hr> -<a name="Funci_00f3n-kill_002dnew"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-kill_002dappend" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#cuerpo-copy_002dregion_002das_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Disgresi_00f3n-dentro-de-C" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-kill_002dnew"></a> -<h4 class="unnumberedsubsubsec">La función <code>kill-new</code></h4> -<a name="index-kill_002dnew"></a> - -<p>La función <code>kill-new</code> se ve de esta manera: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun kill-new (string &optional replace yank-handler) - "Crea STRING el último corte en el anillo de la muerte <em>kill - ring</em>. -Asigna `kill-ring-yank-pointer' para apuntarlo. - -Si `interprogram-cut-function' es no nulo, aplícalo a su - STRING. -Segundo argumento opcional REPLACE no-nulo significa que STRING - reemplazará el frente del kill ring, en vez de ser aãndido a la lista. -…" -</pre><pre class="smallexample"> (if (> (length string) 0) - (if yank-handler - (put-text-property 0 (length string) - 'yank-handler yank-handler string)) - (if yank-handler - (signal 'args-out-of-range - (list string "yank-handler specified for empty string")))) -</pre><pre class="smallexample"> (if (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) -</pre><pre class="smallexample"> (if (and replace kill-ring) - (setcar kill-ring string) - (push string kill-ring) - (if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) -</pre><pre class="smallexample"> (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -</pre></div> - -<p>(Vea que la función no es interactiva.) -</p> -<p>Normalmente, se mira a esta función en partes. -</p> -<p>La definición de la función tiene un argumento opcional -<code>yank-handler</code>, que cuando se invoca cuenta la función de cómo -tratar con propiedades añadidas al texto, tal como ‘negrilla’ o -‘itálica’. Nosotros evitaremos esto. -</p> -<p>La primer línea de la documentación tiene sentido: -</p> -<div class="smallexample"> -<pre class="smallexample">Crea la CADENA la última copia en el anillo de la muerte <em>kill -ring</em>. -</pre></div> - -<p>Permite saltarse el resto de la documentación por el momento. -</p> -<p>También, permite salir de la expresión inicial <code>if</code> y estas -líneas de código involucrando -<code>menu-bar-update-yank-menu</code>. Nosotros explicaremos debajo. -</p> -<p>Las líneas críticas son estas: -</p> -<div class="smallexample"> -<pre class="smallexample"> (if (and replace kill-ring) - ;; <span class="roman">entonces</span> - (setcar kill-ring string) -</pre><pre class="smallexample"> ;; <span class="roman">resto</span> - (push string kill-ring) -</pre><pre class="smallexample"> (setq kill-ring (cons string kill-ring)) - (if (> (length kill-ring) kill-ring-max) - ;; <span class="roman">avoid overly long kill ring</span> - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) -</pre><pre class="smallexample"> (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -</pre></div> - -<p>El test condicional es <code>(and replace <span class="nolinebreak">kill-ring)</span></code>. Esto será -verdad cuando dos condiciones se encuentran: el anillo de la muerte -<em>kill ring</em> tiene alguna cosa dentro, y la variable -<code>replace</code> es verdad. -</p> -<p>Cuando la función <code>kill-append</code> asigna <code>replace</code> para ser -cierto y cuando el anillo de la muerte <em>kill ring</em> tiene al menos -un ítem en eso, la expresión <code>setcar</code> es ejecutada. -</p> -<div class="smallexample"> -<pre class="smallexample">(setcar kill-ring string) -</pre></div> - -<p>La función <code>setcar</code> actualemten cambia el primer elemento del -anillo de la muerte (<code>kill-ring</code> lista al valor de -<code>string</code>. Eso reemplaza el primer elemento. -</p> -<p>Por otro lado, si el kill ring está vacío, o -reemplazar es falso, la else-part de la condición está ejecutado: -</p> -<div class="smallexample"> -<pre class="smallexample">(push string kill-ring) -</pre></div> - -<p><code>push</code> pone su primer argumento dentro del segundo. Es similar al -viejo. -</p> -<div class="smallexample"> -<pre class="smallexample">(setq kill-ring (cons string kill-ring)) -</pre></div> - -<p>o el nuevo -</p> -<div class="smallexample"> -<pre class="smallexample">(add-to-list kill-ring string) -</pre></div> - -<p>Cuando eso es falso, la expresión primero construye una nueva -versión del anillo de la muerte <em>kill ring</em> añadiendo -<code>string</code> al anillo de la muerte <em>kill ring</em> como un nuevo -elemento (que es lo que <code>push</code> hace). Entonces ejecuta un segundo -<code>if</code> cláusula. Este segundo <code>if</code> cláusula guarada el -anillo de la muerte <em>kill ring</em> desde el creciente demasiado largo. -</p> -<p>Déjanos mirar estas dos expresiones en orden. -</p> -<p>La línea <code>push</code> de la parte else asigna el nuevo -valor del kill ring <em>anillo de la muerte</em> a que resultados -añaden la cadena siendo cortada al viejo anillo de la muerte -<em>kill ring</em> -</p> -<p>Nosotros podemos ver cómo esto funciona con un ejemplo. -</p> -<p>Primero, -</p> -<div class="smallexample"> -<pre class="smallexample">(setq example-list '("aqui una clausula" "otra clausula")) -</pre></div> - -<p>Después de evaluar esta expresión con <kbd>C-x C-e</kbd>, se puede -evaluar <code>example-list</code> y mira lo que devuelve: -</p> -<div class="smallexample"> -<pre class="smallexample">example-list - ⇒ ("aquí hay una claúsula" "otra claúsula") -</pre></div> - -<p>Ahora, se puede añadir un nuevo elemento en esta lista evaluando la -siguiente expresión: -<a name="index-push_002c-ejemplo"></a> -</p> -<div class="smallexample"> -<pre class="smallexample">(push "una tercera cláusula" lista-de-ejemplo) -</pre></div> - -<p>Cuando se evalúa <code>example-list</code>, se encuentra su valor es: -</p> -<div class="smallexample"> -<pre class="smallexample">example-list - ⇒ ("una tercera claúsula" "aquí hay una - claúsula" "otra claúsula") -</pre></div> - -<p>De este modo, la tercera claúsula se añade a la lista con <code>push</code>. -</p> -<p>Ahora para la segunda parte de la claúsula <code>if</code>. Esta -expresión deja el kill ring desde lo creciente demasiado largo. Eso -se ve de la siguiente manera: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) -</pre></div> - -<p>El código chequea si el tamaño del anillo de la muerte <em>kill -ring</em> es más grande que el máximo tamaño permitido. Este es el -valor de <code>kill-ring-max</code> (que es 60, por defecto). Si el tamaño -del anillo de la muerte <em>kill ring</em> es demasiado largo, entonces -este código asigna el último elemento del anillo de la muerte -<em>kill ring</em> a <code>nil</code>. Eso hace esto usando dos funciones, -<code>nthcdr</code> y <code>setcdr</code>. -</p> -<p>Nosotros vemos que <code>setcdr</code> temprano (véase la sección <a href="#setcdr"><code>setcdr</code></a>). Eso asigna el <small>CDR</small> de una lista, solo como -<code>setcar</code> asigna el <small>CAR</small> de una lista. En este caso, sin -embargo, <code>setcdr</code> no estará configurando el <small>CDR</small> del kill -ring completo; la función <code>nthcdr</code> es usada para causarlo para -asignar el <small>CDR</small> del siguiente al último elemento del kill ring -— esto significa que desde el <small>CDR</small> del siguiente al último -elemnto del kill ring <em>anillo de la muerte</em>, eso asignará el -último elemento del kill ring <em>anillo de la muerte</em>. -</p> -<a name="index-nthcdr_002c-ejemplo"></a> -<p>La función <code>nthcdr</code> funciona repetidamente tomando el <small>CDR</small> -de una lista — eso toma el <small>CDR</small> del <small>CDR</small> del <small>CDR</small> -…. Eso hace esto <var>N</var> veces y devuelve los -resultados. (Véase la sección <a href="#nthcdr"><code>nthcdr</code></a>.) -</p> -<a name="index-setcdr_002c-ejemplo"></a> -<p>De este modo, si teniamos una lista de cuatro elemento que era -supuestamente de tres elementos, se podría asignar el -<small>CDR</small> del siguiente al último elemento a <code>nil</code>, y por eso se -ordena la lista. (Si se asigna el último elemento a algún otro -valor a <code>nil</code>, que se podría hacer, entonces no -se habría ordenado la lista. Véase la sección <a href="#setcdr"><code>setcdr</code></a>.) -</p> -<p>Se puede ver ordenando la evaluación de las siguientes tres -expresiones en turno. Primero asigna el valor de <code>arboles</code> a -<code>(arce encina pino abedul)</code> entonces asigna el <small>CDR</small> de su -segundo <small>CDR</small> y entonces encuentra el valor de <code>arboles</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(setq arboles '(arce encina pino abedul)) - ⇒ (arce encina pino abedul) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(setcdr (nthcdr 2 arboles) nil) - ⇒ nil - -árboles - ⇒ (arce encina pino) -</pre></div> - -<p>(El valor devuelto por la expresión <code>setcdr</code> es <code>nil</code> -desde que es que el <small>CDR</small> es asignado.) -</p> -<p>Para repetir, en <code>kill-new</code>, la función <code>nthcdr</code> toma el -<small>CDR</small> un número de veces que es uno menos que el tamaño -máximo permitido del anillo de la muerte <em>kill ring</em> y -<code>setcdr</code> asigna el <small>CDR</small> de este elemento (que será el resto -de los elementos en el anillo muerte) para <code>nil</code>. Esto previene -el anillo de la muerte <em>kill ring</em> desde lo que crece demasiado largo. -</p> -<p>De la siguiente a la última expresión en la función -<code>kill-new</code> es -</p> -<div class="smallexample"> -<pre class="smallexample">(setq kill-ring-yank-pointer kill-ring) -</pre></div> - -<p>El <code>kill-ring-yank-pointer</code> es una variable global que es -asignado para ser el <code>kill-ring</code>. -</p> -<p>Incluso aunque el <code>kill-ring-yank-pointer</code> es llamado un -‘<samp>puntero</samp>’, eso es una variable solo como el anillo de la muerte -<em>kill ring</em>. Sin embargo, el nombre que ha sido elegido para -ayudar a humanos a comprender cómo la variable se usa. -</p> -<p>Ahora, para devolver rápido una expresión en el cuerpo de la función: -</p> -<div class="smallexample"> -<pre class="smallexample"> (if (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) -</pre></div> - -<p>Empieza con una expresión <code>if</code> -</p> -<p>En este caso, la expresión chequea primero si -<code>menu-bar-update-yank-menu</code> existe como una función, y si -así, se llama. La función <code>fboundp</code> devuelve -cierto si el símbolo que se chequea tiene una -definición de función que ‘no es vacía’. Si el -símbolo de la definición de función fuera -vacío, recibiría un mensaje de error, como -se hizo cuando se crearon errores intencionalmente (véase la sección <a href="#Creando-errores">Genera un Mensaje de Error</a>). -</p> -<p>La then-part contiene una expresión cuyo primer elemento es la -función <code>and</code>. -</p> -<a name="index-and"></a> -<p>La forma especial <code>and</code> evalúa cada uno de sus argumentos hasta -que uno de los argumentos devuelva un valor de <code>nil</code>, en cuyo caso -la expresión <code>and</code> devuelve <code>nil</code>; sin embargo, si -ninguno de los argumentos devuelve una valor de <code>nil</code>, el valor -resultante desde la evaluación el último argumento es -devuelto. (Desde que tal valor no es <code>nil</code>, eso es considerado -cierto en Emacs Lisp.) En otras palabras, una expresión <code>and</code> -devuelve un valor cierto solo si todos sus argumentos son -verdaderos. (Véase la sección <a href="#Revisar-el-segundo-b_00faffer-relacionado">Revisar</a>.) -</p> -<p>La expresión determina si el segundo argumento -<code>menu-bar-update-yank-menu</code> es verdadero o no. -</p> -<p><code>menu-bar-update-yank-menu</code> es una de la funciones que lo hace -posible para usar el menu ‘Seleccionar y Pegar’ en el -ítem Editar de una barra de menu; usando un ratón, se -pueden mirar varias piezas de texto que se han guardado y se -selecciona una pieza para pegar. -</p> -<p>La última expresión en la función <code>kill-new</code> añade las -cadenas nuevamente copiadas a aquella facilidad que existe copiando y -pegando entre diferentes programas ejecutando un sistema de -ventanas. En el Sistema de Ventanas de X, por ejemplo, la función -<code>x-select-text</code> toma la cadena y la almacena en memoria operada -por X. Se puede pegar la cadena en otro programa, tal como un Xterm. -</p> -<p>La expresión se ve como: -</p> -<div class="smallexample"> -<pre class="smallexample"> (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -</pre></div> - -<p>Si <code>interprogram-cut-function</code> existe, entonces Emacs ejecuta -<code>funcall</code>, que en vez de llamar a su primer argumento como una -función, pasa los argumentos que permanecen en -eso. (Incidentalmente, tan lejos como se puede ver, esta expresión -<code>if</code> podría ser reemplazado por una expresión -<code>and</code> similar a uno en la primera parte de la función.) -</p> -<p>Estamos yendo a discutir sistemas de ventanas y otros programas más -allá pero meramente nota que este es un mecanismo que habilita GNU -Emacs a trabajar fácilmente y bien con otros programas. -</p> -<p>Este código para emplazar texot en el anillo de la muerte <em>kill -ring</em>, concatenado con un elemento existente o como un nuevo elemento, -nos lidera al código para traer texto que ha sido cortado del -búffer — los comandos de corte. Sin embargo, antes de discutir los -comandos de corte, es mejor aprender cómo las listas son implementadas -en un ordenador. Esto dejará claro tales misterios como el uso del -término ‘puntero’. Pero antes de esto, nos desviaremos a C. -</p> - -<hr> -<a name="Disgresi_00f3n-dentro-de-C"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-kill_002dnew" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#defvar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Disgresion-dentro-de-C"></a> -<h2 class="section">8.4 Disgresión dentro de C</h2> -<a name="index-delete_002dand_002dextract_002dregion"></a> -<a name="index-C_002c-una-disgresion-dentro"></a> -<a name="index-Disgresion-dentro-de-C"></a> - -<p>La función <code>copy-region-as-kill</code> (véase la sección <a href="#copy_002dregion_002das_002dkill"><code>copy-region-as-kill</code></a>) usa la función -<code>filter-buffer-substring</code>, que en vez de eso usa la función -<code>delete-and-extract-region</code>. Eso elimina los contenidos de una -región y no se puede volverlos a tener. -</p> -<p>Al contrario que el otro código discutido aquí, la -función <code>delete-and-extract-region</code> no está escrita en Emacs -Lisp; eso está escrito en C y es una de las primitivas del sistema -GNU Emacs. Puesto que es muy simple, se hará la disgresión -brevemente desde el Lisp y se describe aquí. -</p> - -<p>Como muchas de las otras primitivas Emacs, -<code>delete-and-extract-region</code> se escribe como una instancia de una -macro C, una macro es una plantilla para codificar. La macro completa -se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">DEFUN ("delete-and-extract-region", Fdelete_and_extract_region, - Sdelete_and_extract_region, 2, 2, 0, - doc: /* Borra el texto entre START y END y lo devuelve. */) - (Lisp_Object start, Lisp_Object end) -{ - validate_region (&start, &end); - if (XINT (start) == XINT (end)) - return empty_unibyte_string; - return del_range_1 (XINT (start), XINT (end), 1, 1); -} -</pre></div> - -<p>Sin ir dentro de los detalles de la macro que escribe el proceso, se -hará un apunte de esta macro que empieza con la palabra -<code>DEFUN</code>. La palabra <code>DEFUN</code> fué elegida puesto que el -código sirve para el mismo propósito que <code>defun</code> hace en -Lisp. (La macro C <code>DEFUN</code> definida en ‘<tt>emacs/src/lisp.h</tt>’.) -</p> -<p>El palabra <code>DEFUN</code> tiene siete partes dentro de los -paréntesis: -</p> -<ul> -<li> -La primera parte es el nombre dado a la función en Lisp, -<code>delete-and-extract-region</code>. - -</li><li> -La segunda parte es el nombre de la función en C, -<code>Fdelete_and_extract_region</code>. Por convención, eso empieza con -‘<samp>F</samp>’. Puesto que C no usa guiones en nombres, los guiones bajos son -usados a su vez. - -</li><li> -La tercera parte es el nombre para la estructura constante C que -registra información en esta función para uso interno. Es el -nombre de la función en C pero empieza con una ‘<samp>S</samp>’ en vez de -una ‘<samp>F</samp>’. - -</li><li> -Las partes cuarta y quinta especifican el número -mínimo y máximo de argumentos que la función puede -tener. Esta función demanda exactamente 2 argumentos. - -</li><li> -La sexta parte está cerca del argumento que sigue la declaración -<code>interactive</code> en una función escrita en Lisp: una carta -seguida, quizás, por una consola. La única diferencia con Lisp es -que si la macro se llama sin argumentos. Entonces se escribe un <code>0</code> -(que es una ‘cadena nula’), como en esta macro. - -<p>Si se fueran a especificar argumentos, se emplazarían -entre marcas de comillas. La macro C para <code>goto-char</code> incluye -<code>\"NGoto char \"</code> en esta posición se indica que la función -espera un prefijo plano, en este caso, una localización numérica -en un búffer, y provee una consola. -</p> -</li><li> -La séptima parte es una cadena de documentación, solo como la -única para una función escrita en Emacs Lisp. Esto es escrito como -un comentario C. (Cuando se escribe Emacs, el programa -<code>lib-src/make-docfile</code> extrae estos comentarios y los usa para -crear la documentación “real”.) -</li></ul> - -<p>En una macro C, los parámetros son los siguientes, con una frase de -este tipo de objeto se siguen por lo que podría ser -llamado el ‘cuerpo’ de la macro. Para <code>delete-and-extract-region</code> -el ‘cuerpo’ consiste de las siguientes cuatro líneas: -</p> -<div class="smallexample"> -<pre class="smallexample">validate_region (&start, &end); -if (XINT (start) == XINT (end)) - return build_string (""); -return del_range_1 (XINT (start), XINT (end), 1, 1); -</pre></div> - -<p>La función <code>validate_region</code> chequea si los valores pasados -como el principio y fin de la región son el tipo apropiado y son del -mismo rango. Si las posiciones del principio y fin son las mismas, entonces -se devuelve una cadena vacía. -</p> -<p>La función <code>del_range_1</code> actualmente borra el texto. Eso es una -función compleja que no miraremos. Eso actualiza el búffer y hace -otras cosas. Sin embargo, es el valorable mirar los dos argumentos -pasados para <code>del_range</code>. Estos son <code>XINT (start)</code> y -<code>XINT (end)</code>. -</p> -<p>Tan lejos como el lenguaje C es concebido, <code>start</code> y <code>end</code> -son dos enteros que marcan el principio y el fin de la región para -ser borrada<a name="DOCF10" href="#FOOT10">(10)</a>. -</p> -<p>En las primeras versiones de Emacs, estos dos números fueron 32 bits -de longitud, pero el código está lentamente siendo generalizado -para manejar otras longitudes. Tres de los bits disponibles son usados -para especificar el tipo de información; los bits permanecen ser -usados como ‘contenido’. -</p> -<p>‘<samp>XINT</samp>’ es una macro C que extrae los números relevantes desde -la colección larga de bits; los otros tres bits se descartan. -</p> -<p>El comando en <code>delete-and-extract-region</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">del_range_1 (XINT (start), XINT (end), 1, 1); -</pre></div> - -<p>Esto borra la región entre la posición del principio, -<code>start</code>, y la posición final, <code>end</code>. -</p> -<p>Desde el punto de vista de la persona que escribe Lisp, Emacs es muy -simple; pero oculta en el fondo un gran trato de complejidad para -hacer todo el trabajo. -</p> -<hr> -<a name="defvar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Disgresi_00f3n-dentro-de-C" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Mira-el-valor-actual-de-la-variable" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Inicializando-una-variable-con-defvar"></a> -<h2 class="section">8.5 Inicializando una variable con <code>defvar</code></h2> -<a name="index-defvar"></a> -<a name="index-Inicializando-una-variable"></a> -<a name="index-Inicializacion-de-Variable"></a> - - -<p>La función <code>copy-region-as-kill</code> es escrita en Emacs Lisp. Dos -funciones con eso, <code>kill-append</code> y <code>kill-new</code>, copiar una -región en un búffer y guardarlo en una variable llamada el -<code>kill-ring</code>. Esta sección describe cómo la variable -<code>kill-ring</code> es creada e inicializada usando la forma especial -<code>defvar</code>. -</p> -<p>(De nuevo se nota que el término <code>kill-ring</code> es un sin -nombre. El texto que es cortado fuera del búffer puede ser traido; -eso no es un corpus de anillo, pero un anillo de texto resucitable.) -</p> -<p>En Emacs Lisp, una variable tal como <code>kill-ring</code> es creada y dada -por un valor inicial usando la forma especial <code>defvar</code>. El nombre -viene de “definir variable”. -</p> -<p>La forma especial <code>defvar</code> es similar a <code>setq</code> en este se -configura el valor de una variable. Eso no es <code>setq</code> en dos -modos; primero solo configura el valor de la variable si la variable -no tiene ya un valor. Si la variable ya tiene un valor, <code>defvar</code> -no sobreescribe el valor existente. Segundo, <code>defvar</code> tiene una -cadena de documentación. -</p> -<p>(Otra forma especial, <code>defcustom</code>, está diseñado para -variables que la gente personaliza. Eso tiene más funcionalidades -que <code>defvar</code>. (Véase la sección <a href="#defcustom">Configurando Variables con <code>defcustom</code></a>.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Mira-el-valor-actual-de-la-variable">Mirando el actual valor de una variable</a></td><td> </td><td align="left" valign="top"> Mira el valor actual de la variable -</td></tr> -<tr><td align="left" valign="top"><a href="#defvar-y-asterisk">8.5.1 <code>defvar</code> y un asterisco</a></td><td> </td><td align="left" valign="top"> defvar y asterisk -</td></tr> -</table> - -<hr> -<a name="Mira-el-valor-actual-de-la-variable"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#defvar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#defvar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#defvar-y-asterisk" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Mirando-el-actual-valor-de-una-variable"></a> -<h3 class="unnumberedsubsec">Mirando el actual valor de una variable</h3> - -<p>Se puede ver el actual valor de una variable, cualquier variable, -usando la función <code>describe-variable</code>, que es normalmente -invocado escribiendo <kbd>C-h v</kbd>. Si se escribe <kbd>C-h v</kbd> y -<code>kill-ring</code> (seguido por <RET>), se verá que hay en tu -anillo de la muerte actual <em>kill ring</em> al ser pulsado — -¡esto puede ser bastante tranquilo! A la inversa, si no -has estado haciendo nada esta sesión en Emacs, excepto leer este -documento, se puede no tener nada dentro. También, se verá la -documentación para <code>kill-ring</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">Documentación: -Lista de secuencias de texto muerto (guardado). -Desde que el (kill ring) se supone que interactua bien con -cut-and-paste facilita ofrecer por sistemas de ventanas, -debería usar esta variable -</pre><pre class="smallexample">interactúa bin con `interprogram-cut-function' y -`interprogram-paste-function'. Las funciones `kill-new', -`kill-append', y `current-kill' se suponen para implementar esta -interacción; se puede querer usarlo en vez de manipular en anillo de -la muerte <em>kill ring</em> directamente. -</pre></div> - -<p>El kill ring <em>anillo de la muerte</em> está definido por un -<code>defvar</code> del siguiente modo: -</p> -<div class="smallexample"> -<pre class="smallexample">(defvar kill-ring nil - "Lista de secuencia de textos cortados. -…") -</pre></div> - -<p>En esta definición de variable, la variable es dada un valor inicial -de <code>nil</code>, que tiene sentido, desde que si no se ha guardado nada, -no se quiere nada si se da un comando <code>yank</code>. La cadena de -documentación es escrito solo como la cadena de documentación de -un <code>defun</code>. Como con la cadena de documentación -sería una frase completa, desde que algunos comandos, -como <code>apropos</code>, imprime solo la primera línea de -documentación. Las líneas de exito no -serían indentadas; de otro modo se mira cuando se usa -<kbd>C-h v</kbd> (<code>describe-variable</code>). -</p> -<hr> -<a name="defvar-y-asterisk"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Mira-el-valor-actual-de-la-variable" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#defvar" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Revisi_00f3n-de-cons-y-search_002dfwd" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="defvar-y-un-asterisco"></a> -<h3 class="subsection">8.5.1 <code>defvar</code> y un asterisco</h3> -<a name="index-defvar-para-una-variable-personalizable"></a> -<a name="index-defvar-con-un-asterisco"></a> - -<p>En el pasado, Emacs usaba la forma especial <code>defvar</code> tanto para -variables interna que no esperaría que un usuario cambie -y para variables que espera un usuario cambie. Aunque se puede -todavía usar <code>defvar</code> para variables -personalizadas, por favor, usa <code>defcustom</code> en vez, desde que la -forma especial provee una ruta dentro de los comando de -Personalización. (Véase la sección <a href="#defcustom">Especificando Variables usando <code>defcustom</code></a>.) -</p> -<p>Cuando se especifica una variable usando la forma especial -<code>defvar</code>, se podría distinguir una variable que un -usuario podría querer cambiar desde otros escribiendo, -‘<samp>*</samp>’, en la primera columna de su cadena de documentación. Por -ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(defvar shell-command-default-error-buffer nil - "*Nombre de buffer para `shell-command' … salir del error. -… ") -</pre></div> - -<a name="index-set_002dvariable"></a> -<p>Tu podrías (y todavía puedes) usar el -comando <code>set-variable</code> para cambiar el valor de -<code>shell-command-default-error-buffer</code> temporalmente. Sin embargo, -las opciones configuradas usando <code>set-variable</code> no están -asignadas solo por la duración de tu sesión de edición. Los -nuevos valores no están guardados entre sesiones. Cada vez que Emacs -empieza, lee el valor original, a menos que tu cambia el valor con tu -fichero ‘<tt>.emacs</tt>’, si configurándolo manualmente o usando -<code>customize</code>. Véase la sección <a href="#Inicializaci_00f3n-de-Emacs">Tu Fichero ‘<tt>.emacs</tt>’</a>. -</p> -<p>Para mí, el mayor uso del comando <code>set-variable</code> es -sugerir variables que se podrían querer asignar en mi -fichero ‘<tt>.emacs</tt>’. Ahora hay más de 700 variables, demasiadas -para recordarlas fácilmente. Afortunadamente, se puede presionar -<TAB> después de llamar al comando <code>M-x set-variable</code> para -ver la lista de variables. (See <a href="emacs.html#Examinando">Examinando y Configurando Variables</a> in <cite>El Manual de GNU Emacs</cite>.) -</p> -<hr> -<a name="Revisi_00f3n-de-cons-y-search_002dfwd"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#defvar-y-asterisk" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-ejercicios" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Revisar-4"></a> -<h2 class="section">8.6 Revisar</h2> - -<p>Aquí hay un breve resumen de algunas funciones -introducidas recientemente. -</p> -<dl compact="compact"> -<dt><code>car</code></dt> -<dt><code>cdr</code></dt> -<dd><p><code>car</code> devuelve el primer elemento de una lista; <code>cdr</code> -devuelve el segundo y subsiguientes elementos de una lista. -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(car '(1 2 3 4 5 6 7)) - ⇒ 1 -(cdr '(1 2 3 4 5 6 7)) - ⇒ (2 3 4 5 6 7) -</pre></div> - -</dd> -<dt><code>cons</code></dt> -<dd><p><code>cons</code> construye una lista enlazando su primer argumento a su -segundo argumento. -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(cons 1 '(2 3 4)) - ⇒ (1 2 3 4) -</pre></div> - -</dd> -<dt><code>funcall</code></dt> -<dd><p><code>funcall</code> evalúa su primer argumento como una -función. Así pasa los argumentos que permanecen a su -primer argumento. -</p> -</dd> -<dt><code>nthcdr</code></dt> -<dd><p>Devuelve el resultado de tomar <small>CDR</small> ‘n’ veces en una lista. -El ‘resto del resto’, como estaba -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(nthcdr 3 '(1 2 3 4 5 6 7)) - ⇒ (4 5 6 7) -</pre></div> - -</dd> -<dt><code>setcar</code></dt> -<dt><code>setcdr</code></dt> -<dd><p><code>setcar</code> cambia el primer elemento de una lista; <code>setcdr</code> -cambia el segundo y subsiguiente elementos de una lista. -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq triple '(1 2 3)) - -(setcar triple '37) - -triple - ⇒ (37 2 3) - -(setcdr triple '("foo" "bar")) - -triple - ⇒ (37 "foo" "bar") -</pre></div> - -</dd> -<dt><code>progn</code></dt> -<dd><p>Evalúa cada argumento en secuencia y entonces devuelve el valor del -último. -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(progn 1 2 3 4) - ⇒ 4 -</pre></div> - -</dd> -<dt><code>save-restriction</code></dt> -<dd><p>Graba siempre que encoger esté en efecto en el búffer, si -cualquiera, restaura este encogimiento después de evaluar los argumentos. -</p> -</dd> -<dt><code>search-forward</code></dt> -<dd><p>Buscar una cadena, y si la cadena es encontrada, mueve el punto. Con -una expresión regular, usa algo similar a -<code>re-search-forward</code>. (Véase la sección <a href="#Buscar-regexp">Búsquedas de Expresiones Regulares</a>, para una explicación de expresiones -regulares patrones y búsquedas.) -</p> -<p><code>search-forward</code> y <code>re-search-forward</code> tiene cuatro argumentos: -</p> -<ol> -<li> -La cadena o la expresión regular para buscar. - -</li><li> -Opcionalmente, el límite de la búsqueda. - -</li><li> -Opcionalmente, que haces si la búsqueda falla, devuelve <code>nil</code> o -un mensaje de error. - -</li><li> -Opcionalmente, cuántas veces se puede repetir la búsqueda; si es -negativa, la búsqueda va hacia atrás. -</li></ol> - -</dd> -<dt><code>kill-region</code></dt> -<dt><code>delete-and-extract-region</code></dt> -<dt><code>copy-region-as-kill</code></dt> -<dd> -<p><code>kill-region</code> corta el texto entre punto y marca desde el -búffer y almacena ese texto en el anillo de la muerte <em>kill -ring</em>, así se puede obtener pegándolo. -</p> -<p><code>copy-region-as-kill</code> copia el texto entre punto y marca dentro -del anillo de la muerte <em>kill ring</em>, que se puede obtener -pegándolo. La función no corta o borra el texto desde el búffer. -</p></dd> -</dl> - -<p><code>delete-and-extract-region</code> elimina el texto entre el punto y -marca desde el búffer y a través. No se puede volver. Esto no es -un comando interactivo.) -</p> -<hr> -<a name="Buscar-ejercicios"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Revisi_00f3n-de-cons-y-search_002dfwd" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Buscando-ejercicios"></a> -<h2 class="section">8.7 Buscando ejercicios</h2> - -<ul> -<li> -Escribe una función interactiva que busca una cadena. Si la -búsqueda encuentra la cadena, deja el punto después y muestra un -mensaje que dice “¡Encontrado!”. (No use -<code>search-forward</code> como nombre de esta función; si se hace, se -sobreescribirá la versión existente <code>search-forward</code> que -viene con Emacs. Use un nombre tal como <code>test-search</code> en vez de -eso. - -</li><li> -Escribe una función que imprime el tercer elemento del kill ring -<em>anillo de la muerte</em> en el área echo, si cualquiera; si el -kill ring <em>anillo de la muerte</em> no contiene un tercer elemento, -imprime un mensaje apropiado. -</li></ul> - -<hr> -<a name="Implementaci_00f3n-de-listas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Cortando-y-almacenando-texto" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-ejercicios" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-diagramadas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Como-las-listas-se-implementan"></a> -<h1 class="chapter">9 Cómo las listas se implementan</h1> -<a name="index-Listas-en-un-ordenador"></a> - -<p>En Lisp, los átomos se graban de manera simple, si la -implementación no es sencilla en la práctica, no es, nada sencilla -en la teoría. El átomo ‘<samp>rosa</samp>’, por ejemplo, se -graba como las cuatro letras contiguas ‘<samp>r</samp>’, ‘<samp>o</samp>’, ‘<samp>s</samp>’, -‘<samp>a</samp>’. Una lista, por otro lado, se guarda de manera diferente. El -mecanismo es igualmente simple, pero toma un momento para tener usada -la idea. Una lista se guarda usando una serie de pares de punteros. En -las series, el primer puntero en cada par de puntos a un átomo o a -otra lista, y el segundo puntero en cada par al siguiente par, o al -símbolo <code>nil</code>, que marca el fin de la lista. -</p> -<p>Un puntero por sí mismo es poco simple a la dirección -electrónica de la que está apuntada. Aquí, una lista -se guarda como una serie de direcciones electrónicas. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Listas-diagramadas">Listas diagramadas</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#S_00edmbolos-como-cajas">9.1 Símbolos como una caja con cajones</a></td><td> </td><td align="left" valign="top"> Explorando una metáfora poderosa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-Lista">9.2 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio Lista -</td></tr> -</table> - -<hr> -<a name="Listas-diagramadas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#S_00edmbolos-como-cajas" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Listas-diagramadas-1"></a> -<h2 class="unnumberedsec">Listas diagramadas</h2> - -<p>Por ejemplo, la lista <code>(rosa violeta botóndeoro)</code> tiene tres -elementos, ‘<samp>rosa</samp>’, ‘<samp>violeta</samp>’, y ‘<samp>botóndeoro</samp>’. En el -ordenador, la dirección electrónica de ‘<samp>rosa</samp>’ se graba en un -segmento de memoria del ordenador a través de la dirección que da -la dirección electrónica de donde el átomo ‘<samp>violeta</samp>’ está -localizado; y esta dirección (la que cuenta donde ‘<samp>violeta</samp>’ -está se localiza) se guarda con una dirección que cuenta donde la -dirección para el átomo ‘<samp>botóndeoro</samp>’ se localiza. -</p> -<p>Esto parece más complicado de lo que es y es más fácil visto en -un diagrama: -</p> -<div class="smallexample"> -<pre class="smallexample"> ___ ___ ___ ___ ___ ___ - |___|___|--> |___|___|--> |___|___|--> nil - | | | - | | | - ---> rosa ---> violeta ---> botóndeoro -</pre></div> -<br> -<br> - -<p>En el diagrama, cada caja representa una palabra de memoria del -ordenador que maneja un objeto Lisp, normalmente en la forma de una -dirección de memoria. Las cajas, por ej. las direcciones, están en -pares. Cada flecha apunta a lo que la dirección es la dirección -de, si un átomo u otro par de direcciones. La primera caja es la -dirección electrónica de ‘<samp>rosa</samp>’ y la flecha apunta a -‘<samp>rosa</samp>’; la segunda caja es la dirección del siguiente par de -cajas, la primera parte de la que es la dirección de ‘<samp>violeta</samp>’ -y la segunda parte es la dirección del siguiente par. La última -caja apunta al símbolo <code>nil</code>, que marca el fin de -la lista. -</p> -<p>Cuando una variable es configurado a una lista con una función tal -como <code>setq</code>, almacena la dirección de la primera caja en la -variable. De este modo, la evaluación de la expresión es: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq ramo '(rosa violeta botóndeoro)) -</pre></div> - -<p>crea una situación como esta: -</p> -<div class="smallexample"> -<pre class="smallexample">ramo - | - | ___ ___ ___ ___ ___ ___ - --> |___|___|--> |___|___|--> |___|___|--> nil - | | | - | | | - --> rosa --> violeta --> botóndeoro -</pre></div> -<br> -<br> - -<p>En este ejemplo, el símbolo <code>ramo</code> maneja la -dirección del primer par de cajas. -</p> -<p>Esta misma lista puede ser ilustrada en un modo diferente de -anotación de cajas como esta: -</p> -<div class="smallexample"> -<pre class="smallexample">ramo - | - | -------------- ---------------- -------------------- - | | car | cdr | | car | cdr | | car | cdr | - -->| rosa | o------->| violeta | o------->| botóndeoro | nil | - | | | | | | | | | - -------------- ---------------- -------------------- -</pre></div> -<br> -<br> - -<p>(Los símbolos consisten de más pares de direcciones, -pero la estructura de un símbolo es hecha de -direcciones. De manera profunda, el símbolo <code>ramo</code> -consiste de un grupo de cajas-de-direcciones, una que es la -dirección de la palabra impresa ‘<samp>ramo</samp>’, una segunda de la que -es la dirección de una definición de función adjunta al -símbolo, si cualquiera, un tercero del que es la -dirección del primer par de cajas-de-direccion para la lista -<code>(rosa violeta botóndeoro)</code>, y -así. Aquí se está mostrando que la -tercera caja de dirección del símbolo apunta al primer -par de cajas-de-direccion para la lista.) -</p> -<p>Si un símbolo se asigna al <small>CDR</small> de una lista, la -lista en sí no cambia; el símbolo -simplemente tiene una dirección abajo de la lista. (En la jerga, -<small>CAR</small> y <small>CDR</small> son ‘no destructivos’.) De este modo, se evalúa -la siguiente expresión -</p> -<div class="smallexample"> -<pre class="smallexample">(setq flores (cdr ramo)) -</pre></div> - -<p>produce esto: -</p> -<br> -<div class="smallexample"> -<pre class="smallexample">ramo flores - | | - | ___ ___ | ___ ___ ___ ___ - --> | | | --> | | | | | | - |___|___|----> |___|___|--> |___|___|--> nil - | | | - | | | - --> rosa --> violeta --> botóndeoro -</pre></div> -<br> -<br> -<br> - -<p>El valor de <code>flores</code> es <code>(violeta botóndeoro)</code>, esto es -decir que el símbolo <code>flores</code> maneja la dirección -del par address-boxes el primero que maneja la dirección de -<code>violeta</code>, y el segundo que maneja la dirección de -<code>botóndeoro</code>. -</p> -<p>Un par de cajas-de-direcciones se llama una <em>cons cell</em> o <em>par -de puntos</em>. See <a href="elisp.html#Tipo-de-C_00e9lula-Cons">la Célula Cons y los Tipos Lista</a> in <cite>El Manual de Referencia de Emacs Lisp</cite>, y -<a href="elisp.html#Notaci_00f3n-de-Pares-de-Puntos">Notación de Pares de Puntos</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, para más -información acerca de células cons y pares de puntos. -</p> -<p>La función <code>cons</code> añade un nuevo par de direcciones al frente -de una serie de direcciones como son mostradas debajo. Por ejemplo, -evaluando la expresión -</p> -<div class="smallexample"> -<pre class="smallexample">(setq ramo (cons 'lila ramo)) -</pre></div> - -<p>produce: -</p> -<br> -<div class="smallexample"> -<pre class="smallexample">ramo flores - | | - | ___ ___ ___ ___ | ___ ___ ___ ___ - --> | | | | | | --> | | | | | | - |___|___|----> |___|___|----> |___|___|---->|___|___|--> nil - | | | | - | | | | - --> lila --> rosa --> violeta --> botóndeoro -</pre></div> -<br> -<br> -<br> - -<p>Sin embargo, esto no cambia el valor del símbolo -<code>flores</code>, así puedes ver evaluando lo siguiente, -</p> -<div class="smallexample"> -<pre class="smallexample">(eq (cdr (cdr ramo)) flores) -</pre></div> - -<p>que devuelve <code>t</code> para verdad. -</p> -<p>Hasta que se resetea, <code>flores</code> todavía tiene el -valor de <code>(violeta botóndeoro)</code>; que es, eso tiene la -dirección de la celula cons cuya primera dirección es -<code>violeta</code>. También, esto no altera cualquier célula -prexistente cons; ellas está todavía allí. -</p> -<p>De este modo, en Lisp, tiene el <small>CDR</small> de una lista, se obtiene la -dirección del siguiente cons en las serie; para tener el <small>CAR</small> de -una lista, se obtiene la dirección del primer elemento de la lista; -para <code>cons</code> un nuevo elemento en una lista, se añade una nueva -célula cons al frente de la lista. ¡Esto es todo lo que -hay así! ¡La estructura subyacente de Lisp -es brillantemente simple! -</p> -<p>¿Y qué hace la última dirección en una serie de -células cons -se refieren? Eso es la dirección de la lista vacía, de -<code>nil</code>. -</p> -<p>En resumen, cuando una variable Lisp es asignada a un valor, eso -provee con la dirección de la lista a la que la variable se refiere. -</p> -<hr> -<a name="S_00edmbolos-como-cajas"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Listas-diagramadas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-Lista" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Simbolos-como-una-caja-con-cajones"></a> -<h2 class="section">9.1 Símbolos como una caja con cajones</h2> -<a name="index-Simbolos-como-una-caja-con-cajones"></a> -<a name="index-Caja-con-cajones_002c-metafora-para-su-simbolo"></a> -<a name="index-Cajones_002c-Caja-de_002c-metafora-para-un-simbolo"></a> - -<p>En una sección temprana, se sugería que se -podría imaginar un símbolo siendo una caja -con cajones. La definición de función se pone en un cajón, el -valor en otro, y así. Lo que se pone en el cajón -maneja el valor que puede cambiarse sin afectar a los contenidos del -cajón manejando la definición de función, y viceversa. -</p> -<p>Actualmente, lo que está puesto en cada cajón es la dirección -del valor o definición de función. Eso es como si se encontrara un -viejo cajón en el ático, y en uno de sus cajones se encontrara un -mapa dándote direcciones a donde está el tesoro escondido. -</p> -<p>(Además de su nombre, la definición del símbolo, y -un valor de la variable, un símbolo tiene un ‘cajón’ -para una <em>lista de propiedades</em> que puede ser usada para grabar -otra información. Las listas de propiedades no se discuten -aquí; ver <a href="elisp.html#Listas-de-Propiedades">Listas de Propiedades</a> in <cite>El Manual de Referencia de Emacs Lisp</cite>.) -</p> -<p>Aquí hay una representación visionaria: -</p> -<br> -<div class="smallexample"> -<pre class="smallexample"> Caja de Cajones Contenidos de Cajones - - __ o0O0o __ - / \ - --------------------- - | direcciones al | [mapeo a] - | nombre del simbolo | ramo - | | - +---------------------+ - | direcciones a la | - | definición del | [nunca] - | simbolo | - +---------------------+ - | direcciones al | [mapeo a] - | valor de variable | (rosa violeta botóndeoro) - | | - +---------------------+ - | direcciones a la | - |lista de propiedades | [no descrito aquí] - | | - +---------------------+ - |/ \| -</pre></div> -<br> -<br> -<br> - -<hr> -<a name="Ejercicio-Lista"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#S_00edmbolos-como-cajas" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio-1"></a> -<h2 class="section">9.2 Ejercicio</h2> - -<p>Asignar <code>flores</code> a <code>violeta</code> y <code>botóndeoro</code>. Asigna -dos flores más en esta lista y asigna esta nueva lista a -<code>mas-flores</code>. Asigna el <small>CAR</small> de <code>flores</code> a un -pez. ¿Qué lista contiene ahora <code>mas-flores</code>? -</p> -<hr> -<a name="Pegando"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Implementaci_00f3n-de-listas" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-Lista" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Resumen-del-anillo-de-la-muerte" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Pegando-texto"></a> -<h1 class="chapter">10 Pegando texto</h1> -<a name="index-pegar"></a> -<a name="index-Recuperar-Texto"></a> -<a name="index-Recuperando-Texto"></a> -<a name="index-Pegando-Texto"></a> - -<p>Siempre y cuando se corta texto fuera de un búffer con un comando -‘kill’ en GNU Emacs, se puede traer con un comando ‘pegar’. El texto -cortado del búffer es puesto en el anillo de la muerte y en los -comandos pegar, se insertan los contenidos apropiados del kill ring -detrás de un búffer (no necesariamente el búffer original). -</p> -<p>Un simple comando <kbd>C-y</kbd> (<code>yank</code>) inserta el primer -ítem desde el anillo de la muerte <em>kill ring</em> -dentro del actual búffer. Si el comando <kbd>C-y</kbd> es seguido -inmediatamente para <kbd>M-y</kbd>, el primer elemento se reemplaza por el -segundo elemento. Los sucesivos comandos <kbd>M-y</kbd> reemplazan el -segundo elemento con el tercer, cuarto, o quinto elemento, y -así. Cuando se llega al último elemento en el anillo -de la muerte <em>kill ring</em>, se reemplaza por el primer elemento y -el ciclo se repite. (De este modo, el kill ring se llama un ‘anillo’ -en vez de solo una ‘lista’. Sin embargo, la estructura de de datos -actual que maneja el texto es una lista. Véase la sección <a href="#Qu_00e9-hace-el-anillo-de-la-muerte">Manejando el anillo de la muerte <em>kill ring</em></a>, para -los detalles de cómo la lista es manejada como un anillo.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Resumen-del-anillo-de-la-muerte">10.1 Resumen del anillo de la muerte</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#kill_002dring_002dyank_002dpointer">10.2 La variable <code>kill-ring-yank-pointer</code></a></td><td> </td><td align="left" valign="top"> El anillo de la muerte es una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#pegar-Ejercicio-nthcdr">10.3 Ejercicios con <code>yank</code> y <code>nthcdr</code></a></td><td> </td><td align="left" valign="top"> La variable <code>kill-ring-yank-pointer</code>. -</td></tr> -</table> - -<hr> -<a name="Resumen-del-anillo-de-la-muerte"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Pegando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#kill_002dring_002dyank_002dpointer" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Resumen-del-anillo-de-la-muerte-1"></a> -<h2 class="section">10.1 Resumen del anillo de la muerte</h2> -<a name="index-Resumen-del-Anillo-de-la-Muerte-Kill-ring"></a> - -<p>El anillo de la muerte <em>kill ring</em> es una lista de cadenas -textuales. Esto es lo que se ve: -</p> -<div class="smallexample"> -<pre class="smallexample">("algún texto" "una pieza diferente pieza de texto" -"todavía más texto") -</pre></div> - -<p>Si estos fueran los contenidos de mi anillo de la muerte <em>kill -ring</em> y yo presionara <kbd>C-y</kbd>, la cadena de caracteres diciendo -‘<samp>algún texto</samp>’ sería insertado en este búffer -donde mi cursor está localizado. -</p> -<p>El comando <code>yank</code> <em>pegar</em> es también usado para duplicar -texto copiándolo. El texto copiado no es cortado desde el búffer, -pero una copia de eso se pone en el anillo de la muerte <em>kill -ring</em> y se inserta pegándolo. -</p> -<p>Tres funciones se usan para atraer texto desde el anillo de la muerte -<em>kill ring</em>: <code>yank</code> (<em>pegar</em>), que normalmente se -asocian a <kbd>C-y</kbd>; <code>yank-pop</code>, que normalmente se asocia a -<kbd>M-y</kbd>; y <code>rotate-yank-pointer</code>, que se usa por las otras -dos funciones. -</p> -<p>Estas funciones se refieren al kill ring <em>anillo de la muerte</em> a -través de una variable llamada el <code>kill-ring-yank-pointer</code>. En -vez de eso, la inserción del código para ambos son las funciones -<code>yank</code> y <code>yank-pop</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(insert (car kill-ring-yank-pointer)) -</pre></div> - -<p>(Bien, no más. En GNU Emacs 22, la función se ha reemplazado por -<code>insert-for-yank</code> que llama a <code>insert-for-yank-1</code> -repetitivamente para cada segmento <code>yank-handler</code>. En vez de eso, -<code>insert-for-yank-1</code> destituye las propiedades de texto desde el -texto insertado de acuerdo a <code>yank-excluded-properties</code>. De otro -modo, eso es como <code>insert</code>. Nosotros lo pegamos con un <code>insert</code> -plano puesto que sea fácil de comprender.) -</p> -<p>Para empezar a comprender cómo <code>yank</code> y <code>yank-pop</code> -funcionan, primero es necesario mirar en la variable -<code>kill-ring-yank-pointer</code>. -</p> -<hr> -<a name="kill_002dring_002dyank_002dpointer"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Pegando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Resumen-del-anillo-de-la-muerte" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#pegar-Ejercicio-nthcdr" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-variable-kill_002dring_002dyank_002dpointer"></a> -<h2 class="section">10.2 La variable <code>kill-ring-yank-pointer</code></h2> - -<p><code>kill-ring-yank-pointer</code> es una variable, solo como -<code>kill-ring</code> es una variable. Eso apunta a alguna cosa siendo -asignada al valor de lo que apunta, como cualquier otra variable Lisp. -</p> -<p>De este modo, si el valor del kill ring es: -</p> -<div class="smallexample"> -<pre class="smallexample">("algún texto" "una pieza diferente pieza de texto" -"todavía más texto") -</pre></div> - -<p>y el <code>kill-ring-yank-pointer</code> apunta a la segunda cláusula, el -valor de <code>kill-ring-yank-pointer</code> es: -</p> -<div class="smallexample"> -<pre class="smallexample">("una pieza diferente de texto" "todavía más texto") -</pre></div> - -<p>Como se explica en el capítulo previo -(Véase la sección <a href="#Implementaci_00f3n-de-listas">Cómo las listas se implementan</a>), el ordenador no guarda dos copias -diferentes del texto siendo apuntado por ambos el <code>kill-ring</code> (el -<em>anillo de la muerte</em>) y el <code>kill-ring-yank-pointer</code> (el -<em>puntero de pegar el anillo de la muerte</em>). Las -palabras “una pieza diferente de texto” y “todavía -más texto” no están duplicadas. En vez de eso, las dos variables -Lisp apuntan a las mismas piezas de texto. Aquí hay un -diagrama: -</p> -<div class="smallexample"> -<pre class="smallexample">kill-ring kill-ring-yank-pointer - | | - | ___ ___ | ___ ___ ___ ___ - ---> | | | --> | | | | | | - |___|___|----> |___|___|--> |___|___|--> nil - | | | - | | | - | | --> "todavía más texto" - | | - | --> "una pieza diferente de texto" - | - --> "algo de texto" -</pre></div> -<br> -<br> -<br> - -<p>Tanto la variable <code>kill-ring</code> y la variable -<code>kill-ring-yank-pointer</code> son punteros. Pero el kill ring -<em>anillo de la muerte</em> en sí es normalmente descrito -como si fuera actualmente de lo que está compuesto. El -<code>kill-ring</code> se refiere a lo que es la lista en vez de lo que -apunta a la lista. Conversando, el <code>kill-ring-yank-pointer</code> se -refiere a como se apunta a una lista. -</p> -<p>Estas dos maneras hablar acerca de la misma cosa suena confuso al -principio pero tiene sentido para reflexionar. El kill ring -<em>anillo de la muerte</em> es generalmente pensado como la estructura -completa de datos que manejan la información de lo que se ha -cortado reciéntemente de los búffers de Emacs. El -<code>kill-ring-yank-pointer</code> en la otra mano, sirve para indicar — -que es, para ‘apuntar a’ — esta parte del anillo de la muerte del -que el primer elemento (el <small>CAR</small>) será insertado. -</p> - -<hr> -<a name="pegar-Ejercicio-nthcdr"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Pegando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#kill_002dring_002dyank_002dpointer" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Pegando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicios-con-yank-y-nthcdr"></a> -<h2 class="section">10.3 Ejercicios con <code>yank</code> y <code>nthcdr</code></h2> - -<ul> -<li> -Usando <kbd>C-h v</kbd> (<code>describe-variable</code>), mira en el valor de tu -kill ring <em>anillo de la muerte</em>. Añade varios -ítems a tu anillo de la muerte <em>kill ring</em>; mira en -su valor de nuevo. Usando <kbd>M-y</kbd> (<code>yank-pop</code>, mueve todo el -camino alrededor del kill ring <em>anillo de la -muerte</em>. ¿Cuántos ítems estaban en tu -kill ring <em>anillo de la muerte</em>? Encuentra el valor de -<code>kill-ring-max</code>. ¿Estaba tu anillo de la muerte -<em>kill ring</em> completo, o podrías haber guardado -más bloques de texto dentro? - -</li><li> -Usando <code>nthcrd</code> y <code>car</code>, construye una serie de expresiones -para devolver, el primer, segundo, tercer y cuarto elemento de una lista. -</li></ul> - -<hr> -<a name="Bucles-y-recursi_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Pegando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#pegar-Ejercicio-nthcdr" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Bucles-y-recursion"></a> -<h1 class="chapter">11 Bucles y recursión</h1> -<a name="index-Bucles-y-recursion"></a> -<a name="index-Recursion-y-bucles"></a> -<a name="index-Repeticion-_0028bucles_0029"></a> - -<p>Emacs Lisp tiene dos caminos primarios para causar una expresión, o -una serie de expresiones, para ser evaluado repetidamente: uno usa un -bucle <code>while</code>, y el otro usa <em>recursión</em>. -</p> -<p>La repetición puede ser valorable. Por ejemplo, para mover hacia -delante cuatro frases, tu solo necesitas escribir un programa que -moverá hacia delante una frase y entonces repite el proceso cuatro -veces. Ya que un ordenador no está aburrido o cansado, tal acción -repetitiva no tiene los efectos de borrado por equivocación o exceso -que pueden tener los humanos. -</p> -<p>La gente mayoritariamente escribe funciones de Emacs Lisp usando -bucles <code>while</code>; pero se puede usar recursión, que provee un -poderoso camino mental para resolver problemas<a name="DOCF11" href="#FOOT11">(11)</a>. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#while">11.1 <code>while</code></a></td><td> </td><td align="left" valign="top"> Causando un cierto código para repetir. -</td></tr> -<tr><td align="left" valign="top"><a href="#Dolist-y-dotimes">11.2 Ahorra tiempo: <code>dolist</code> y <code>dotimes</code></a></td><td> </td><td align="left" valign="top"> Dolist y dotimes -</td></tr> -<tr><td align="left" valign="top"><a href="#Recursi_00f3n">11.3 Recursión</a></td><td> </td><td align="left" valign="top"> Causando que una función se llame a - sí misma. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-Bucle">11.4 Ejercicio de bucles</a></td><td> </td><td align="left" valign="top"> Ejercicio de Bucle -</td></tr> -</table> - -<hr> -<a name="while"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-while" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="while-1"></a> -<h2 class="section">11.1 <code>while</code></h2> -<a name="index-Bucles"></a> -<a name="index-while"></a> - -<p>La forma especial <code>while</code> chequea si el valor devuelto para -evaluar el primer argumento es verdadero o falso. Esto es parecido a -lo que el intérprete Lisp hace con un <code>if</code>; el intérprete -hace lo siguiente, sin embargo, es diferente. -</p> -<p>En una expresión <code>while</code>, si el valor devuelto por evaluar el -primer argumento es falso, el intérprete Lisp descarta el resto de la -expresión (el <em>cuerpo</em> de la expresión) y no la evalúa. Sin -embargo, si el valor es cierto, el intérprete Lisp evalúa el -cuerpo de la expresión y entonces de nuevo chequea si el primer -argumento para <code>while</code> es cierto o falso. Si el valor devuelto de -evaluar el primer argumento es cierto de nuevo, el intérprete Lisp -evalúa el cuerpo de la expresión. -</p> -<p>La plantilla para una expresión <code>while</code> se ve así: -</p> -<div class="smallexample"> -<pre class="smallexample">(while <var>test-verdadero-o-falso</var> - <var>cuerpo</var>…) -</pre></div> - -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Bucles-while">Bucles con <code>while</code></a></td><td> </td><td align="left" valign="top"> Repetir tantas veces como el test devuelva - verdadero. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-de-bucle">11.1.1 Un bucle <code>while</code> y una lista</a></td><td> </td><td align="left" valign="top"> Un bucle <code>while</code> que usa una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002delements_002dof_002dlist">11.1.2 Un ejemplo: <code>imprimir-elementos-de-la-lista</code></a></td><td> </td><td align="left" valign="top"> Usos <code>while</code>, <code>car</code>, <code>cdr</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Incrementando-el-Bucle">11.1.3 Un bucle con un contaje incremental</a></td><td> </td><td align="left" valign="top"> Un bucle con un contador de incremento. -</td></tr> -<tr><td align="left" valign="top"><a href="#Incrementando-los-detalles-de-los-bucles">Detalles de un bucle que se incrementa</a></td><td> </td><td align="left" valign="top"> Incrementando los detalles de - los bucles -</td></tr> -<tr><td align="left" valign="top"><a href="#Bucle-que-se-decrementa">11.1.4 Bucle que decrementa</a></td><td> </td><td align="left" valign="top"> Un bucle con un decrementando contador. -</td></tr> -</table> - -<hr> -<a name="Bucles-while"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-bucle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Bucles-con-while"></a> -<h3 class="unnumberedsubsec">Bucles con <code>while</code></h3> - -<p>En el momento en el que el true-or-false-test de la expresión -<code>while</code> devuelve un valor cierto cuando eso se evalúa, el -cuerpo es repetidamente evaluado. Este proceso se llama bucle puesto -que el intérprete Lisp repite la misma cosa una y otra vez, como un -avión haciendo un loop. Cuando el resultado de evaluar el -true-or-false-test es falso, el intérprete Lisp no evalúa el resto -de la expresión <code>while</code> y ‘existe el bucle’. -</p> -<p>Claramente, si el valor devuelto evaluando el primer argumento para -<code>while</code> es siempre cierto, el cuerpo siguiente será evaluado -una y otra vez … y … para -siempre. Recíprocamente, si el valor devuelto nunca es -cierto, las expresiones en el cuerpo nunca serán evaluadas. La -fortaleza de escribir un bucle <code>while</code> consiste de elegir un -mecanismo tal que el true-or-false-test devuelva cierto solo el -número de veces que requieren las subsiguientes expresiones para -ser evaluadas, y entonces tener el test devuelto a falso. -</p> -<p>El valor devuelto evaluando <code>while</code> es el valor del -true-or-false-test. Una consecuencia interesante de esto es que un -bucle <code>while</code> que evalúa sin errores devolverá <code>nil</code> o -falso sin dignidad de si eso ha girado 1 o 100 veces o -ninguna. ¡Una expresión <code>while</code> que se evalúa de -manera exitosa nunca devuelve un valor cierto! Lo que esto significa -es que <code>while</code> es siempre evaluado por sus efectos laterales, que -es decir, las consecuencias de evaluar las expresiones con el cuerpo -del bucle <code>while</code>. Esto tiene sentido. Eso no es el mero acto del -bucle que es deseado, pero las consecuencias de lo que ocurre cuando -las expresiones en el bucle son repetidamente evaluadas. -</p> -<hr> -<a name="Ejemplo-de-bucle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-while" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#print_002delements_002dof_002dlist" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-bucle-while-y-una-lista"></a> -<h3 class="subsection">11.1.1 Un bucle <code>while</code> y una lista</h3> - -<p>Un camino común para controlar un bucle <code>while</code> es chequear si -una lista tiene cualquier elemento. Si eso se hace, el bucle se -repite; pero si no, la repetición se finaliza. Puesto que esto es -una técnica importante, se creará un breve ejemplo para -ilustrarlo. -</p> -<p>Un camino simple para chequear si una lista tiene elementos es evaluar -la lista: si eso no tiene elementos, si es una lista -vacía y devuelve la lista vacía, -<code>()</code>, que es un sinónimo para <code>nil</code> o falso. Por otro -lado, una lista con elementos devolverá estos elementos cuando eso -se evalúa. Puesto que Emacs Lisp considera como cierto cualquier -valor que no es <code>nil</code>, una lista que devuelve elementos -chequeará cierto en un bucle <code>while</code>. -</p> -<p>Por ejemplo, se puede asignar la variable <code>empty-list</code> a -<code>nil</code> para evaluar la siguiente expresión <code>setq</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq lista-vacia ()) -</pre></div> - -<p>Después de evaluar la expresión <code>setq</code>, se puede evaluar la -variable <code>lista-vacia</code> es el camino normal, posicionando el cursor -después del símbolo y escribiendo <kbd>C-x C-e</kbd>; -<code>nil</code> aparecerá en tu área echo: -</p> -<div class="smallexample"> -<pre class="smallexample">lista-vacia -</pre></div> - -<p>Por otro lado, si se asigna una variable para ser una lista con -elementos, la lista aparecerá cuando se evalúe la variable, como -se puede ver evaluando las siguientes dos expresiones: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(gacela jirafa leon tigre)) - -animales -</pre></div> - -<p>De este modo, para un bucle <code>while</code> que chequea si hay cualquier -ítem en la lista <code>animales</code>, la primera parte del -bucle será escrito así: -</p> -<div class="smallexample"> -<pre class="smallexample">(while animales - … -</pre></div> - -<p>Cuando el <code>while</code> chequea su primer argumento, la variable -<code>animales</code> se evalúa. Eso devuelve una lista. Mientras la -lista tiene elementos, el <code>while</code> considera los resultados del -test para ser verdadero; pero cuando la lista es vacía, -eso considera los resultados del test para ser falso. -</p> -<p>Para prevenir que el bucle <code>while</code> se ejecute siempre, se -necesita proporcionar algún mecanismo. Una técnica usada con -frecuencia es tener una de las subsiguientes formas en la expresión -<code>while</code> que asigna el valor de la lista para ser el <small>CDR</small> de -la lista. Cada vez que la función <code>cdr</code> se evalúa, se va -reduciendo, hasta que finalmente solo queda la lista -vacía. En este punto, el test del bucle <code>while</code> -devolverá falso, y los argumentos para el <code>while</code> no se -evaluarán. -</p> -<p>Por ejemplo, la lista de animales asociada a la variable -<code>animals</code> se puede asignar a ser el <small>CDR</small> de la lista original -con la siguiente expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animals (cdr animals)) -</pre></div> - -<p>Si se han evaluado las expresiones previas y entonces se evalúa esta -expresión, se verá <code>(jirafa leon tigre)</code> que aparecerá en -el área echo. Si se evalúa la expresiń de nuevo, <code>(leon -tigre)</code> aparecerá en el área echo. Si se evalúa de nuevo, -<code>(tigre)</code> y todavía de nuevo aparecerá la lista -vacía y se mostrará como <code>nil</code>. -</p> -<p>Una plantilla para un bucle <code>while</code> usa la función <code>cdr</code> -repetidamente para causar el true-or-false-test finalmente para -chequear la veracidad y se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(while <var>test-whether-list-is-empty</var> - <var>body</var>… - <var>set-list-to-cdr-of-list</var>) -</pre></div> - -<p>Este chequeo y uso de <code>cdr</code> puede ser puesto junto a una -función que va a través de una lista e imprime cada elemento de la -lista en una línea de sí misma. -</p> -<hr> -<a name="print_002delements_002dof_002dlist"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-bucle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Incrementando-el-Bucle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-ejemplo_003a-imprimir_002delementos_002dde_002dla_002dlista"></a> -<h3 class="subsection">11.1.2 Un ejemplo: <code>imprimir-elementos-de-la-lista</code></h3> -<a name="index-print_002delements_002dof_002dlist"></a> - -<p>La función <code>imprimir-elementos-de-la-lista</code> ilustra un bucle -<code>while</code> con una lista. -</p> -<a name="index-_002ascratch_002a-buffer"></a> -<p>La función requiere varias líneas por su salida. Si -estás leyendo esto en una instancia reciente de GNU Emacs, se puede -evaluar la siguiente expresión dentro de Info, de normal. -</p> -<p>Si se está usando una versión antigua de Emacs, es necesario -copiar las expresiones necesarias para el búffer ‘<tt>*scratch*</tt>’ y -evaluarlas allí. Esto es porque el área echo -tenía solo una línea en las versiones -antiguas. -</p> -<p>Se pueden copiar las expresiones marcando el principio de la región -con <kbd>C-<SPC></kbd> (<code>set-mark-command</code>), moviendo el cursor al -fin de la región y entonces copiando la región usando <kbd>M-w</kbd> -(<code>kill-ring-save</code>, que llama a <code>copy-region-as-kill</code> y -entonces provee realimentación visual). En el búffer -‘<tt>*scratch*</tt>’, se pueden copiar las expresiones escribiendo -<kbd>C-y</kbd> (<code>yank</code>). -</p> -<p>Después de haber copiado las expresiones al búffer -‘<tt>*scratch*</tt>’, se evalúa cada expresión en orden. Asegúrese -de evaluar la última expresión, <code>(imprimir-elementos-de-la-lista -animales)</code>, escribiendo <kbd>C-u C-x C-e</kbd>, que es, dando un argumento -para <code>eval-last-sexp</code>. Esto causará el resultado de la -evaluación para ser impreso en el búffer ‘<tt>*scratch*</tt>’ en vez -de siendo impreso en el área echo. (De otro modo se verá alguna -cosa como esto en tu área echo: -<code>^Jgacela^J^Jjirafa^J^Jleon^J^Jtigre^Jnulo</code>, en cada ‘<samp>^J</samp>’ se -estructura una ‘nueva línea’.) -</p> -<p>En una instancia de GNU Emacs reciente, se pueden evaluar estas -expresiones directamente en el búffer Info, y el área echo crecerá -para mostrar los resultados. -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(gacela jirafa leon tigre)) - -(defun imprimir-elementos-de-la-lista (list) - "Imprime cada elemento de LIST en una línea." - (while list - (print (car list)) - (setq list (cdr list)))) - -(imprimir-elementos-de-la-lista animales) -</pre></div> - -<p>Cuando se evalúan las tres expresiones en secuencia, se verá esto: -</p> -<div class="smallexample"> -<pre class="smallexample">gacela - -jirafa - -leon - -tigre -nil -</pre></div> - -<p>Cada elemento de la lista se imprime en una línea en -sí (que es lo que la función <code>print</code> hace) y -entonces el valor devuelto por la función se imprime. Desde que la -última expresión en la función es el bucle <code>while</code>, y -desde que el bucle <code>while</code> siempre devuelve <code>nil</code>, un -<code>nil</code> se imprime después del último elemento de la lista. -</p> -<hr> -<a name="Incrementando-el-Bucle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#print_002delements_002dof_002dlist" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Incrementando-los-detalles-de-los-bucles" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-bucle-con-un-contaje-incremental"></a> -<h3 class="subsection">11.1.3 Un bucle con un contaje incremental</h3> - -<p>Un bucle no es útil a menos que pare cuando debe. Bajo el control de -un bucle con una lista, un camino común de parar un bucle es -escribir el primer argumento como un test que devuelve falso cuando el -número correcto de repeticiones es completo. Esto significa que el -bucle debe tener un contador — una expresión que cuenta cuántas -veces el bucle se repite a sí mismo. -</p> -<hr> -<a name="Incrementando-los-detalles-de-los-bucles"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Incrementando-el-Bucle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-Incremento" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Detalles-de-un-bucle-que-se-incrementa"></a> -<h3 class="unnumberedsubsec">Detalles de un bucle que se incrementa</h3> - -<p>El test para un bucle con un contador de incremento puede ser una -expresión tal como <code>(< contador numero-deseado)</code> que devuelve -<code>t</code> para verdad si el valor de <code>contador</code> es menor que el -<code>numero-deseado</code> de repeticiones y <code>nil</code> para falso si el -valor de <code>contador</code> es igual a o es mayor que el -<code>numero-deseado</code>. La expresión que incrementa el contador puede -ser un simple <code>setq</code> tal como <code>(setq contador (1+ contador))</code>, -donde <code>1+</code> es una función construida en Emacs Lisp que añade -1 a su argumento. (La expresión <code>(1+ contador)</code> tiene el mismo -resultado que <code>(+ contador 1)</code>, que es fácil de leer para un -humano.) -</p> -<p>La plantilla para un bucle <code>while</code> controlado por un contador -que se incrementa se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample"><var>asignar-contador-al-valor-inicial</var> -(while (< contador numero-deseado) ; <span class="roman">true-or-false-test</span> - <var>body</var>… - (setq contador (1+ contador))) ; <span class="roman">incremento</span> -</pre></div> - -<p>Note que se necesita asignar el valor inicial de <code>contador</code>; -normalmente asignado a 1. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Ejemplo-de-Incremento">Ejemplo con contador incremental</a></td><td> </td><td align="left" valign="top"> Contando esquinas en un triángulo. -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-Inc-de-Ejemplo">Las partes de la definición de función</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-Inc-junto">Poniendo la definición de la función junta</a></td><td> </td><td align="left" valign="top"> Poniendo la definición de función junta. -</td></tr> -</table> - -<hr> -<a name="Ejemplo-de-Incremento"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Incrementando-los-detalles-de-los-bucles" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Incrementando-los-detalles-de-los-bucles" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-Inc-de-Ejemplo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejemplo-con-contador-incremental"></a> -<h4 class="unnumberedsubsubsec">Ejemplo con contador incremental</h4> - -<p>Supón que estás jugando en la playa y decides crear un triángulo -de asteriscos, poniendo un asterisco en la primera fila, dos en la -segunda fila, tres en la tercera fila y así: -</p> -<br> -<div class="smallexample"> -<pre class="smallexample"> * - * * - * * * - * * * * -</pre></div> -<br> - -<p>(Hace 2500 años, Pitágoras y otras desarrollaron los principios de -la teoría de números considerando preguntas como esta.) -</p> -<p>Supón que quieres saber cuántos asteriscos necesitarás crear para un -triángulo con 7 filas -</p> -<p>Claramente, lo que necesitas hacer es añadir los números de 1 a -7. Hay dos caminos para hacer esto; se puede comenzar con los -números más pequeños, uno, y añadir la lista en secuencia, 1, -2, 3, 4 y así; o empieza con el número más largo y -añade la lista bajando: 7, 6, 5, 4 y así. Porque ambos -mecanismos ilustran caminos comunes de escribir el bucle <code>while</code>, -crearemos dos ejemplos, uno contando hacia arriba y el otro contando -hacia abajo. En este primer ejemplo, empezaremos con 1 y añadimos 2, -3, 4 y así. -</p> -<p>Si se quiere sumar toda una lista de números, el camino más -fácil para hacer eso es sumar todos los números a la vez. Sin -embargo, si no se sabe cuántos números tendrá la lista, o si se -requiere estar preparado para una lista muy larga, entonces se -necesita diseñar la adición, esto es, repetir un proceso simple -muchas veces en vez de hacer un proceso más complejo. -</p> -<p>Por ejemplo, en vez de añadir todos los asteriscos a la vez, lo que -se puede hacer es añadir el número de asteriscos en la primera -fila, 1, para el número en la segunda fila, 2, y entonces añadir -el total de estas dos filas a la tercera fila, 3. Entonces se puede -añadir el número en la cuarta fila, 4, al total de las primeras -tres filas; y así. -</p> -<p>La característica crítica del proceso es -que cada acción repetitiva sea simple. En este caso, en cada paso -nosotros añadimos solo dos números, el número de asteriscos en -la fila y el total ya encontrado. Este proceso de añadir dos -números es repetido de nuevo y de nuevo hasta la última fila que -ha sido añadida al total de todas las filas precedentes. En un -bucle más complejo la acción repetitiva podría no -ser tan simple, pero será tan simple como hacer todo a la vez. -</p> -<hr> -<a name="Partes-Inc-de-Ejemplo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-Incremento" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Incrementando-los-detalles-de-los-bucles" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-Inc-junto" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Las-partes-de-la-definicion-de-funcion"></a> -<h4 class="unnumberedsubsubsec">Las partes de la definición de función</h4> - -<p>El análisis precedente nos da los bonos de nuestra definición de -función: primero, necesitaremos una variable que podemos llamar -<code>total</code> que será el número total de asteriscos. Esto será -el valor devuelto por la función. -</p> -<p>Segundo, sabemos que la función requerirá un argumento: este -argumento será el número de filas en el triángulo. Eso puede -llamarse <code>number-of-rows</code>. -</p> -<p>Finalmente, se necesita una variable para usarse como contador. Se -podría llamar a esta variable <code>counter</code>, pero un -nombre mejor es <code>row-number</code>. Debido a que lo que el contador hace -en esta función es contar filas, y un programa debería -escribirse para ser comprendido en la medida de lo posible. -</p> -<p>Cuando el intérprete Lisp primero empieza evaluando las expresiones -de la función, el valor de <code>total</code> estaría -asignado a cero, ya que no hemos añadido cualquier cosa a -eso. Entonces la función añadiría el número de -asteriscos en la primera fila al total, y entonces añade el número -de asteriscos en la segunda al total, y entonces añade el número -de asteriscos a la tercera fila al total, y así, hasta -que no hay más filas a la izquierda para añadir. -</p> -<p>Ambos <code>total</code> y <code>row-number</code> se usan solo dentro de la -función, así ellos pueden ser declarados como -variables locales con <code>let</code> y valores iniciales -dados. Claramente, el valor inicial para total sería -0. El valor inicial de <code>row-number</code> sería 1, desde -que se comienza con la primera fila. Esto significa que la frase -<code>let</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample"> (let ((total 0) - (row-number 1)) - <var>body</var>…) -</pre></div> - -<p>Después de que las variables internas se declaran y se asignan a -sus valores iniciales se podría empezar el bucle -<code>while</code>. La expresión que sirve como el test -devolvería un valor de <code>t</code> para la verdad tan -grande como el <code>row-number</code> que es menor o igual al -<code>number-of-rows</code>. (La expresión devuelve cierto solo si el -número de fila es menor que el número de filas en el triángulo, -la última fila nunca será añadida al total; aquí -el número de fila tiene que ser menor o igual el número de -filas.)) -</p> -<a name="index-_003c_003d-_0028menos-que-igual_0029"></a> -<p>Lisp provee la función <code><=</code> que devuelve cierto si el valor de -su primer argumento es menor o igual al valor de su segundo argumento -y falso de otro modo. Así la expresión que el -<code>while</code> evaluará como si su test se vería como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(<= row-number number-of-rows) -</pre></div> - -<p>El número de asteriscos puede encontrarse repetidamente añadiendo -el número de asteriscos en una fila al total ya encontrado. Puesto -que el número de asteriscos en la fila es igual al número de la -fila, el total puede encontrarse añadiendo el número de filas -al total. (Claramente, en una situación más compleja, el número -de asteriscos en la fila podría ser relacionada al -número de la fila en un camino más complicado; si este fuera el -caso, el número de fila sería reemplazado por la -expresión apropiada.) -</p> -<div class="smallexample"> -<pre class="smallexample">(setq total (+ total row-number)) -</pre></div> - -<p>Lo que esto hace es asignar el nuevo valor de <code>total</code> a ser igual a -la suma de añadiendo el número de asteriscos en la fila al total previo. -</p> -<p>Después de configurar el valor de <code>total</code>, las condiciones -deben ser establecidas para la siguiente repetición del bucle, -si hay alguna. Esto se hace incrementando el valor de la variable -<code>row-number</code>, que sirve como un contador. Después que la -variable <code>row-number</code> ha sido incrementada, el true-or-false-test -al principio del bucle <code>while</code> chequea si su valor es -todavía menor o igual al valor del <code>number-of-rows</code> -y si eso es, añade el nuevo valor de la variable <code>row-number</code> -al <code>total</code> de la repetición del bucle. -</p> -<p>La función construida en Emacs Lisp <code>1+</code> añade 1 a un -número, así la variable <code>row-number</code> puede ser -incrementado con esta expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq row-number (1+ row-number)) -</pre></div> - -<hr> -<a name="Ejemplo-Inc-junto"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-Inc-de-Ejemplo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Incrementando-los-detalles-de-los-bucles" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Bucle-que-se-decrementa" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Poniendo-la-definicion-de-la-funcion-junta"></a> -<h4 class="unnumberedsubsubsec">Poniendo la definición de la función junta</h4> - -<p>Nosotros hemos creado las partes para la definición de la función; -ahora necesitamos ponerlas juntas. -</p> -<p>Primero, los contenidos de la expresión <code>while</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(while (<= row-number number-of-rows) ; <span class="roman">true-or-false-test</span> - (setq total (+ total row-number)) - (setq row-number (1+ row-number))) ; <span class="roman">incremento</span> -</pre></div> - -<p>Tener la expresión <code>let</code> de varlist, se acerca a completar el -cuerpo de la definición de función. Sin embargo, eso requiere un -elemento final, la necesidad para la que es alguna cosa pequeña. -</p> -<p>El toque final es emplazar la variable <code>total</code> en una -línea por sí misma después de la -expresión <code>while</code>. De otro modo, el valor devuelto por la -función completa es el valor de la última expresión que es -evaluada en el cuerpo del <code>let</code>, y este es el valor devuelto por -el <code>while</code> que es siempre <code>nil</code>. -</p> -<p>Esto puede no ser evidente a primera vista. Eso casi se ve como si la -expresión de incremento es la última expresión de la función -completa. Pero esta expresión es parte del cuerpo del <code>while</code>; -eso es el último elemento de la lista que empieza con el -símbolo <code>while</code>. Más allá, el bucle -<code>while</code> completo es una lista con el cuerpo del <code>let</code>. -</p> -<p>En línea (<em>outline</em>), la función se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun <var>name-of-function</var> (<var>argument-list</var>) - "<var>documentation</var>…" - (let (<var>varlist</var>) - (while (<var>true-or-false-test</var>) - <var>body-of-while</var>… ) - … )) ; <span class="roman">Necesita la expresión final aquí.</span> -</pre></div> - -<p>El resultado de evaluar el <code>let</code> es que lo que está yendo para -devolver el <code>defun</code> desde el <code>let</code> que no está embebido -con cualquier lista que contiene, excepto para la <code>defun</code> como un -todo. Sin embargo, si el <code>while</code> es el último elemento de la -expresión <code>let</code>, la función siempre devolverá -<code>nil</code>. ¡Esto no es lo que quiero! En vez de eso, lo -que queremos es el valor de la variable <code>total</code>. Eso devuelve -simplemente emplazando el símbolo como el último -elemento de la lista empezando con <code>let</code>. Eso se evalúa -después de los elementos precedentes de la lista evaluada, que -significa que eso se evaluó después de haber sido asignado el -valor correcto para el total. -</p> -<p>Eso puede ser fácil de ver imprimiendo la lista empezando con -<code>let</code> todo en una línea. Este formato hace evidente -que las expresiones <var>varlist</var> y <code>while</code> son el segundo el -tercer elementos de la lista empezando con <code>let</code>, y el -<code>total</code> es el último elemento: -</p> -<div class="smallexample"> -<pre class="smallexample">(let (<var>varlist</var>) (while (<var>true-or-false-test</var>) -<var>body-of-while</var>… ) total) -</pre></div> - -<p>Poniendo cualquier cosa junta, la definición de función -<code>triangle</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle (number-of-rows) ; <span class="roman">Versión con</span> - ; <span class="roman"> contador de incremento.</span> - "Añade el número de asteriscos en un triángulo. -La primera fila tiene un asterisco, la segunda fila dos asteriscos, -la tercera fila tres asteriscos, y así. -El argumento es NUMBER-OF-ROWS." -</pre><pre class="smallexample"> (let ((total 0) - (row-number 1)) - (while (<= row-number number-of-rows) - (setq total (+ total row-number)) - (setq row-number (1+ row-number))) - total)) -</pre></div> - -<p>Después de haber instalado <code>triangle</code> para evaluar la función, -se puede probar. Aquí hay dos ejemplos: -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle 4) - -(triangle 7) -</pre></div> - -<p>La suma del primero de cuatro números es 10 y la suma de los primeros -siete números es 28. -</p> -<hr> -<a name="Bucle-que-se-decrementa"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-Inc-junto" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#while" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-Decremento" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Bucle-que-decrementa"></a> -<h3 class="subsection">11.1.4 Bucle que decrementa</h3> - -<p>Otro camino común para escribir un bucle <code>while</code> es escribir el -test así que determina si un contador es mayor que -cero. Así tan largo es el contador mayor que cero, el -bucle se repite. Pero cuando el contador es igual o menor que cero, -el bucle se para. Para este trabajo, el contador tiene que empezar -mayor que cero y entonces se hace más pequeño y pequeño por una -forma que es evaluada repetidamente. -</p> -<p>El test será una expresión tal como <code>(> counter 0)</code> que -devuelve <code>t</code> <em>cierto</em> si el valor de <code>counter</code> es mayor -que cero, y <code>nil</code> <em>falso</em> si el valor de <code>counter</code> es -igual a o menor que cero. La expresión hace que el número menor y -menor puede ser un simple <code>setq</code> tal como <code>(setq counter (1- -counter)</code>, donde <code>1-</code> es una función construida en Emacs Lisp -que sustrae 1 de su argumento. -</p> -<p>La plantilla para decrementar el bucle <code>while</code> se ve -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(while (> counter 0) ; <span class="roman">test-verdadero-o-falso</span> - <var>body</var>… - (setq counter (1- counter))) ; <span class="roman">decremento</span> -</pre></div> - -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Ejemplo-de-Decremento">Ejemplo con el contador que se decrementa</a></td><td> </td><td align="left" valign="top"> Más piedras en la playa. -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-de-Ejemplo-Dec">Las partes de la definición de función</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-Dec-junto">Poniendo la definición de la función junta</a></td><td> </td><td align="left" valign="top"> Poniendo la definición de función junta. -</td></tr> -</table> - -<hr> -<a name="Ejemplo-de-Decremento"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Bucle-que-se-decrementa" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Bucle-que-se-decrementa" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-de-Ejemplo-Dec" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejemplo-con-el-contador-que-se-decrementa"></a> -<h4 class="unnumberedsubsubsec">Ejemplo con el contador que se decrementa</h4> - -<p>Para ilustrar un bucle con un contador de decremento, reescribirá la -función <code>triangle</code> así como el contador se -decrementa a cero. -</p> -<p>Esto es lo inverso de la versión temprana de la función. En este -caso, para encontrar cuántos asteriscos son necesarios para crear un -triángulo con 3 filas, añade el número de asteriscos en la -tercera fila, 3, para el número en la fila precedente, 2, y entonces -añade el total de estas dos filas a la fila que lo precede, 1. -</p> -<p>Más allá, para encontrar el número de asteriscos en un -triángulo con 7 filas, añade el número de asteriscos en la fila -siete, 7, al número en la fila precedente, que es 6, y entonces -añade el total de estas dos filas a la fila esta que lo precede, -que es 5, y así. Como en el ejemplo previo, cada -adición solo involucra la adición de dos números, el total de -las filas ya se añadió y el número de asteriscos en la fila que -está siendo añadida al total. Este proceso de añadir dos -números se repite de nuevo y de nuevo hasta que no haya más -asteriscos que añadir. -</p> -<p>Sabemos con cuántos asteriscos empezar: el número de asteriscos en -la última fila es igual al número de filas. Si el triángulo -tiene siete filas, el número de asteriscos en la última fila es -7. Más allá, sabemos cuántos asteriscos están en la fila -precedente: eso es uno menos que el número en la fila. -</p> -<hr> -<a name="Partes-de-Ejemplo-Dec"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-de-Decremento" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Bucle-que-se-decrementa" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-Dec-junto" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Las-partes-de-la-definicion-de-funcion-1"></a> -<h4 class="unnumberedsubsubsec">Las partes de la definición de función</h4> - -<p>Empezamos con tres variables: el número total de filas en el -triángulo; el número de asteriscos en una fila; y el número -total de asteriscos, que es lo que queremos calcular. Estas variables -pueden llamarse <code>number-of-rows</code>, -<code>number-of-pebbles-in-row</code>, y <code>total</code>, respectivamente. -</p> -<p>Ambos <code>total</code> y <code>number-of-pebbles-in-row</code> se usan solo -dentro de la función y se declaran con <code>let</code>. El valor -inicial de <code>total</code> sería cero. Sin embargo, el -valor inicial de <code>number-of-pebbles-in-row</code> sería -igual al número de filas en el triángulo, desde la adición -empezará con la fila más larga. -</p> -<p>Esto significa que el principio de la expresión <code>let</code> se verá -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((total 0) - (number-of-pebbles-in-row number-of-rows)) - <var>body</var>…) -</pre></div> - -<p>El número total de asteriscos puede encontrarse repetidamente -añadiendo el número de asteriscos en una fila para el total ya -encontrado, que, se evalúa repetidamente en la siguiente -expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq total (+ total number-of-pebbles-in-row)) -</pre></div> - -<p>Después el <code>number-of-pebbles-in-row</code> se añade al -<code>total</code>, el <code>number-of-pebbles-in-row</code> sería -decrementado por uno, desde que la siguiente vez el bucle repite, la -fila precedente será añadida al total. -</p> -<p>El número de asteriscos en una fila precedente es uno menos que el -número de asteriscos en una fila, así la función -Emacs Lisp construida <code>1-</code> puede usarse para computar el número -de asteriscos de la fila precedente. Esto puede ser hecho con la -siguiente expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq number-of-pebbles-in-row - (1- number-of-pebbles-in-row)) -</pre></div> - -<p>Finalmente, sabemos que el bucle <code>while</code> pararía -creando repetidas adiciones cuando no hay asteriscos en una -fila. Así el test para el bucle <code>while</code> es simple: -</p> -<div class="smallexample"> -<pre class="smallexample">(while (> number-of-pebbles-in-row 0) -</pre></div> - -<hr> -<a name="Ejemplo-Dec-junto"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-de-Ejemplo-Dec" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Bucle-que-se-decrementa" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Dolist-y-dotimes" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Poniendo-la-definicion-de-la-funcion-junta-1"></a> -<h4 class="unnumberedsubsubsec">Poniendo la definición de la función junta</h4> - -<p>Se pueden poner estas expresiones juntas para crear una definición de -función que funcione. Sin embargo, al examinarlas, encontraremos que -una de la variables locales ¡es innecesaria! -</p> -<p>La definición de función se ve como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Primero la versión substractiva.</span> -(defun triangle (number-of-rows) - "Añade el número de asteriscos en un triángulo." - (let ((total 0) - (number-of-pebbles-in-row number-of-rows)) - (while (> number-of-pebbles-in-row 0) - (setq total (+ total number-of-pebbles-in-row)) - (setq number-of-pebbles-in-row - (1- number-of-pebbles-in-row))) - total)) -</pre></div> - -<p>Como se dijo, esta función funciona. -</p> -<p>Sin embargo, no se necesita <code>number-of-pebbles-in-row</code>. -</p> -<a name="index-Argumento-como-variable-local"></a> -<p>Cuando la función <code>triangle</code> se evalúa, el -símbolo <code>number-of-rows</code> será asociado al -número, dando un valor inicial. Este número puede ser cambiado en -el cuerpo de la función si hubiera una variable local, sin miedo -de que tal cambio se efectuará el valor de la variable fuera de la -función. Esto es una característica muy útil de Lisp; -eso significa que la variable <code>number-of-rows</code> puede ser usada en -cualquier lugar en la función donde <code>number-of-pebbles-in-row</code> -se usa. -</p> -<p>Aquí hay una segunda versión de la función escrita un -poco más limpiamente: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle (number) ; <span class="roman">Segunda versión.</span> - "Devuelve la suma de números 1 a través de NUMBER inclusive." - (let ((total 0)) - (while (> number 0) - (setq total (+ total number)) - (setq number (1- number))) - total)) -</pre></div> - -<p>En breve, un bucle <code>while</code> apropiadamente escrito consistirá de -tres partes: -</p> -<ol> -<li> -Un test que devuelva falso después de que el bucle ha repetido por -sí mismo el número de veces correcto. - -</li><li> -Una expresión de la evaluación de que devolverá el valor deseado -después de ser repetidamente evaluado. - -</li><li> -Una expresión para cambiar el valor pasado al true-or-false-test -así el test devuelve falso después de que el bucle -se ha repetido por sí mismo el número de veces -correcto. -</li></ol> - -<hr> -<a name="Dolist-y-dotimes"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-Dec-junto" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#dolist" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ahorra-tiempo_003a-dolist-y-dotimes"></a> -<h2 class="section">11.2 Ahorra tiempo: <code>dolist</code> y <code>dotimes</code></h2> - -<p>Además de <code>while</code>, tanto <code>dolist</code> como <code>dotimes</code> -proveen un bucle. Algunas veces estos son rápidos para escribir -el bucle equivalente <code>while</code>. Ambos son macros -Lisp. (See <a href="elisp.html#Macros">Macros</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>.) -</p> -<p><code>dolist</code> funciona como un bucle <code>while</code> con ‘<small>CDR</small>s que -bajan la lista’: <code>dolist</code> automáticamente ordena la lista cada -vez que la lista hace bucles — toma la <small>CDR</small> de la lista — y -asocia el <small>CAR</small> de cada versión ordenada de la lista al primero -de sus argumentos. -</p> -<p><code>dotimes</code> repite el bucle un número específico de -veces: tu especificas el número. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#dolist">La macro <code>dolist</code></a></td><td> </td><td align="left" valign="top"> dolist -</td></tr> -<tr><td align="left" valign="top"><a href="#dotimes">La macro <code>dotimes</code></a></td><td> </td><td align="left" valign="top"> dotimes -</td></tr> -</table> - -<hr> -<a name="dolist"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Dolist-y-dotimes" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Dolist-y-dotimes" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#dotimes" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-macro-dolist"></a> -<h3 class="unnumberedsubsec">La macro <code>dolist</code></h3> -<a name="index-dolist"></a> - -<p>Supón, por ejemplo, que quieres invertir una lista, -así que “primero”, “segundo”, “tercero” llega a -ser “tercero”, “segundo”, “primero”. -</p> -<p>En la práctica, usarías la función <code>reverse</code>, -como esta: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(gacela jirafa leon tigre)) - -(reverse animales) -</pre></div> - -<p>Aquí se ve cómo se podría invertir la -lista usando un bucle <code>while</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(gacela jirafa leon tigre)) - -(defun reverse-list-with-while (list) - "Usando while, invierte el orden de LIST." - (let (value) ; asegura que la lista comienza vacía - (while list - (setq value (cons (car list) value)) - (setq list (cdr list))) - value)) - -(reverse-list-with-while animales) -</pre></div> - -<p>Y aquí se ve cómo podría usarse la macro -<code>dolist</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(gacela jirafa leon tigre)) - -(defun reverse-list-with-dolist (list) - "Usando dolist, reverse, la orden de la LISTA." - (let (value) ; asegura que la lista empieza vacía - (dolist (element list value) - (setq value (cons element value))))) - -(reverse-list-with-dolist animals) -</pre></div> - -<p>En Info, se puede localizar su cursor después de cerrar paréntesis -de cada expresión y escribir <kbd>C-x C-e</kbd>; en cada caso, se -vería -</p> -<div class="smallexample"> -<pre class="smallexample">(tigre leon jirafa gacela) -</pre></div> - -<p>en el área echo. -</p> -<p>Para este ejemplo, la función <code>reverse</code> existente es obviamente -la mejor. El bucle <code>while</code> es solo como nuestro primer ejemplo -(véase la sección <a href="#Ejemplo-de-bucle">Un bucle <code>while</code> y una lista</a>). El -<code>while</code> primero chequea si la lista tiene elementos; si es -así, eso construye una nueva lista añadiendo el primer -elemento de la lista a la lista existente (que en la primera -iteración del bucle es <code>nil</code>). Puesto que el segundo elemento -está asignado en frente del segundo elemento, la lista es inversa. -</p> -<p>En la expresión que usa el bucle <code>while</code>, la expresión -<code>(setq list (cdr list))</code> ordena la lista, así -el bucle <code>while</code> finalmente para. Además, se proporciona la -expresión <code>cons</code> con un nuevo primer elemento creando una nueva -lista y se ordena en cada repetición del bucle. -</p> -<p>La expresión <code>dolist</code> hace lo mismo que la expresión -<code>while</code>, excepto que la macro <code>dolist</code> hace algo del trabajo -que se tiene que hacer cuando se escribe una expresión <code>while</code>. -</p> -<p>Al igual que el bucle <code>while</code>, tenemos el bucle <code>dolist</code>. Lo -que es diferente es que automáticamente ordena la lista cada vez que -se repite — eso es ‘recorrer los <small>CDR</small>s de la lista’ en -sí — y eso automáticamente asocia el <small>CAR</small> de -cada versión ordenada de la lista al primero de sus argumentos. -</p> -<p>En el ejemplo, el <small>CAR</small> de cada versión ordenada de la lista se -refiere a usar el símbolo ‘<samp>element</samp>’, la lista en -sí se llama ‘<samp>list</samp>’, y el valor devuelto se llama -‘<samp>value</samp>’. El resto de la expresión <code>dolist</code> es el cuerpo. -</p> -<p>La expresión <code>dolist</code> asocia el <small>CAR</small> de cada versión -ordenada de la lista al <code>element</code> y entonces evalúa el cuerpo -de la expresión y repite el bucle. El resultado es devuelto en -<code>value</code>. -</p> -<hr> -<a name="dotimes"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#dolist" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Dolist-y-dotimes" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-macro-dotimes"></a> -<h3 class="unnumberedsubsec">La macro <code>dotimes</code></h3> -<a name="index-dotimes"></a> - -<p>La macro <code>dotimes</code> es similar a <code>dolist</code>, excepto que el -bucle se repite un número específico de veces. -</p> -<p>El primer argumento <code>dotimes</code> se asigna a los números 0, 1, 2 y -así vuelve al bucle, y el valor del tercer argumento se -devuelve. Se necesita proveer el valor del segundo argumento, que es -cuántas veces la macro hace el bucle. -</p> -<p>Por ejemplo, lo siguiente asocia los números de 0 en adelante, pero -no incluyendo, el número 3 al primer argumento, <var>número</var>, y -entonces construye una lista de los tres números. (El primer -número es 0, el segundo número es 1, y el tercer número es 2; -esto crea un total de tres números en todo, empezando con cero como -el primer número.) -</p> -<div class="smallexample"> -<pre class="smallexample">(let (value) ; de otro modo un valor es una variable vacía - (dotimes (number 3 value) - (setq value (cons number value)))) - -⇒ (2 1 0) -</pre></div> - -<p><code>dotimes</code> devuelve <code>value</code>, así el camino para -usar <code>dotimes</code> es para operar en alguna expresión el número -de veces <var>number</var> y entonces devolver el resultado, como una lista -o un átomo. -</p> -<p>Aquí hay un ejemplo de una <code>defun</code> que usa -<code>dotimes</code> para añadir el número de asteriscos en un triángulo. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-using-dotimes (number-of-rows) - "Usando dotimes, añade el número de asteriscos en un triángulo." -(let ((total 0)) ; de otro modo un total es una variable vacía - (dotimes (number number-of-rows total) - (setq total (+ total (1+ number)))))) - -(triangle-using-dotimes 4) -</pre></div> - -<hr> -<a name="Recursi_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#dotimes" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Construyendo-robots" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Recursion"></a> -<h2 class="section">11.3 Recursión</h2> -<a name="index-Recursion"></a> - -<p>Una función recursiva contiene código que hace que el intérprete -Lisp llame a un programa que ejecute el código en sí, -pero con argumentos ligeramente diferentes. El código ejecuta -exactamente lo mismo porque eso tiene el mismo nombre. Sin embargo, -incluso aunque el programa tenga el mismo nombre, no es la misma -entidad. Eso es diferente. En la jerga, se dice es una ‘instancia’ -diferente. -</p> -<p>Finalmente, si el programa se escribe correctamente, los ‘argumentos -ligeramente diferentes’ llegan a ser suficientemente diferentes puesto -que los primeros argumentos de la instancia final se pararán. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Construyendo-robots">11.3.1 Construyendo robots: Extendiendo la metáfora</a></td><td> </td><td align="left" valign="top"> Mismo modelo, diferente número serie ... -</td></tr> -<tr><td align="left" valign="top"><a href="#Partes-de-definici_00f3n-recursiva">11.3.2 Las partes de una definición recursiva</a></td><td> </td><td align="left" valign="top"> Paseo hasta que tu pares ... -</td></tr> -<tr><td align="left" valign="top"><a href="#Recursi_00f3n-con-lista">11.3.3 Recursión con una lista</a></td><td> </td><td align="left" valign="top"> Usando una lista con el test si para recurso. -</td></tr> -<tr><td align="left" valign="top"><a href="#Funci_00f3n-recursiva-tri_00e1ngulo">11.3.4 Recursión en lugar de un contador</a></td><td> </td><td align="left" valign="top"> Función recursiva triángulo -</td></tr> -<tr><td align="left" valign="top"><a href="#Recursi_00f3n-con-cond">11.3.5 Ejemplo de recursión usando <code>cond</code></a></td><td> </td><td align="left" valign="top"> Recursión con cond -</td></tr> -<tr><td align="left" valign="top"><a href="#Patrones-recursivos">11.3.6 Patrones recursivos</a></td><td> </td><td align="left" valign="top"> Plantillas usadas con frecuencia. -</td></tr> -<tr><td align="left" valign="top"><a href="#Sin-Aplazar">11.3.7 Recursión sin diferir</a></td><td> </td><td align="left" valign="top"> No almacenar trabajo ... -</td></tr> -<tr><td align="left" valign="top"><a href="#No-aplazar-la-soluci_00f3n">11.3.8 No hay solución pospuesta</a></td><td> </td><td align="left" valign="top"> No aplazar la solución -</td></tr> -</table> - -<hr> -<a name="Construyendo-robots"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-de-definici_00f3n-recursiva" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Construyendo-robots_003a-Extendiendo-la-metafora"></a> -<h3 class="subsection">11.3.1 Construyendo robots: Extendiendo la metáfora</h3> -<a name="index-Construyendo-robots"></a> -<a name="index-Robots_002c-construyendo"></a> - -<p>Algunas veces es útil pensar en un programa en ejecución como un -robot que hace un trabajo. Haciendo su trabajo, una función -recursiva llama a un segundo robot para que le ayude. El segundo robot es -idéntico al primero en cada paso, excepto que el segundo robot -ayuda al primero y se han pasado diferentes argumentos en vez del primero. -</p> -<p>En una función recursiva, el segundo robot puede llamar a un -tercero; y el tercero puede llamar a un cuarto, y -así. Cada una de estos es una entidad diferente; pero -todos son clones. -</p> -<p>Desde que cada robot tiene instrucciones ligeramente diferentes — -los argumentos diferirán desde un robot al siguiente — el último -robot conocería cuando pare. -</p> -<p>Permite expandir la metáfora en el que un programa de ordenador -es un robot. -</p> -<p>Una definición de función provee impresiones para un robot. Cuando -se instala una definición de función, que es, cuando se evalúa -una forma especial <code>defun</code>, se instala el equipamiento para -construir robots. Eso es como si tu estuvieras en una fábrica, -configurando una línea de ensamblaje. Los robots con el -mismo nombre son construidos de acuerdo a las mismas -impresiones. Así ellos tienen, como estaban, el mismo -‘número de modelo’, pero un diferente ‘número de serie’. -</p> -<p>Nosotros con frecuencia decimos que una función recursiva ‘se llama -así misma’. Esto significa que las instrucciones en una -función recursiva causa que el intérprete de Lisp ejecute una -función diferente que tiene el mismo nombre y hace el mismo trabajo -que el primero, pero con diferentes argumentos. -</p> -<p>Es importante que los argumentos difieran desde una instancia a la -siguiente; de otro modo, el proceso nunca parará. -</p> -<hr> -<a name="Partes-de-definici_00f3n-recursiva"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Construyendo-robots" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n-con-lista" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Las-partes-de-una-definicion-recursiva"></a> -<h3 class="subsection">11.3.2 Las partes de una definición recursiva</h3> -<a name="index-Partes-de-una-Definicion-Recursiva"></a> -<a name="index-Partes-de-definicion-recursiva"></a> - -<p>Una función recursiva típicamente contiene una -expresión condicional que tiene tres partes: -</p> -<ol> -<li> -Un true-or-false-test que determina si la función se llama de -nuevo, aquí se llama el <em>do-again-test</em>. - -</li><li> -El nombre de la función. Cuando este nombre se llama, es una nueva -instancia de la función — un nuevo robot, así — se -crea y se dice qué hacer. - -</li><li> -Una expresión que devuelve un valor diferente cada vez que la -función se llama, aquí llamada la -<em>next-step-expression</em>. Consecuentemente, el argumento (o -argumentos) pasados a la nueva instancia de la función serán -diferentes puesto que se pasa a la instancia previa. Esto causa la -expresión condicional, que el <em>do-again-test</em>, devuelva -falso después del número correcto de repeticiones. -</li></ol> - -<p>Las funciones recursivas pueden ser más simples que cualquier otro -tipo de funciones. De manera profunda, cuando la gente empieza a -usarlas, con frecuencia se miran así misteriosamente -de manera tan simple como incompresible. Como montar en bicicleta, leer una -función recursiva es duro al principio, pero después es simple. -</p> -<p>Hay varios patrones recursivos diferentes. Un patrón muy simple se -parece a: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun <var>name-of-recursive-function</var> (<var>argument-list</var>) - "<var>documentation</var>…" - (if <var>do-again-test</var> - <var>body</var>… - (<var>name-of-recursive-function</var> - <var>next-step-expression</var>))) -</pre></div> - -<p>Cada vez que una función recursiva es evaluada, una nueva instancia -se crea y se dice qué hacer. Los argumentos le dicen a la instancia -qué hacer. -</p> -<p>Un argumento se empareja al valor de la next-step-expresion. Cada -instancia se ejecuta con un valor diferente de la next-step-expression. -</p> -<p>El valor en la next-step-expression es usado en la do-again-test. -</p> -<p>El valor devuelto por la next-step-expression es pasada a las nuevas -instancias de la función, que lo evalúa (o alguna transformación -de eso) para determinar si continuar o parar. El next-step-expression -está diseñado así que el do-again-test devuelve -falso cuando la función no se repetiría mucho. -</p> -<p>El do-again-test es algunas veces llamado la <em>condición de -parar</em>, puesto que sirve para parar las repeticiones cuando se devuelve -falso. -</p> -<hr> -<a name="Recursi_00f3n-con-lista"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Partes-de-definici_00f3n-recursiva" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-recursiva-tri_00e1ngulo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Recursion-con-una-lista"></a> -<h3 class="subsection">11.3.3 Recursión con una lista</h3> - -<p>El ejemplo de un bucle <code>while</code> que imprimió los elementos de -una lista de números puede ser escrito -recursivamente. Aquí está el código, incluyendo una -expresión para asignar el valor de la variable <code>animales</code> a una -lista. -</p> -<p>Si está leyendo esto en el Info de Emacs, se puede evaluar esta -expresión directamente en Info. De otro modo, se debe copiar el -ejemplo al búffer ‘<tt>*scratch*</tt>’ y evalúa cada expresión -aquí. Usa <kbd>C-u C-x C-e</kbd> para evaluar la expresión -<code>(print-elements-recursively animals)</code> así que los -resultado se imprimen en el búffer; de otro modo el intérprete -Lisp intentará presionar los resultados dentro de una -línea del área echo. -</p> -<p>También, posiciona tu cursor inmediatamente después del último -paréntesis que cierra la función -<code>print-elements-recursively</code>, antes del comentario. De otro modo, -el intérprete Lisp intentará evaluar el comentario. -</p> -<a name="index-print_002delements_002drecursively"></a> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(gacela jirafa leon tigre)) - -(defun print-elements-recursively (list) - "Imprime cada elemento de la LISTA de la línea en - sí. Usa recursión." - (when list ; <span class="roman">do-again-test</span> - (print (car list)) ; <span class="roman">body</span> - (print-elements-recursively ; <span class="roman">recursive call</span> - (cdr list)))) ; <span class="roman">next-step-expression</span> - -(print-elements-recursively animales) -</pre></div> - -<p>La función <code>print-elements-recursively</code> primero chequea si hay -cualquier contenido en la lista; si lo hay, la función imprime el -primer elemento de la lista, el <small>CAR</small> de la lista. Entonces la -función se ‘invoca en sí’, pero da a sí -mismo como su argumento, no la lista completa, pero el segundo y -subsiguientes elementos de la lista, el <small>CDR</small> de la lista. -</p> -<p>Pon otro camino, si la lista no está vacía, la -función invoca otra instancia de código que es similar al código -inicial, pero es un hilo diferente de ejecución, con diferentes -argumentos a la primera instancia. -</p> -<p>Veamos una manera más, si la lista no está vacía, el -primer robot ensambla un segundo robot que cuenta qué hacer; el -segundo robot es un individuo diferente desde el principio, pero es el -mismo modelo. -</p> -<p>Cuando la segunda evaluación ocurre, la expresión <code>when</code> se -evalúa y si es verdad, se imprime el primer elemento de la lista que -recibe como su argumento (que es el segundo elemento de la lista -original). Entonces la función ‘llamarse a sí mismo’ -con la <small>CDR</small> del <small>CDR</small> de la lista original. -</p> -<p>Note que aunque nosotros decimos que la función ‘se llama a -sí misma’, lo que significa es que el intérprete Lisp -ensambla e instruye una nueva instancia del programa. La nueva -instancia es un clon del primero, pero es un individuo separado. -</p> -<p>Cada vez que la función ‘se invoca a sí misma’, se -invoca a sí misma en una versión de la lista -original. Eso crea una nueva instancia que funciona como una lista -ordenada. -</p> -<p>Finalmente, la función se invoca a sí misma en una -lista vacía. Eso crea una nueva instancia cuyo argumento -es <code>nil</code>. La expresión condicional chequea el valor de -<code>lista</code>. Desde el valor de <code>lista</code> a <code>nil</code>, la -expresión <code>when</code> devuelve falso así la then-part -no está evaluada. La función es como un todo que entonces devuelve -<code>nil</code>. -</p> -<p>Cuando se evalúa la expresión <code>(print-elements-recursively -animals)</code> en el búffer ‘<tt>*scratch*</tt>’, se verá este resultado: -</p> -<div class="smallexample"> -<pre class="smallexample">gacela - -jirafa - -leon - -tigre -nil -</pre></div> - -<hr> -<a name="Funci_00f3n-recursiva-tri_00e1ngulo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n-con-lista" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-recursivo-y-argumento-con-valor-1-o-2" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Recursion-en-lugar-de-un-contador"></a> -<h3 class="subsection">11.3.4 Recursión en lugar de un contador</h3> -<a name="index-triangle_002drecursively"></a> - -<p>La función <code>triangle</code> describe en una sección previa si puede -ser escrita recursivamente. Se ve así: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-recursively (number) - "Return the sum of the numbers 1 through NUMBER inclusive. -Uses recursion." - (if (= number 1) ; <span class="roman">do-again-test</span> - 1 ; <span class="roman">then-part</span> - (+ number ; <span class="roman">else-part</span> - (triangle-recursively ; <span class="roman">recursive call</span> - (1- number))))) ; <span class="roman">next-step-expression</span> - -(triangle-recursively 7) -</pre></div> - -<p>Se puede instalar esta función evaluando y entonces se intenta -evaluar <code>(triangle-recursively 7)</code>. (Recuerda poner tu cursor -inmediatamente después de los últimos paréntesis de la -definición de la función, antes del comentario.) La función -se evalúa a 28. -</p> -<p>Para comprender cómo funciona la función, hay que considerar qué -ocurre en varios casos cuando la función se le pasa 1, 2, 3, o 4 -como el valor a su argumento. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Ejemplo-recursivo-y-argumento-con-valor-1-o-2">Un argumento de 1 o 2</a></td><td> </td><td align="left" valign="top"> Ejemplo recursivo y - argumento con valor 1 o 2 -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejemplo-Recursivo-de-3-o-4-argumentos">Un argumento de 3 o 4</a></td><td> </td><td align="left" valign="top"> Ejemplo Recursivo de 3 o 4 - argumentos -</td></tr> -</table> - -<hr> -<a name="Ejemplo-recursivo-y-argumento-con-valor-1-o-2"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-recursiva-tri_00e1ngulo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-recursiva-tri_00e1ngulo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-Recursivo-de-3-o-4-argumentos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-argumento-de-1-o-2"></a> -<h4 class="unnumberedsubsubsec">Un argumento de 1 o 2</h4> - -<p>Primero, veamos qué ocurre si el valor del argumento es 1. -</p> -<p>La función tiene una expresión <code>if</code> después de la cadena de -documentación. Esto chequea si el valor de <code>number</code> es igual a -1; si es así, Emacs evalúa la then-part de la -expresión <code>if</code>, que devuelve el número 1 como el valor de la -función. (Un triángulo con una fila tiene un asterisco dentro.) -</p> -<p>Supón, sin embargo, que el valor del argumento es 2. En este caso, -Emacs evalúa la parte else de la expresión <code>if</code>. -</p> -<p>La parte else consiste de una adición, la llamada recursiva para -<code>triangle-recursively</code> y una acción de decremento; y se ve -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ number (triangle-recursively (1- number))) -</pre></div> - -<p>Cuando Emacs evalúa esta expresión, la expresión interna es -evaluada primero; entonces las otras partes en -secuencia. Aquí están los pasos en detalle: -</p> -<dl compact="compact"> -<dt><i>Paso 1 Evalúa la expresión interna.</i></dt> -<dd> -<p>La expresión interna es <code>(1- number)</code> así Emacs -decrementa el valor de <code>number</code> desde 2 a 1. -</p> -</dd> -<dt><i>Paso 2 Evalúa la función <code>triangle-recursively</code>.</i></dt> -<dd> -<p>El intérprete Lisp crea una instancia individual de -<code>triangle-recursively</code>. Eso no importa que esta función está -contenida con sí misma. Emacs pasa el resultado Paso 1 -como el argumento usado por esta instancia de la función -<code>triangle-recursively</code> -</p> -<p>En este caso, Emacs evalúa <code>triangle-recursively</code> con un -argumento de 1. Esto significa que esta evaluación de -<code>triangle-recursively</code> devuelve 1. -</p> -</dd> -<dt><i>Paso 3 Evalúa el valor de <code>number</code>.</i></dt> -<dd> -<p>La variable <code>number</code> es el segundo elemento de la lista que -empieza con <code>+</code>; su valor es 2. -</p> -</dd> -<dt><i>Paso 4 Evalúa la expresión <code>+</code>.</i></dt> -<dd> -<p>La expresión <code>+</code> recibe dos argumentos, el primero desde la -evaluación de <code>number</code> (Paso 3) y el segundo desde la -evaluación de <code>triangle-recursively</code> (Paso 2). -</p> -<p>El resultado de la adición es la suma de 2 + 1, y el número 3 es -devuelto, que es correcto. Un triángulo con dos filas tiene tres -asteriscos ahí. -</p></dd> -</dl> - -<hr> -<a name="Ejemplo-Recursivo-de-3-o-4-argumentos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-recursivo-y-argumento-con-valor-1-o-2" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Funci_00f3n-recursiva-tri_00e1ngulo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n-con-cond" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-argumento-de-3-o-4"></a> -<h4 class="unnumberedsubsubsec">Un argumento de 3 o 4</h4> - -<p>Supón que <code>triangle-recursively</code> es llamado con un argumento de -3. -</p> -<dl compact="compact"> -<dt><i>Paso 1 Evalúa la do-again-test.</i></dt> -<dd> -<p>La expresión <code>if</code> se evalúa primero. Esto es el test do-again -y devuelve falso, así la parte else de la expresión -<code>if</code> es evaluada. (Note que en este ejemplo, el do-again-test -causa la función para llamarse a sí misma cuando eso -se chequea como falso, no cuando eso se chequea como verdadero.) -</p> -</dd> -<dt><i>Paso 2 Evalúa la expresión propia de la parte else.</i></dt> -<dd> -<p>La expresión propia de la parte que es evaluada, decrementa 3 a -2. Esta la next-step-expression. -</p> -</dd> -<dt><i>Paso 3 Evalúa la función <code>triangle-recursively</code>.</i></dt> -<dd> -<p>El número 2 es pasado a la función <code>triangle-recursively</code>. -</p> -<p>Nosotros ya sabemos qué ocurre cuando Emacs evalúa -<code>triangle-recursively</code> con un argumento de 2. Después de ir a -través de la secuencia de acciones descritas temprano, eso devuelve -un valor de 3. Así que es lo que ocurrirá -aquí. -</p> -</dd> -<dt><i>Paso 4 Evalúa la adición.</i></dt> -<dd> -<p>3 será pasado como un argumento para la adición y será añadido -al número con el que la función se llamó, que es 3. -</p></dd> -</dl> - -<p>El valor devuelto por la función como un todo será 6. -</p> -<p>Ahora que sabemos qué ocurrirá cuando <code>triangle-recursively</code> -llama con un argumento 3, es evidente lo que ocurrirá si se llama -con el argumento 4: -</p> -<blockquote> -<p>En la llamada recursiva, la evaluación de -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle-recursively (1- 4)) -</pre></div> - -<p>devuelve el valor de evaluar -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle-recursively 3) -</pre></div> - -<p>que es 6 este valor será añadido a 4 por la adición en la -tercera línea. -</p></blockquote> - -<p>El valor devuelto por la función como un todo será 10. -</p> -<p>Cada vez que <code>triangle-recursively</code> se evalúa, se interpreta -una versión de sí misma — una instancia diferente en -sí — con un pequeño argumento, hasta que el -argumento es suficientemente pequeño así que no se -evalúa en sí. -</p> -<p>Note que este particular diseño para una función recursiva -requiere que las operaciones sean diferidas. -</p> -<p>Antes de que <code>(triangle-recursively 7)</code> pueda calcular su -respuesta, debe llamarse a <code>(triangle-recursively 6)</code>; y antes a -<code>(triangle-recursively 5)</code>; y así. Esto es decir, -que el cálculo de <code>(triangle-recursively 7)</code> a crear debe ser -diferido hasta que <code>(triangle-recursively 6)</code> haga su cálculo; -y <code>(triangle-recursively 5)</code> lo complete; y así. -</p> -<p>Si cada una de estas instancias de <code>triangle-recursively</code> son -pensadas como diferentes robots, el primer robot debe esperar por el -segundo para completar su trabajo, que debe esperar hasta los terceros -completos, y así. -</p> -<p>Hay un camino alrededor de este tipo de espera, que se discutirá en -<a href="#Sin-Aplazar">Recursión sin Defermentos.</a> -</p> -<hr> -<a name="Recursi_00f3n-con-cond"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-Recursivo-de-3-o-4-argumentos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Patrones-recursivos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejemplo-de-recursion-usando-cond"></a> -<h3 class="subsection">11.3.5 Ejemplo de recursión usando <code>cond</code></h3> -<a name="index-cond"></a> - -<p>La versión de <code>triangle-recursively</code> antes descrita se escribió -con la forma especial <code>if</code>. Eso puede también ser escrita -usando otra forma especial llamada <code>cond</code>. El nombre de la forma -especial <code>cond</code> es una abreviación de la palabra ‘<samp>conditional</samp>’. -</p> -<p>Aunque la forma especial <code>cond</code> no se usa con frecuencia en las -fuentes de Emacs como <code>if</code>, se usa con suficiente frecuencia para -justificarse explicando. -</p> -<p>La plantilla para una expresión <code>cond</code> se parece a: -</p> -<div class="smallexample"> -<pre class="smallexample">(cond - <var>body</var>…) -</pre></div> - -<p>donde el <var>body</var> es una serie de listas. -</p> -<p>Escrito de manera más completa, la plantilla se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(cond - (<var>first-true-or-false-test</var> <var>first-consequent</var>) - (<var>second-true-or-false-test</var> <var>second-consequent</var>) - (<var>third-true-or-false-test</var> <var>third-consequent</var>) - …) -</pre></div> - -<p>Cuando el intérprete Lisp evalúa la expresión <code>cond</code>, -evalúa el primer elemento (el <small>CAR</small> o true-or-false-test) de la -primera expresión en una serie de expresiones con el cuerpo del -<code>cond</code>. -</p> -<p>Si el true-or-false-test devuelve <code>nil</code> el resto de esta -expresión, el consecuente, se descarta y el true-or-false-test de la -siguiente expresión se evalúa. Cuando una expresión encuentra un -true-or-false-test cuyo valor no es <code>nil</code>, el consecuente de esta -expresión se evalúa. El consecuente puede ser una o más -expresiones. Si el consecuente consiste de más de una expresión, -las expresiones son evaluadas en secuencia y el valor del último se -devuelve. Si la expresión no tiene un consecuente, se devuelve el -valor del true-or-false-test. -</p> -<p>Si ninguno del test true-or-false-tests es cierto, la expresión -<code>cond</code> devuelve <code>nil</code>. -</p> -<p>Escrito usando <code>cond</code>, la función <code>triangle</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-using-cond (number) - (cond ((<= number 0) 0) - ((= number 1) 1) - ((> number 1) - (+ number (triangle-using-cond (1- number)))))) -</pre></div> - -<p>En este ejemplo, el <code>cond</code> devuelve 0 si el número es menor o -igual a 0, eso devuelve 1 si el número es 1 y eso evalúa <code>(+ -number (triangle-using-cond (1- number)))</code> si el número es más -grandes que 1. -</p> -<hr> -<a name="Patrones-recursivos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n-con-cond" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Cada" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Patrones-recursivos-1"></a> -<h3 class="subsection">11.3.6 Patrones recursivos</h3> -<a name="index-Patrones-recursivos"></a> - -<p>Aquí hay tres patrones recursivos. Cada uno involucra -una lista. La recursión no se necesita para involucrar listas, pero -Lisp se diseña para listas y esto provee un sentido de sus -capacidades primarias. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Cada">Patrón recursivo: <em>every</em></a></td><td> </td><td align="left" valign="top"> Cada -</td></tr> -<tr><td align="left" valign="top"><a href="#Acumular">Patrón recursivo: <em>accumulate</em></a></td><td> </td><td align="left" valign="top"> Acumular -</td></tr> -<tr><td align="left" valign="top"><a href="#Guardar">Patrón recursivo: <em>keep</em></a></td><td> </td><td align="left" valign="top"> Guardar -</td></tr> -</table> - -<hr> -<a name="Cada"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Patrones-recursivos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Patrones-recursivos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Acumular" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Patron-recursivo_003a-every"></a> -<h4 class="unnumberedsubsubsec">Patrón recursivo: <em>every</em></h4> -<a name="index-Every_002c-tipo-de-patron-recursivo"></a> -<a name="index-Patron-recursivo_003a-every"></a> - -<p>En el patrón recursivo <code>every</code>, se desarrolla una acción por -cada elemento de una lista. -</p> -<p>El patrón básico es: -</p> -<ul> -<li> -Si una lista es vacía, devuelve <code>nil</code>. -</li><li> -Else, act on the beginning of the list (the <small>CAR</small> of the list) - <ul class="no-bullet"> -<li>- - through a recursive call by the function on the rest (the <small>CDR</small>) of the -list, - </li><li>- - and, optionally, combine the acted-on element, using <code>cons</code>, with the -results of acting on the rest. - </li></ul> -</li></ul> - -<p>Aquí está el ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun square-each (numbers-list) - "El cuadrado de cada LISTA DE NUMEROS, recursivamente." - (if (not numbers-list) ; test-hazlo-de-nuevo - nil - (cons - (* (car numbers-list) (car numbers-list)) - (square-each (cdr numbers-list))))) ; expresion-siguiente-paso -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(square-each '(1 2 3)) - ⇒ (1 4 9) -</pre></div> - -<p>Si <code>numbers-list</code> está vacío, no hay que hacer -nada. Pero si tiene contenido, se construye una lista combinando el -cuadrado del primer número en la lista con el resultado de la -llamada recursiva. -</p> -<p>(El ejemplo sigue el patrón exactamente: se devuelve <code>nil</code> si -la lista de números es vacía. En la práctica, se -escribiría el condicional, así se ejecuta -la acción cuando la lista de números no es vacía.) -</p> -<p>La función <code>print-elements-recursively</code> (véase la sección <a href="#Recursi_00f3n-con-lista">Recursión con una Lista</a>) es otro ejemplo de un patrón -<code>every</code>, excepto en este caso, en vez de traer los resultados -juntos usando <code>cons</code>, se imprime cada elemento de salida. -</p> -<p>La función <code>print-elements-recursively</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq animales '(gacela jirafa leon tigre)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(defun print-elements-recursively (list) - "Imprime cada elemento de la LISTA de la línea en - sí. Usa recursión." - (when list ; <span class="roman">do-again-test</span> - (print (car list)) ; <span class="roman">body</span> - (print-elements-recursively ; <span class="roman">recursive call</span> - (cdr list)))) ; <span class="roman">next-step-expression</span> - -(print-elements-recursively animales) -</pre></div> - -<p>El patrón para <code>print-elements-recursively</code> es: -</p> -<ul> -<li> -Cuando la lista está vacía, no hacer nada. -</li><li> -But when the list has at least one element, - <ul class="no-bullet"> -<li>- - act on the beginning of the list (the <small>CAR</small> of the list), - </li><li>- - and make a recursive call on the rest (the <small>CDR</small>) of the list. - </li></ul> -</li></ul> - -<hr> -<a name="Acumular"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Cada" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Patrones-recursivos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Guardar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Patron-recursivo_003a-accumulate"></a> -<h4 class="unnumberedsubsubsec">Patrón recursivo: <em>accumulate</em></h4> -<a name="index-Acumular_002c-tipo-de-patron-recursivo"></a> -<a name="index-Patron-recursivo_003a-acumular"></a> - -<p>Otro patrón recursivo es llamado el patrón <code>accumulate</code>. En -el patrón recursivo <code>accumulate</code>, se realiza una acción en -cada elemento de una lista y el resultado de esta acción se acumula -con los resultados de desarrollar la acción en otros elementos. -</p> -<p>Esto es como ‘cada’ patrón usando <code>cons</code>, excepto que este -<code>cons</code> no se esté usando, pero que algún otro combine. -</p> -<p>El patrón es: -</p> -<ul> -<li> -Si una lista está vacía, devuelve cero o alguna otra -constante. -</li><li> -Else, act on the beginning of the list (the <small>CAR</small> of the list), - <ul class="no-bullet"> -<li>- - and combine that acted-on element, using <code>+</code> or some other combining -function, with - </li><li>- - a recursive call by the function on the rest (the <small>CDR</small>) of the list. - </li></ul> -</li></ul> - -<p>Aquí hay un ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun add-elements (numbers-list) - "Añade los elementos de NUMBERS-LIST juntos." - (if (not numbers-list) - 0 - (+ (car numbers-list) (add-elements (cdr numbers-list))))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(add-elements '(1 2 3 4)) - ⇒ 10 -</pre></div> - -<p>Véase la sección <a href="#Listar-ficheros">Creando una lista de ficheros</a>, para un ejemplo -del patrón acumulado. -</p> -<hr> -<a name="Guardar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Acumular" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Patrones-recursivos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Sin-Aplazar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Patron-recursivo_003a-keep"></a> -<h4 class="unnumberedsubsubsec">Patrón recursivo: <em>keep</em></h4> -<a name="index-Keep_002c-el-tipo-de-patron-recursivo"></a> -<a name="index-Patron-recursivo_003a-keep"></a> - -<p>Un tercer patrón es llamado el patrón <code>keep</code>. En el patrón -recursivo <code>keep</code>, se chequea cada elemento de una lista; se -actúa en el elemento y los resultados se guardan solo si el elemento -encuentra un criterio. -</p> -<p>De nuevo, esto se parece al patrón ‘every’, excepto que el elemento -se descarta a menos que se encuentre un criterio. -</p> -<p>El patrón tiene tres partes: -</p> -<ul> -<li> -Si una lista es vacía, devuelve <code>nil</code>. -</li><li> -Else, if the beginning of the list (the <small>CAR</small> of the list) passes a test - <ul class="no-bullet"> -<li>- - act on that element and combine it, using <code>cons</code> with - </li><li>- - a recursive call by the function on the rest (the <small>CDR</small>) of the list. - </li></ul> -</li><li> -Otherwise, if the beginning of the list (the <small>CAR</small> of the list) fails the -test - <ul class="no-bullet"> -<li>- - skip on that element, - </li><li>- - and, recursively call the function on the rest (the <small>CDR</small>) of the list. - </li></ul> -</li></ul> - -<p>Aquí hay un ejemplo que usa <code>cond</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun manten-tres-letras (lista-palabras) - "Guarda 3 palabras en WORD-LIST." - (cond - ;; Primero do-again-test: stop-condition - ((not lista-palabras) nil) - - ;; Segundo do-again-test: cuando actuar - ((eq 3 (length (symbol-name (car lista-palabras)))) - ;; combina el elemento que actúa con la llamada recursiva en la - ;; lista ordenada - (cons (car lista-palabras) (manten-tres-letras (cdr lista-palabras)))) - - ;; Tercero do-again-test: cuando se descarte el elemento; - ;; llama recursivamente a la lista ordenada con la next-step expression - (t (manten-tres-letras (cdr lista-palabras))))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(manten-tres-letras '(uno dos tres cuatro cinco seis)) - ⇒ (uno dos) -</pre></div> - -<p>Eso va sin decir que no se necesita usar <code>nil</code> como si el test -para cuando para; y se puede, de acuerdo, combinar estos patrones. -</p> -<hr> -<a name="Sin-Aplazar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Guardar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#No-aplazar-la-soluci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Recursion-sin-diferir"></a> -<h3 class="subsection">11.3.7 Recursión sin diferir</h3> -<a name="index-Diferir-en-recursion"></a> -<a name="index-Recursion-sin-diferir"></a> - -<p>Permita considerar de nuevo qué ocurre con la función -<code>triangle-recursively</code>. Nosotros encontraremos que los cálculos -difieran hasta que todo pueda ser hecho. -</p> -<p>Aquí está la definición de función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-recursively (number) - "Devuelve la suma de los números 1 a través de NUMBER inclusive -Usa recursión." - (if (= number 1) ; <span class="roman">do-again-test</span> - 1 ; <span class="roman">then-part</span> - (+ number ; <span class="roman">else-part</span> - (triangle-recursively ; <span class="roman">recursive call</span> - (1- number))))) ; <span class="roman">next-step-expression</span> -</pre></div> - -<p>¿Qué ocurre cuando se llama a esta función con un -argumento de 7? -</p> -<p>La primera instancia de la función <code>triangle-recursively</code> -añade el número 7 al valor devuelto por una segunda instancia de -<code>triangle-recursively</code>, una instancia que ha pasado un argumento -de 6. Así, el primer cálculo es: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 7 (triangle-recursively 6)) -</pre></div> - -<p>La primera instancia de <code>triangle-recursively</code> — se puede -querer pensar como un pequeño robot — no puede completar su -trabajo. Eso debe manejar el cálculo para -<code>(triangle-recursively 6)</code> a una segunda instancia del programa, -a un segundo robot. Este segundo individuo es completamente diferente -desde el primero; eso es, en la jerga, una ‘diferente -instanciación’. O, poner otro camino, eso es un diferente robot. Eso -es el mismo modelo como el primero; eso calcula números de -triángulo recursivamente; pero eso tiene un número de serie diferente. -</p> -<p>¿Y qué hace <code>(triangle-recursively 6)</code> -devuelve? Eso devuelve el número 6 añadido al valor devuelto para -evaluar <code>triangle-recursively</code> con un argumento de 5. Usando la -metáfora del robot, eso cuestiona todavía otro robot -para ayudarle. -</p> -<p>Ahora el total es: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 7 6 (triangle-recursively 5)) -</pre></div> - -<p>¿Y qué ocurre después? -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 7 6 5 (triangle-recursively 4)) -</pre></div> - -<p>Cada vez que <code>triangle-recursively</code> es llamado, excepto por la -última vez, eso crea otra instancia del programa — otro robot — -y pregunta para crear un cálculo. -</p> -<p>Finalmente, la adición completa es de la siguiente manera: -</p> -<div class="smallexample"> -<pre class="smallexample">(+ 7 6 5 4 3 2 1) -</pre></div> - -<p>Este diseño para la función difiere el cálculo del primer paso -hasta el segundo puede ser hecho, y difiere esto hasta que el tercero -puede ser hecho, y así. Cada defermento significa el -ordenador debe recordar que está siendo esperado dentro. Esto no es -un problema cuando hay solo unos pocos pasos, como en este -ejemplo. Pero eso puede ser un problema cuando hay más pasos. -</p> -<hr> -<a name="No-aplazar-la-soluci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Sin-Aplazar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-Bucle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="No-hay-solucion-pospuesta"></a> -<h3 class="subsection">11.3.8 No hay solución pospuesta</h3> -<a name="index-No-aplazar-la-solucion"></a> -<a name="index-Sin-posponer-la-solucion"></a> -<a name="index-Solucion-no-pospuesta"></a> - -<p>La solución al problema de operaciones pospuestas es para escribir -en una manera que no posponga operaciones<a name="DOCF12" href="#FOOT12">(12)</a>. Esto requiere escribir a un patrón diferente, con -frecuencia uno que involucra escribiendo dos definiciones de -función, una función de ‘inicialización’ y una función ‘ayuda’. -</p> -<p>La función ‘inicializacion’ configura el trabajo; la función -‘ayudante’ hace el trabajo. -</p> -<p>Aquí hay dos definiciones para añadir números. Son -así de simple, aunque se encuentre duro de comprender. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-initialization (number) - "Devuelve la suma de los números 1 a través de NUMBER inclusive. -Este es el componente de `inicialización' de una función dúo que -usa recursión" - (triangle-recursive-helper 0 0 number)) -</pre></div> - -<div class="smallexample"> -<pre class="smallexample">(defun triangle-recursive-helper (sum counter number) - "Devuelve SUM, usando COUNTER, a través de NUMBER inclusive. -Este es el componente `helper' de unas dos funciones -que usan recursión." - (if (> counter number) - sum - (triangle-recursive-helper (+ sum counter) ; <span class="roman">suma</span> - (1+ counter) ; <span class="roman">contador</span> - number))) ; <span class="roman">número</span> -</pre></div> - -<p>Instalar ambas definiciones de función por evaluarlo, entonces llama -a <code>triangle-initialization</code> con 2 filas: -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle-initialization 2) - ⇒ 3 -</pre></div> - -<p>La función ‘inicialización’ llama la primera instancia de la -función ‘ayudante’ con tres argumentos: cero, cero, y un número -que es el número de filas en el triángulo. -</p> -<p>Los primeros dos argumentos pasaron a la función ‘ayuda’ son valores -de inicialización. Estos valores son cambiados cuando -<code>triangle-recursive-helper</code> invocan nuevas -instancias.<a name="DOCF13" href="#FOOT13">(13)</a> -</p> -<p>Permítase ver que ocurre cuando tenemos un triángulo -que tiene una fila. (¡Este triángulo tendrá un -asterisco dentro!) -</p> -<p><code>triangle-initialization</code> llamará su ayudante con los -argumentos <code>0 0 1</code>. Esta función ejecutará el test -condicional si <code>(> counter number)</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(> 0 1) -</pre></div> - -<p>y encuentra que el resultado es falso, así invocará la -else-part de la claúsula <code>if</code>: -</p> -<div class="smallexample"> -<pre class="smallexample"> (triangle-recursive-helper - (+ sum counter) ; <span class="roman">sum más counter</span> ⇒ <span class="roman">sum</span> - (1+ counter) ; <span class="roman">incrementa counter</span> ⇒ <span class="roman">counter</span> - number) ; <span class="roman">number parece lo mismo</span> -</pre></div> - -<p>que computará primero: -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle-recursive-helper (+ 0 0) ; <span class="roman">sum</span> - (1+ 0) ; <span class="roman">counter</span> - 1) ; <span class="roman">number</span> -que es: - -(triangle-recursive-helper 0 1 1) -</pre></div> - -<p>De nuevo, <code>(> counter number)</code> será falso, así de -nuevo, el intérprete Lisp evaluará -<code>triangle-recursive-helper</code>, creando una nueva instancia con -nuevos argumentos. -</p> -<p>Esta nueva instancia será; -</p> -<div class="smallexample"> -<pre class="smallexample"> (triangle-recursive-helper - (+ sum counter) ; <span class="roman">suma más contador</span> ⇒ <span class="roman">sum</span> - (1+ counter) ; <span class="roman">incrementar contador</span> ⇒ <span class="roman">contador</span> - number) ; <span class="roman">número empieza lo mismo</span> - -que es: - -(triangle-recursive-helper 1 2 1) -</pre></div> - -<p>En este caso, el test <code>(> counter number)</code> ¡será -cierto! Así la instancia devolverá el valor de la -suma, que será 1, como se espera. -</p> -<p>Ahora, permite pasar <code>triangle-initialization</code> un argumento de 2, -para encontrar cuántos asterisco hay en un triángulo con dos filas. -</p> -<p>Esta función llama <code>(triangle-recursive-helper 0 0 2)</code>. -</p> -<p>En fases, las instancias llamadas serán: -</p> -<div class="smallexample"> -<pre class="smallexample"> <span class="roman">suma contador número</span> -(triangle-recursive-helper 0 1 2) - -(triangle-recursive-helper 1 2 2) - -(triangle-recursive-helper 3 3 2) -</pre></div> - -<p>Cuando la última instancia se llama, el <code>(> counter number)</code> se -chequea si será cierto, así la instancia devolverá -el valor de <code>sum</code>, que será 3. -</p> -<p>Este tipo de patrón ayuda cuando estás escribiendo funciones que -puede usar recursos en un ordenador. -</p> -<hr> -<a name="Ejercicio-de-Bucle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#No-aplazar-la-soluci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio-de-bucles"></a> -<h2 class="section">11.4 Ejercicio de bucles</h2> - -<ul> -<li> -Escribe una función similar a <code>triangle</code> en el que cada fila -tiene un valor que es la raíz del número de la -fila. Usa un bucle <code>while</code>. - -</li><li> -Escribe una función similar para <code>triangle</code> que multiplique en vez -de añadir los valores. - -</li><li> -Reescribe estas dos funciones recursivamente. Reescribe estas -funciones usando <code>cond</code>. - -</li><li> -Escribe una función para el modo Texinfo que crea una entrada -índice al principio de un párrafo para cada -‘<samp>@dfn</samp>’ con el párrafo. (En un fichero Texinfo, ‘<samp>@dfn</samp>’ -marca una definición. El libro es escrito en Texinfo.) - -<p>Muchas de las funciones necesitarán ser descritas en dos de los -capítulos, <a href="#Cortando-y-almacenando-texto">Cortando y almacenando texto</a> y <a href="#Pegando">Pegando texto</a>. Si usas -<code>forward-paragraph</code> para poner la entrada índice al -principio del párrafo, tendrá que usar <kbd><span class="nolinebreak">C-h</span> f</kbd> -(<code>describe-function</code>) para encontrar cómo conseguir que el comando -vaya hacia atrás. -</p> -<p>Para más información, ver -<a href="texinfo.html#Indicando">Indicando</a> in <cite>Manual de Texinfo</cite>, que va al -manual Texinfo en el actual directorio. O, si estás en Internet, -mira <a href="http://www.gnu.org/software/texinfo/manual/texinfo/">http://www.gnu.org/software/texinfo/manual/texinfo/</a> -</p></li></ul> - -<hr> -<a name="Buscar-regexp"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Bucles-y-recursi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-Bucle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#sentence_002dend" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Busquedas-de-expresiones-regulares"></a> -<h1 class="chapter">12 Búsquedas de expresiones regulares</h1> -<a name="index-Busquedas_002c-ilustrando"></a> -<a name="index-Busquedas-de-expresiones-regulares"></a> -<a name="index-Patrones_002c-buscando-por"></a> -<a name="index-Mover-frase-y-parrafo"></a> -<a name="index-Frases_002c-movimiento-por"></a> -<a name="index-Parrafos_002c-movimiento-por"></a> - -<p>Las búsquedas expresiones regulares son usadas extensivamente en GNU -Emacs. Las dos funciones <code>forward-sentence</code> y -<code>forward-paragraph</code>, ilustran estas búsquedas bien. Usan -expresiones regulares para encontrar donde mover el punto. La frase -‘expresión regular’ es con frecuencia escrita como ‘regexp’. -</p> -<p>Las búsquedas de expresiones regulares son descritas en -<a href="emacs.html#B_00fasqueda-de-Regexp">Búsqueda de Expresión Regular</a> in <cite>El Manual de GNU Emacs</cite>, tan bien como en <a href="elisp.html#Expresiones-Regulares">Expresiones Regulares</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>. Escribiendo -este capítulo, estoy presuponiendo que tiene al menos una -familiaridad con esto. El mayor punto para recordar es que las -expresiones regulares te permiten buscar patrones tan bien como para -cadenas literales de caracteres. Por ejemplo, el código en -<code>forward-sentence</code> busca para el patrón de posibles caracteres -que podrían marcar el fin de una frase, y mueve el punto -al otro lado. -</p> -<p>Antes de mirar en el código la función <code>forward-sentence</code>, es -valorable considerar que el patrón que marca el fin de una frase -debe estar. El patrón se discute en la siguiente sección; -siguiendo que es una descripción de la expresión regular de -búsqueda, <code>re-search-forward</code>. La función -<code>forward-sentence</code> es descrito en la sección -siguiente. Finalmente, la función <code>forward-paragraph</code> es -descrito en la última sección de este -capítulo. <code>forward-paragraph</code> es una función -compleja que introduce varias funcionalidades. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#sentence_002dend">12.1 La expresión regular para <code>sentence-end</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#re_002dsearch_002dforward">12.2 La función <code>re-search-forward</code></a></td><td> </td><td align="left" valign="top"> Muy similar a <code>search-forward</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#forward_002dsentence">12.3 <code>forward-sentence</code></a></td><td> </td><td align="left" valign="top"> Un ejemplo sencillo de búsqueda con - expresiones regulares. -</td></tr> -<tr><td align="left" valign="top"><a href="#forward_002dparagraph">12.4 <code>forward-paragraph</code>: una mina de oro de funciones</a></td><td> </td><td align="left" valign="top"> Un ejemplo complejo de alguna cosa. -</td></tr> -<tr><td align="left" valign="top"><a href="#etags">12.5 Crea tu propio fichero ‘<tt>TAGS</tt>’</a></td><td> </td><td align="left" valign="top"> Cómo crear tu propia tabla ‘<tt>TAGS</tt>’. -</td></tr> -<tr><td align="left" valign="top"><a href="#Revisar-regexp">12.6 Revisar</a></td><td> </td><td align="left" valign="top"> Revisar regexp -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-re_002dsearch">12.7 Ejercicios con <code>re-search-forward</code></a></td><td> </td><td align="left" valign="top"> Ejercicios re-search -</td></tr> -</table> - -<hr> -<a name="sentence_002dend"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#re_002dsearch_002dforward" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-expresion-regular-para-sentence_002dend"></a> -<h2 class="section">12.1 La expresión regular para <code>sentence-end</code></h2> -<a name="index-sentence_002dend"></a> - -<p>El símbolo <code>sentence-end</code> se asocia al patrón que -marca el fin de una frase. ¿Cuál sería -esta expresión regular? -</p> -<p>Claramente, una frase puede ser finalizada por un periodo, una marca -de inicio de interrogación, o una marca de exclamación. Puesto que -viene del inglés, solo las claúsulas que finalizan con uno de -estos tres caracteres deberían ser consideradas al fin de -una frase. Esto significa que el patrón incluiría el -conjunto de caracteres: -</p> -<div class="smallexample"> -<pre class="smallexample">[.?!] -</pre></div> - -<p>Sin embargo, no queremos que <code>forward-sentence</code> salte a un -periodo, una marca de pregunta, o una marca de exclamación, porque -tal carácter podría ser usado en el medio de una -frase. Un periodo, por ejemplo, se usa después de -abreviaciones. Así, otra información es necesaria. -</p> -<p>De acuerdo a la convención, escribe dos espacios después de cada -frase, pero solo un espacio después de un periodo, una marca de -pregunta, o una marca de exclamación seguida por dos espacios es un -buen indicador de un fin de frase. Sin embargo, en un fichero, los dos -espacios pueden ser un tabulador o el fin de una -línea. Esto significa que la expresión regular -incluiría estos tres ítems como -alternativas. -</p> -<p>Este grupo de alternativas se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">\\($\\| \\| \\) - ^ ^^ - TAB SPC -</pre></div> - -<p>Aquí, ‘<samp>$</samp>’ indica el fin de la línea, y -yo he apuntado donde el tab y dos espacios están insertados en la -expresión. Ambos están insertados poniendo los caracteres actuales -dentro de la expresión. -</p> -<p>Dos barras invertidas, ‘<samp>\\</samp>’, se requiere antes de los -paréntesis y barras verticales: la primera barra invertida cita la -siguiente barra invertida en Emacs; y el segundo indica que el -siguiente caracter, el paréntesis o la barra vertical, es especial. -</p> -<p>También, una frase puede ser seguida por uno o más retornos de -carro, como este: -</p> -<div class="smallexample"> -<pre class="smallexample">[ -]* -</pre></div> - -<p>Como en los tabuladores y espacios, un retorno de carro se inserta -dentro de una expresión regular insertándolo literalmente. El -asterisco indica que el <RET> se repite cero o más veces. -</p> -<p>Pero una frase no consiste solo en un periodo, una marca de pregunta o -una marca de exclamación seguida por espacios apropiados: una marca -de cerrar comillas o cerrar un paréntesis de algún tipo puede -preceder el espacio. En realidad más de una marca o paréntesis -pueden preceder el espacio. Estas requieren una expresión que se -parezca a: -</p> -<div class="smallexample"> -<pre class="smallexample">[]\"')}]* -</pre></div> - -<p>En esta expresión, el primer ‘<samp>]</samp>’ es el primer caracter en la -expresión; el segundo caracter es ‘<samp>"</samp>’, que está precedido -por un ‘<samp>\</samp>’ para contar Emacs el ‘<samp>"</samp>’ <em>no</em> es -especial. Los últimos tres caracteres son ‘<samp>'</samp>’, ‘<samp>)</samp>’, y -‘<samp>}</samp>’. -</p> -<p>Todo esto sugiere que el patrón de la expresión regular para -asociar el fin de una frase sería; y, profundamente, si -se evalúa <code>sentence-end</code> y encuentra que se devuelve el valor -siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">sentence-end - ⇒ "[.?!][]\"')}]*\\($\\| \\| \\)[ -]*" -</pre></div> - -<p>(Bien, no en GNU Emacs 22; porque es un esfuerzo crear el proceso -simple y manejar más símbolos y lenguajes. Cuando el -valor de <code>sentence-end</code> es <code>nil</code>, entonces usa el valor -definido por la función <code>sentence-end</code> es <code>nil</code>, entonces -usa el valor definido por la función -<code>sentence-end</code>. (Aquí se usa la diferencia entre un -valor y una función en Emacs Lisp.) La función devuelve un valor -construido desde las variables <code>sentence-end-base</code>, -<code>sentence-end-double-space</code>, <code>sentence-end-without-period</code>, -y <code>sentence-end-without-space</code>. La variable crítica -es <code>sentence-end-base</code>; su valor global es similar a uno descrito -debajo pero también contiene marcas de cita adicionales. Estas -tienen diferentes grados de curvas. La variable -<code>sentence-end-without-period</code>, cuando es verdad, dice a Emacs que -una frase puede finalizar sin un periodo tal como texto en Thai.) -</p> - -<hr> -<a name="re_002dsearch_002dforward"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#sentence_002dend" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dsentence" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-re_002dsearch_002dforward"></a> -<h2 class="section">12.2 La función <code>re-search-forward</code></h2> -<a name="index-re_002dsearch_002dforward"></a> - -<p>La función <code>re-search-forward</code> es similar a la función -<code>search-forward</code>. (Véase la sección <a href="#search_002dforward">La Función <code>search-forward</code></a>.) -</p> -<p><code>re-search-forward</code> busca una expresión regular. Si la -búsqueda es exitosa, deja el punto inmediatamente después del -último caracter en el objetivo. Si la búsqueda es hacia atrás, -deja el punto antes del primer caracter en el objetivo. Se puede -contar <code>re-search-forward</code> para devolver <code>t</code> a -cierto. (Moviendo el punto es por ello un ‘efecto lateral’.) -</p> -<p>Como <code>search-forward</code>, la función <code>re-search-forward</code> toma -cuatro argumentos: -</p> -<ol> -<li> -El primer argumento es la expresión regular que la función -busca. La expresión regular será una cadena entre comillas. - -</li><li> -El segundo argumento opcional limita cómo la función busca; es -un emparejamiento, que se especifica como una posición en el -búffer. - -</li><li> -El tercer argumento opcional especifica cómo la función responde al -fallo: <code>nil</code> como tercer argumento que causa la función para -señalar un error (e imprime un mensaje) cuando la búsqueda falla; -cualquier otro valor causa devolver <code>nil</code> si la búsqueda falla -y <code>t</code> si la búsqueda tiene éxito. - -</li><li> -El cuarto argumento opcional es el contaje repetido. Un contaje -negativo repetido causa <code>re-search-forward</code> para buscar hacia atrás. -</li></ol> - -<p>La plantilla para <code>re-search-forward</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(re-search-forward "<var>regular-expression</var>" - <var>limit-of-search</var> - <var>what-to-do-if-search-fails</var> - <var>repeat-count</var>) -</pre></div> - -<p>El segundo, tercer, y cuarto argumentos son opcionales. Sin embargo, -si se quiere pasar un valor a uno o ambos de los últimos dos -argumentos, se debe también pasar un valor a todos los argumentos -precedentes. De otro modo, el intérprete Lisp errará a qué -argumento estás pasando el valor. -</p> -<p>En la función <code>forward-sentence</code>, la expresión regular será -el valor de la variable <code>sentence-end</code>. En forma simple, esto es: -</p> -<div class="smallexample"> -<pre class="smallexample">"[.?!][]\"')}]*\\($\\| \\| \\)[ -]*" -</pre></div> - -<p>El límite de la búsqueda será el fin del párrafo -(desde una frase no puede ir bajo un párrafo). Si la búsqueda -falla, la función devuelve <code>nil</code>, y el contaje repite será -provisto por el argumento para la función <code>forward-sentence</code>. -</p> -<hr> -<a name="forward_002dsentence"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#re_002dsearch_002dforward" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Completa-forward_002dsentence" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="forward_002dsentence-1"></a> -<h2 class="section">12.3 <code>forward-sentence</code></h2> -<a name="index-forward_002dsentence"></a> - -<p>El comando mueve el cursor hacia adelante una frase es una -ilustración honesta de cómo usar búsquedas de expresiones -regulares en Emacs Lisp. En realidad, la función parece más larga -y más complicada de lo que es; esto es porque la función está -diseñada para ir hacia atrás tan bien como hacia adelante; y, -opcionalmente, a través de una frase. La función está -normalmente asociada al comando <kbd>M-e</kbd>. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Completa-forward_002dsentence">Completa la definición <code>forward-sentence</code></a></td><td> </td><td align="left" valign="top"> Completa forward-sentence -</td></tr> -<tr><td align="left" valign="top"><a href="#Bucles-while-fwd_002dsentence">Los bucles <code>while</code></a></td><td> </td><td align="left" valign="top"> Dos bucles <code>while</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Volver-a-buscar-la-frase-en-sentido-directo">La búsqueda de expresiones regulares</a></td><td> </td><td align="left" valign="top"> Una búsqueda de - expresión regular. -</td></tr> -</table> - -<hr> -<a name="Completa-forward_002dsentence"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dsentence" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dsentence" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-while-fwd_002dsentence" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Completa-la-definicion-forward_002dsentence"></a> -<h3 class="unnumberedsubsec">Completa la definición <code>forward-sentence</code></h3> - -<p>Aquí está la código para <code>forward-sentence</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun forward-sentence (&optional arg) - "Ve al siguiente `sentence-end'. Con el argumento, repite. -Con el argumento negativo, mueve atrás repetidamente a `sentence-beginning'. -La variable `sentence-end' es una expresión regular que empareja el -fin de frases. También, cada párrafo asociado termina las frases -bien. -</pre><pre class="smallexample"> (interactive "p") - (or arg (setq arg 1)) - (let ((opoint (point)) - (sentence-end (sentence-end))) - (while (< arg 0) - (let ((pos (point)) - (par-beg (save-excursion (start-of-paragraph-text) (point)))) - (if (and (re-search-backward sentence-end par-beg t) - (or (< (match-end 0) pos) - (re-search-backward sentence-end par-beg t))) - (goto-char (match-end 0)) - (goto-char par-beg))) - (setq arg (1+ arg))) -</pre><pre class="smallexample"> (while (> arg 0) - (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) - (if (re-search-forward sentence-end par-end t) - (skip-chars-backward " \t\n") - (goto-char par-end))) - (setq arg (1- arg))) - (constrain-to-field nil opoint t))) -</pre></div> - - -<p>La función se ve larga a primera vista y es mejor mirar primero el -esqueleto, y entonces su músculo. El camino para ver el esqueleto es -mirar en las expresiones que empiezan las columnas más a la -izquierda: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun forward-sentence (&optional arg) - "<var>documentation</var>…" - (interactive "p") - (or arg (setq arg 1)) - (let ((opoint (point)) (sentence-end (sentence-end))) - (while (< arg 0) - (let ((pos (point)) - (par-beg (save-excursion (start-of-paragraph-text) (point)))) - <var>rest-of-body-of-while-loop-when-going-backwards</var> - (while (> arg 0) - (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) - <var>rest-of-body-of-while-loop-when-going-forwards</var> - <var>handle-forms-and-equivalent</var> -</pre></div> - -<p>¡Esto parece bastante simple! La definición de la -función consiste de documentación una expresión -<code>interactive</code>, una expresión <code>or</code>, una expresión -<code>let</code>, y bucles <code>while</code>. -</p> -<p>Permite mirar cada una de estas partes. -</p> -<p>Notamos que la documentación es profunda y comprensible. -</p> -<p>La función tiene una declaración <code>interactive "p"</code>. Esto -signifca que el argumento prefijo, si cualquiera es pasado a la -función como su argumento. (Esto será un número.) Si la -función no pasa un argumento (eso es opcional) entonces el argumento -<code>arg</code> será asociado a 1. -</p> -<p>Cuando <code>forward-sentence</code> se llama no interactivamente sin un -argumento, <code>arg</code> está asignado <code>nil</code>. La expresión -<code>or</code> maneja esto. Lo que hace es dejar el valor de <code>arg</code> -como eso es, pero solo si <code>arg</code> está asignado a un valor; o eso -asigna el valor de <code>arg</code> a 1, en el caso de <code>arg</code> está -asignado a <code>nil</code>. -</p> -<p>Lo siguiente es un <code>let</code>. Que especifica los valores de dos -variables locales <code>point</code> y <code>sentence-end</code>. El valor local -de punto, desde antes de la búsqueda, es usada en la función -<code>constrain-to-field</code> que maneja formularios y equivalentes. La -variable <code>sentence-end</code> está asignada por la función -<code>sentence-end</code>. -</p> -<hr> -<a name="Bucles-while-fwd_002dsentence"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Completa-forward_002dsentence" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dsentence" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Volver-a-buscar-la-frase-en-sentido-directo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Los-bucles-while"></a> -<h3 class="unnumberedsubsec">Los bucles <code>while</code></h3> - -<p>Sigue dos bucles <code>while</code>. El primer <code>while</code> tiene un -true-or-false-test que chequea cierto si el argumento prefijo para -<code>forward-sentence</code> es un número negativo. Esto es para volver -hacia atrás. El cuerpo de este bucle es similar al cuerpo de la -segunda cláusula <code>while</code>, pero eso no es exactamente el -mismo. Se obviará este bucle <code>while</code> y concentra en el segundo -bucle <code>while</code>. -</p> -<p>El segundo bucle <code>while</code> está moviendo el punto hacia -adelante. Su esqueleto se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(while (> arg 0) ; <span class="roman">true-or-false-test</span> - (let <var>varlist</var> - (if (<var>true-or-false-test</var>) - <var>then-part</var> - <var>else-part</var> - (setq arg (1- arg)))) ; <code>while</code> <span class="roman">loop decrementer</span> -</pre></div> - -<p>El bucle <code>while</code> es el tipo de decremento. (Véase la sección <a href="#Bucle-que-se-decrementa">Un Bucle con un Contador de Decremento</a>.) Eso tiene un -true-or-false-test que chequea cierto tan largo con el contador (en -este caso, la variable <code>arg</code>) es mayor que cero; y eso tiene un -decremento que elimina 1 desde el valor del contador cada vez que el -bucle se repite. -</p> -<p>Si ningún argumento prefijo es dado para <code>forward-sentece</code>, que -es el camino más común es usado, este bucle <code>while</code> -ejecutará una vez, desde que el valor de <code>arg</code> será 1. -</p> -<p>El cuerpo del cuerpo <code>while</code> consite de una expresión -<code>let</code>, que crea y asocia una variable local, y tiene, su cuerpo, -una expresión <code>if</code>. -</p> -<p>El cuerpo del bucle <code>while</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((par-end - (save-excursion (end-of-paragraph-text) (point)))) - (if (re-search-forward sentence-end par-end t) - (skip-chars-backward " \t\n") - (goto-char par-end))) -</pre></div> - -<p>La expresión <code>let</code> crea y asocia la variable local -<code>par-end</code>. Como se ve, esta variable local está diseñada para -proporcionar una asociación o límite para la -búsqueda de la expresión regular. Si la búsqueda falla para -encontrar una frase apropiada finalizando en el párrafo, eso -se parará logrando el fin del párrafo. -</p> -<p>Pero primero, permítenos examinar cómo <code>par-end</code> -se asocia a la variable del fin del párrafo. Lo que ocurre es que el -<code>let</code> asigna el valor de <code>par-end</code> al valor devuelto cuando -el intérprete evalúa la expresión. -</p> -<div class="smallexample"> -<pre class="smallexample">(save-excursion (end-of-paragraph-text) (point)) -</pre></div> - -<p>En esta expresión, <code>(end-of-paragraph-text)</code> mueve el punto al -fin del párrafo, <code>(point)</code> devuelve el valor del punto, y -entonces <code>save-excursion</code> restaura el punto a su posición -original. De este modo, el <code>let</code> asocia <code>par-end</code> al valor -devuelto por la expresión <code>save-excursion</code>, que es la -posición del fin del párrafo. (La función -<code>end-of-paragraph-text</code> usa <code>forward-paragraph</code>, que se -discutirá pronto.) -</p> -<p>Emacs evalúa el cuerpo del <code>let</code>, que es una expresión -<code>if</code> que se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (re-search-forward sentence-end par-end t) ; <span class="roman">if-part</span> - (skip-chars-backward " \t\n") ; <span class="roman">then-part</span> - (goto-char par-end))) ; <span class="roman">else-part</span> -</pre></div> - -<p>El test <code>if</code> si su primer argumento es cierto y si -así, evalúa su parte then; de otro modo, el -intérprete Emacs Lisp evalúa la parte else. El true-or-false-test -de la expresión <code>if</code> es la búsqueda de la expresión regular. -</p> -<p>Puede estar mal tener que mirar como el ‘trabajo real’ de la función -<code>forward-sentence</code> es vista aquí, pero esto es un -camino común de este tipo de operación traida en Lisp. -</p> -<hr> -<a name="Volver-a-buscar-la-frase-en-sentido-directo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Bucles-while-fwd_002dsentence" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dsentence" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dparagraph" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-busqueda-de-expresiones-regulares"></a> -<h3 class="unnumberedsubsec">La búsqueda de expresiones regulares</h3> - -<p>La función <code>re-search-forward</code> busca el fin de la frase, que -es, para el patrón definido por la expresión regular -<code>sentence-end</code>. Si el patrón es encontrado — si el fin de la -frase se encuentra — entonces la función <code>re-search-forward</code> -hace dos cosas: -</p> -<ol> -<li> -La función <code>re-search-forward</code> trae un efecto lateral, que es -mover el punto al final de la ocurrencia encontrada. - -</li><li> -La función <code>re-search-forward</code> devuelve un valor de -verdad. Esto es el valor recibido por el <code>if</code>, y significa que la -búsqueda fué exitosa. -</li></ol> - -<p>El efecto lateral, el movimiento del punto se completa antes de la -función <code>if</code> y es manejado por el valor devuelto por la exitosa -conclusión de la búsqueda. -</p> -<p>Cuando la función <code>if</code> recibe el valor de verdad desde una -llamada exitosa a <code>re-search-forward</code>, el <code>if</code> evalúa la -parte then que es la expresión <code>(skip-chars-backward -"\t\n")</code>. Esta expresión se mueve atrás a través de espacios en -blanco, los tabuladores o retornos de carro hasta un caracter impreso -es encontrado y entonces deja el punto correcto después del caracter -impreso cerrado de la frase, que es normalmente un periodo. -</p> -<p>Por otro lado, si la función <code>re-search-forward</code> falla para -encontrar un patrón marcando el fin de la frase, la función -devuelve falso. Lo falso causa el <code>if</code> para evaluar su tercer -argumento, que es <code>(goto-char par-end)</code>: eso mueve el punto al -final del párrafo. -</p> -<p>(Y si el texto está en una forma o equivalente, y apunta a que no -puede moverse completamente entonces la función -<code>constrain-to-field</code> empieza a funcionar.) -</p> -<p>Las búsquedas de expresiones regulares son excepcionalmente útiles -y el patrón ilustrado por <code>re-search-forward</code>, en el que la -búsqueda es el test de una expresión <code>if</code>, es manejable. Se -verá o escribirá código incorporando este patrón con frecuencia. -</p> -<hr> -<a name="forward_002dparagraph"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Volver-a-buscar-la-frase-en-sentido-directo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dparagraph-en-breve" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="forward_002dparagraph_003a-una-mina-de-oro-de-funciones"></a> -<h2 class="section">12.4 <code>forward-paragraph</code>: una mina de oro de funciones</h2> -<a name="index-forward_002dparagraph"></a> - - -<p>La función <code>forward-paragraph</code> mueve el punto al fin del -párrafo. Eso está normalmente asociado a <kbd>M-}</kbd> y hace uso de -un número de funciones que son importantes en sí, -incluyendo <code>let*</code>, <code>match-beginning</code>, y <code>looking-at</code>. -</p> -<p>La definición de función para <code>forward-paragraph</code> es -considerablemente mayor que la definición de función para -<code>forward-sentence</code> porque eso funciona como un párrafo, cada -línea puede empezar con un prefijo de relleno <em>fill -prefix</em>. -</p> -<p>Un prefijo de relleno <em>fill prefix</em> consiste en una cadena de -caracteres que se repite al principio de cada -línea. Por ejemplo, en código Lisp, es una -convención para empezar cada línea de un comentario de -párrafo largo con ‘<samp>;;; </samp>’. En modo Texto, cuatro espacios en -blanco crean otro prefijo de relleno <em>fill prefix</em> común, -creando un párrafo indentado. (See <a href="emacs.html#Fill-Prefix">Fill Prefix</a> in <cite>The GNU Emacs Manual</cite> para más información acerca de prefijos de relleno -<em>fill prefix</em>.) -</p> -<p>La existencia de un prefijo de relleno significa que además de ser -capaz de encontrar el fin de un párrafo cuyas líneas -empiezan más a la izquierda, la función <code>forward-paragraph</code> -debe ser capaz de encontrar el fin de un párrafo cuando todas o -muchas de las líneas en el búffer empiezan con el -prefijo de relleno <em>fill prefix</em>. -</p> -<p>Más allá, es algunas veces práctico ignorar un prefijo de -relleno <em>fill prefix</em> que existe, especialmente cuando las -líneas en blanco separen párrafos. Esto es una -complicación añadida. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#forward_002dparagraph-en-breve">Definición de función <code>forward-paragraph</code></a></td><td> </td><td align="left" valign="top"> Partes clave de la definición de la - función. -</td></tr> -<tr><td align="left" valign="top"><a href="#fwd_002dpara-let">La expresión <code>let*</code></a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#fwd_002dpara-while">El bucle <code>while</code> hacia adelante</a></td><td> </td><td align="left" valign="top"> El bucle <code>while</code> con modo hacia adelante. -</td></tr> -</table> - -<hr> -<a name="forward_002dparagraph-en-breve"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dparagraph" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dparagraph" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#fwd_002dpara-let" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Definicion-de-funcion-forward_002dparagraph"></a> -<h3 class="unnumberedsubsec">Definición de función <code>forward-paragraph</code></h3> - -<p>En vez de imprimir toda la función <code>forward-paragraph</code>, -nosotros solo imprimiremos partes de la misma. ¡Lee sin -preparación, la función puede estar para desanimar! -</p> -<p>En esquema, la función se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun forward-paragraph (&optional arg) - "<var>documentation</var>…" - (interactive "p") - (or arg (setq arg 1)) - (let* - <var>varlist</var> - (while (and (< arg 0) (not (bobp))) ; <span class="roman">backward-moving-code</span> - … - (while (and (> arg 0) (not (eobp))) ; <span class="roman">forward-moving-code</span> - … -</pre></div> - -<p>Las primeras partes de la función son rutinas: la función lista -argumentos que consisten de un argumento opcional. La documentación sigue. -</p> -<p>La letra minúscula ‘<samp>p</samp>’ en la declaración <code>interactive</code> -significa que el argumento prefijo se procesa, si se pasa a la -función. Eso será un número, y es el contaje repetido de cuántos -párrafos se moverá. La expresión <code>or</code> en la siguiente -línea maneja el caso común cuando no hay argumentos -que se pasan a la función, esto ocurre si la función se llama -desde otro código en vez de interactivamente. Este caso se describe -pronto. (Véase la sección <a href="#forward_002dsentence">La función <code>forward-sentence</code></a>.) Ahora se logra el fin de la parte familiar -de esta función. -</p> -<hr> -<a name="fwd_002dpara-let"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dparagraph-en-breve" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dparagraph" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#fwd_002dpara-while" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-expresion-let_002a"></a> -<h3 class="unnumberedsubsec">La expresión <code>let*</code></h3> - -<p>La siguiente línea de la función -<code>forward-paragraph</code> empieza una expresión <code>let*</code>. Esto es -tan diferente como <code>let</code>. El símbolo es <code>let*</code> -no <code>let</code>. -</p> -<p>La forma especial <code>let*</code> es como <code>let</code> excepto que Emacs -asigna cada variable en secuencia, una después de otra, y las -variables en la última parte de la varlist hacen uso de los valores -para los que Emacs asignó variable al principio la varlist. -</p> - -<p>(<a href="#append-save_002dexcursion"><code>save-excursion</code> en <code>append-to-buffer</code></a>.) -</p> -<p>En la expresión <code>let*</code> en esta función, Emacs asigna un total -de siete variables: <code>opoint</code>, <code>fill-prefix-regexp</code>, -<code>parstart</code>, <code>parsep</code>, <code>sp-parstart</code>, <code>start</code>, y -<code>found-start</code>. -</p> -<p>La variable <code>parsep</code> aparece dos veces, primero, para borrar -instancias de ‘<samp>^</samp>’, y segundo, para manejar prefijos rellenos. -</p> -<p>La variable <code>opoint</code> es solo el valor de <code>point</code>. Como se -puede adivinar, eso se usa en una expresión -<code>constrain-to-field</code>, solo como en <code>forward-sentence</code>. -</p> -<p>La variable <code>fill-prefix-regexp</code> se asigna al valor devuelto para -evaluar la siguiente lista: -</p> -<div class="smallexample"> -<pre class="smallexample">(and fill-prefix - (not (equal fill-prefix "")) - (not paragraph-ignore-fill-prefix) - (regexp-quote fill-prefix)) -</pre></div> - -<p>Esta es una expresión cuyo primer elemento es la forma especial -<code>and</code>. -</p> -<p>Como se aprendió antes la (véase la sección <a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a>), la forma especial <code>and</code> evalúa cada uno de -sus argumentos hasta uno de los argumentos y devuelve un valor de -<code>nil</code> en el que el caso de la expresión <code>and</code> devuelve -<code>nil</code>; sin embargo, si ninguno de los argumentos devuelve un -valor de <code>nil</code>, el valor resultante de evaluar el último -argumento es devuelto. (Puesto que tal valor no es <code>nil</code>, eso es -considerado verdad en Lisp.) En otras palabras, una expresión -<code>and</code> devuelve un valor de verdad solo si todos sus argumentos -son verdad. -<a name="index-and-1"></a> -</p> -<p>En este caso, la variable <code>fill-prefix-regexp</code> está asociado a -un valor no <code>nil</code> solo si el las siguientes cuatro expresiones -producen un valor true (por ej., un no <code>nil</code>) cuando son -evaluados; de otro modo, <code>fill-prefix-regexp</code> está asociado a -<code>nil</code>. -</p> -<dl compact="compact"> -<dt><code>fill-prefix</code></dt> -<dd><p>Cuando esta variable se evalúa, el valor del prefijo de relleno -<em>fill prefix</em>, si cualquiera, está devuelto. Si no hay prefijo -relleno, la variable devuelve <code>nil</code>. -</p> -</dd> -<dt><code>(not (equal fill-prefix "")</code></dt> -<dd><p>Esta expresión chequea si un prefijo lleno es una cadena -vacía, que es, una cadena sin caracteres en eso. Una -cadena vacía no es útil un prefijo relleno <em>fill -prefix</em>. -</p> -</dd> -<dt><code>(not paragraph-ignore-fill-prefix)</code></dt> -<dd><p>Esta expresión devuelve <code>nil</code> si la variable -<code>paragraph-ignore-fill-prefix</code> ha sido cambiado siendo asignado -un valor de verdad tal como <code>t</code>. -</p> -</dd> -<dt><code>(regexp-quote fill-prefix)</code></dt> -<dd><p>Este es el último argumento para la forma especial <code>and</code>. Si -todos los argumentos de <code>and</code> son verdaderos, el valor resultante -de evaluar esta expresión será devuelto por la expresión -<code>and</code> y asociado a la variable <code>fill-prefix-regexp</code>, -</p></dd> -</dl> - -<a name="index-regexp_002dquote"></a> -<p>El resultado de evaluar esta expresión <code>and</code> con éxito es que -<code>fill-prefix-regexp</code> se asociará al valor de <code>fill-prefix</code> -como fué modificado por la función <code>regexp-quote</code>. Lo que -<code>regexp-quote</code> hace es leer una cadena y devolver la expresión -regular que asociará exactamente la cadena y nada más. Esto -significa que <code>fill-prefix-regexp</code> será asignada a un valor que -asociará el prefijo si el prefijo existe. De otro modo, la variable -será asignada a <code>nil</code>. -</p> -<p>Las dos variables locales siguientes en la expresión <code>let*</code> -están diseñadas para eliminar instancias de ‘<samp>^</samp>’ desde -<code>parstart</code> y <code>parsep</code>, las variables locales indican que -el párrafo empieza como separador de párrafo. La siguiente -expresión asigna <code>parsep</code> de nuevo. Esto es manejar prefijos -rellenos. -</p> -<p>Esta es la configuración que requiere la llamada de la definición -<code>let*</code> en vez de <code>let</code>. El true-or-false-test para el -<code>if</code> depende de si la variable <code>fill-prefix-regexp</code> evalúa -a <code>nil</code> o algún otro valor. -</p> -<p>Si <code>fill-prefix-regexp</code> no tiene un valor, Emacs evalúa la -parte else de la expresión <code>if</code> y asocia <code>parsep</code> a su -valor local. (<code>parsep</code> es una expresión regular que asocia lo -que los párrafos separan.) -</p> -<p>Pero si <code>fill-prefix-regexp</code> tiene un valor, Emacs evalúa la -parte then de la expresión <code>if</code> y asocia <code>parsep</code> a una -expresión regular que incluye el <code>fill-prefix-regexp</code> como -parte del patrón. -</p> -<p>Específicamente, <code>parsep</code> está asignado al valor -original del -párrafo que separa la expresión regular concatenada con una -expresión alternativa que consiste del <code>fill-prefix-regexp</code> -seguido por espacios en blanco opcionales para el fin de la -línea. El espacio en blanco está definido por -<code>"[ \t]*$"</code>.) El ‘<samp>\\|</samp>’ define esta porción del regexp -como una alternativa a <code>parsep</code>. -</p> -<p>De acuerdo a un comentario en el código, la siguiente variable -local, <code>sp-parstart</code>, se usa para buscar, y entonces los dos -finales, <code>start</code> y <code>found-start</code>, se asignan a <code>nil</code>. -</p> -<p>Ahora tenemos dentro el cuerpo del <code>let*</code>. La primera parte del -cuerpo del <code>let*</code> trata con el caso cuando la función es dada -a un argumento negativo y consiguientemente moviéndose hacia -atrás. Nosotros saldremos de esta sección yendo hacia atrás. -</p> -<hr> -<a name="fwd_002dpara-while"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#fwd_002dpara-let" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#forward_002dparagraph" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#etags" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-bucle-while-hacia-adelante"></a> -<h3 class="unnumberedsubsec">El bucle <code>while</code> hacia adelante</h3> - -<p>La segunda parte del cuerpo del <code>let*</code> trata con el proceso hacia -adelante. Eso es un bucle <code>while</code> que se repite si el valor de -<code>arg</code> es mayor que cero. En el uso más común de la función -el valor del argumento es 1, así el cuerpo del bucle -<code>while</code> se evalúa exactamente una vez, y el cursor se mueve -hacia adelante un párrafo. -</p> - -<p>Esta parte maneja tres situaciones: cuando el punto está entre -párrafos, cuando hay un prefijo de relleno y cuando no hay prefijo -de relleno <em>fill prefix</em>. -</p> -<p>El bucle <code>while</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">;; <span class="roman">yendo hacia adelante y no al fin del búffer</span> -(while (and (> arg 0) (not (eobp))) - - ;; <span class="roman">entre párrafos</span> - ;; Mueve hacia adelante a través de líneas de - ;; separación... - (while (and (not (eobp)) - (progn (move-to-left-margin) (not (eobp))) - (looking-at parsep)) - (forward-line 1)) - ;; <span class="roman">Esto decremento el bucle</span> - (unless (eobp) (setq arg (1- arg))) - ;; ... y una línea más - (forward-line 1) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (if fill-prefix-regexp - ;; Hay un prefijo lleno; que sobreescribe parstart; - ;; vamos adelante línea por línea - (while (and (not (eobp)) - (progn (move-to-left-margin) (not (eobp))) - (not (looking-at parsep)) - (looking-at fill-prefix-regexp)) - (forward-line 1)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; No hay prefijo; - ;; vamos hacia adelante caracter por caracter - (while (and (re-search-forward sp-parstart nil 1) - (progn (setq start (match-beginning 0)) - (goto-char start) - (not (eobp))) - (progn (move-to-left-margin) - (not (looking-at parsep))) - (or (not (looking-at parstart)) - (and use-hard-newlines - (not (get-text-property (1- start) 'hard))))) - (forward-char 1)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; y si no hay prefijo y si no estamos al final - ;; ir a lo que fué encontrado en la búsqueda de expresiones regulares - ;; para sp-parstart - (if (< (point) (point-max)) - (goto-char start)))) -</pre></div> - -<a name="index-eobp"></a> -<p>Se puede ver que esto es un contador de decremento <code>while</code>, -usando la expresión <code>(setq arg (1- arg))</code> como lo que se -decrementa. Esta expresión no está lejos desde el <code>while</code>, -pero está oculta en otra macro Lisp, una macro <code>unless</code>. A -menos que estemos al final del búffer — esto es lo que la -función <code>eobp</code> determina; eso es una abreviación de ‘<samp>Fin -del Buffer P</samp>’ — nosotros decrementamos el valor de <code>arg</code> por -uno. -</p> -<p>(Si estamos al fin del búffer, no podemos ir más hacia adelante y -el siguiente bucle de la expresión <code>while</code> chequeará falso -desde que el test es un <code>and</code> con <code>(not (eobp))</code>. La -función <code>not</code> significa exactamente como se esperaba; eso es -otro nombre de <code>null</code>, una función que devuelve cierto cuando -su argumento es falso.) -</p> -<p>De manera interesante, el bucle cuenta que no se decrementa -hasta que deje el espacio entre párrafos, a menos que vuelva al fin -del búffer o pare viendo el valor local del separador del párrafo. -</p> -<p>El segundo <code>while</code> también tiene una expresión -<code>(move-to-left-margin)</code>. La función es autoexplicativa. Eso -está dentro de una expresión <code>progn</code> y no el último -elemento de su cuerpo, así es solo invocado para su -efecto lateral, que es mover el punto al margen izquierdo de la -línea actual. -</p> -<a name="index-looking_002dat"></a> -<p>La función <code>looking-at</code> es también auto-explicativa; eso -devuelve cierto si el texto después del punto asocia la expresión -regular dada como su argumento. -</p> -<p>El resto del cuerpo del bucle se ve compleja al principio, pero tiene -sentido cuando se comprende. -</p> -<p>Primero considera que ocurre si hay un prefijo de relleno <em>fill -prefix</em>: -</p> -<div class="smallexample"> -<pre class="smallexample"> (if fill-prefix-regexp - ;; Hay un prefijo lleno; que sobreescribe parstart; - ;; vamos adelante línea por línea - (while (and (not (eobp)) - (progn (move-to-left-margin) (not (eobp))) - (not (looking-at parsep)) - (looking-at fill-prefix-regexp)) - (forward-line 1)) -</pre></div> - -<p>Esta expresión mueve el punto hacia adelante línea por -línea tan lejos como que las cuatro condiciones son ciertas: -</p> -<ol> -<li> -Punto no está al final del búffer. - -</li><li> -Podemos mover al margen izquierdo del texto y no estar al fin del búffer. - -</li><li> -El siguiente punto no separa párrafos. - -</li><li> -El patrón que sigue el punto es la expresión regular prefija rellena. -</li></ol> - -<p>La última condición puede ser un puzzle, hasta que se recuerde qué -punto fué movido al principio de la línea temprana en -la función <code>forward-paragraph</code>. Esto significa que si el texto -tiene el prefijo relleno, la función <code>looking-at</code> se verá. -</p> -<p>Considera qué ocurre cuando no hay un prefijo lleno. -</p> -<div class="smallexample"> -<pre class="smallexample"> (while (and (re-search-forward sp-parstart nil 1) - (progn (setq start (match-beginning 0)) - (goto-char start) - (not (eobp))) - (progn (move-to-left-margin) - (not (looking-at parsep))) - (or (not (looking-at parstart)) - (and use-hard-newlines - (not (get-text-property (1- start) 'hard))))) - (forward-char 1)) -</pre></div> - -<p>El bucle <code>while</code> nos tiene buscando hacia adelante para -<code>sp-parstart</code>, que es la combinación de posibles espacios en -blanco con un valor local del comienzo de un párrafo o de un -párrafo separador. (Las últimas dos son con una expresión -empezando con <code>(?:)</code> así que no están -referenciadas por la función <code>match-beginning</code>.) -</p> -<p>Las dos expresiones, -</p> -<div class="smallexample"> -<pre class="smallexample">(setq start (match-beginning 0)) -(goto-char start) -</pre></div> - -<p>significa ir al comienzo del siguiente texto localizado por la -expresión regular. -</p> -<p>La expresión <code>(match-beginning 0)</code> es nueva. Eso devuelve un -número especificando la posición del comienzo del texto fuese -asociado a la última búsqueda. -</p> -<p>La función <code>match-beginning</code> es usado aquí porque -una característica de una búsqueda hacia adelante: una -búsqueda hacia adelante, sin dignidad si eso es una búsqueda plana -o una expresión regular, mueve el punto al fin del texto que es -encontrado. En este caso, una búsqueda exitosa mueve el punto al -fin del patrón para <code>sp-parstart</code>. -</p> -<p>Sin embargo, se quiere poner el punto al fin del actual párrafo, no -en algún lugar más. En vez de eso, desde que la búsqueda -posiblemente incluye el separador del párrafo, el punto puede -finalizar al principio de lo siguiente a menos que se use una -expresión que incluya <code>match-beginning</code>. -</p> -<a name="index-match_002dbeginning"></a> -<p>Cuando un argumento de 0, <code>match-beginning</code> devuelve la posición -que es el comienzo del texto asociado por la búsqueda más -reciente. En este caso, la búsqueda más reciente parece -<code>sp-parstart</code>. La expresión <code>(match-beginning 0)</code> devuelve -la posición del comienzo de este patrón, en vez de la posición -final de este patrón. -</p> -<p>(Incidentalmente, cuando se pasa un número positivo como un -argumento, la función <code>match-beginning</code> devuelve la -localización de punto en el que la expresión con paréntesis en -la última búsqueda a menos que la expresión con paréntesis -empiece con <code>\(?:</code>. No sé porque <code>\(?:</code> aparece -aquí desde que el argumento es 0.) -</p> -<p>La última expresión cuando no hay prefijos es -</p> -<div class="smallexample"> -<pre class="smallexample">(if (< (point) (point-max)) - (goto-char start)))) -</pre></div> - -<p>Esto dice que si no hay prefijo lleno y no estamos al punto final que -se movería al principio de lo que fué encontrado por -la búsqueda de la expresión regular para <code>sp-parstart</code>. -</p> -<p>La definición completa para la función <code>forward-paragraph</code> no -solo incluye código para avanzar, también código para retroceder. -</p> -<p>Si está leyendo esto dentro de GNU Emacs y quieres ver la función -completa, se puede escribir <kbd>C-h f</kbd> (<code>describe-function</code>) y -el nombre de la función. Esto da la documentación de función -y el nombre de la librería conteniendo las fuentes de la -función. Posiciona el punto a través del nombre de la -librería y presionar la tecla RET; será tomado -directamente a las fuentes. (¡Asegúrate de instalar las -fuentes! ¡Sin eso, estarás como una persona que intenta -conducir un coche con los ojos cerrados!) -</p> -<hr> -<a name="etags"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#fwd_002dpara-while" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Revisar-regexp" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Crea-tu-propio-fichero-TAGS"></a> -<h2 class="section">12.5 Crea tu propio fichero ‘<tt>TAGS</tt>’</h2> -<a name="index-etags"></a> -<a name="index-fichero-de-TAGS_002c-crea-el-propio"></a> - -<p>Bajo <kbd>C-h f</kbd> (<code>describe-function</code>), otro camino para ver la -fuente de una función es escribir <kbd>M-.</kbd> (<code>find-tag</code>) y el -nombre de la función se asigna para eso. Esto es un buen hábito -para obtenerlo. El comando <kbd>M-.</kbd> (<code>find-tag</code>) toma -directamente a las fuentes de una función, variable, o nodo. La -función depende de tablas de etiquetas para saber donde ir. -</p> -<p>Si la función <code>find-tag</code> pregunta primero por el nombre de una -tabla ‘<tt>TAGS</tt>’, dado el nombre de un fichero ‘<tt>TAGS</tt>’ tal como -‘<tt>/usr/local/src/emacs/src/TAGS</tt>’. (La ruta exacta a tu fichero -‘<tt>TAGS</tt>’ depende de cómo tu copia de Emacs fué instalada. Yo -te cuento la localización que provee tanto mi C y mis fuentes de -Emacs Lisp.) -</p> -<p>Se puede también crear tu propio fichero ‘<tt>TAGS</tt>’ para los directorios -que faltan. -</p> -<p>Con frecuencia se necesita construir e instalar etiquetas de tablas -por uno mismo. Esas no son construidas automáticamente. Una tabla de -etiquetas llama a un fichero ‘<tt>TAGS</tt>’; el nombre es letras -mayúsculas. -</p> -<p>Se puede crear un fichero ‘<tt>TAGS</tt>’ llamando el programa -<code>etags</code> que viene como parte de la distribución -Emacs. Normalmente, <code>etags</code> está compilado e instalado cuando -Emacs se construye. (<code>etags</code> no es una función Lisp o una parte -de Emacs; eso es un programa C.) -</p> -<p>Para crear el fichero ‘<tt>TAGS</tt>’, primero cambia el directorio en el -que se quiere crear el fichero. En Emacs se puede hacer esto con el -comando <kbd>M-x cd</kbd>, o visitando un fichero en el directorio, o -listando el directorio <code>etags *.el</code> como el comando a ejecutar -</p> -<div class="smallexample"> -<pre class="smallexample">M-x compile RET etags *.el RET -</pre></div> - -<p>crear un fichero de ‘<tt>TAGS</tt>’ para Emacs Lisp. -</p> -<p>Por ejemplo, si se tiene un gran número de ficheros en el -directorio ‘<tt>~/emacs</tt>’, como se hace — Yo tengo 137 ‘<tt>.el</tt>’ -dentro, de que se carguen 12 — se puede crear un fichero ‘<tt>TAGS</tt>’ -para los ficheros Emacs Lisp en este directorio. -</p> -<p>El programa <code>etags</code> toma en toda la consola usual ‘comodines’. Por -ejemplo, si tienes dos directorios para el que quieres un fichero -‘<tt>TAGS</tt>’ simple, escribe <code>etags *.el ../elisp/*.el</code>, donde -‘<tt>../elisp/</tt>’ es el segundo directorio: -</p> -<div class="smallexample"> -<pre class="smallexample">M-x compile RET etags *.el ../elisp/*.el RET -</pre></div> - -<p>Tipo -</p> -<div class="smallexample"> -<pre class="smallexample">M-x compile RET etags --help RET -</pre></div> - -<p>para ver una lista de las opciones aceptadas por <code>etags</code> tan bien -como una lista de lenguajes soportados. -</p> -<p>El programa <code>etags</code> maneja más de 20 lenguajes, incluyendo -Emacs Lisp, Common Lisp, Scheme, C, C++, Ada, Fortran, HTML, Java, -LaTeX, Pascal, Perl, Postscript, Python, TeX, Texinfo, makefiles, y la -mayoría de ensambladores. El programa no cambia para -especificar el lenguaje; eso reconoce el lenguaje como una entrada de -fichero de acuerdo a su nombre de fichero y contenidos. -</p> -<p>‘<tt>etags</tt>’ es muy útil cuando se escribe código por -tí mismo y quiere referirse a funciones que ya se han -escrito. Ahora ejecuta <code>etags</code> de nuevo en intervalos como se -escriben nuevas funciones, así llegan a ser parte del -fichero ‘<tt>TAGS</tt>’. -</p> -<p>Si piensa que un fichero ‘<tt>TAGS</tt>’ apropiado que ya existe para lo -que quieres, pero no conoces donde está, se puede usar el programa -<code>locate</code> para intentar encontrarlo. -</p> -<p>Escribe <kbd><span class="nolinebreak">M-x</span> locate <RET> TAGS <RET></kbd> y Emacs -listará para ti las rutas nombres completas de todos tus ficheros -‘<tt>TAGS</tt>’. En mi sistema, este comando lista 34 fichero ‘<tt>TAGS</tt>’. -Por otro lado, un sistema ‘vanilla plano’ que recientemente no -contenía fichero ‘<tt>TAGS</tt>’. -</p> -<p>Si la tabla de etiquetas que se quiere ha sido creada, se puede usar -el comando <code>M-x visit-tags-table</code> para especificarlo. De otro -modo, se necesitará la tabla de etiquetas por tí mismo -y entonces usar <code>M-x visit-tags-table</code>. -</p> -<a name="Construyendo-Etiquetas-en-las-fuentes-Emacs"></a> -<h4 class="subsubheading">Construyendo Etiquetas en las fuentes Emacs</h4> -<a name="index-Construyendo-Etiquetas-en-las-fuentes-Emacs"></a> -<a name="index-Etiquetas-en-las-fuentes-Emacs"></a> -<a name="index-crear-etiquetas"></a> - -<p>Las fuentes GNU Emacs vienen con un ‘<tt>Makefile</tt>’ que contiene un -comando sofisticado <code>etags</code> que crea, recoge, y asocia tablas de -etiquetas de todas las fuentes de Emacs y pone la información dentro -de un fichero ‘<tt>TAGS</tt>’ en el directorio ‘<tt>src/</tt>’. (El directorio -‘<tt>src/</tt>’ está debajo del alto nivel de tu directorio Emacs.) -</p> -<p>Para construir este fichero ‘<tt>TAGS</tt>’, se puede ir al alto nivel de -directorio de fuentes Emacs y ejecutar el comando de compilar <code>make -tags</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">M-x compile RET make tags RET -</pre></div> - -<p>(El comando <code>make tags</code> trabaja bien con las fuentes de GNU -Emacs, tan bien como con otros paquetes fuentes.) -</p> -<p>Para más información, mira <a href="emacs.html#Etiquetas">Tablas de Etiquetas</a> in <cite>El Manual GNU Emacs</cite>. -</p> -<hr> -<a name="Revisar-regexp"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#etags" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-re_002dsearch" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Revisar-5"></a> -<h2 class="section">12.6 Revisar</h2> - -<p>Aquí hay un breve resumen de algunas funciones -introducidas recientemente. -</p> -<dl compact="compact"> -<dt><code>while</code></dt> -<dd><p>Repetidamente evalúa el cuerpo de la expresión tan larga como el -primer elemento del cuerpo chequea cierto. Entonces devuelve -<code>nil</code>. (La expresión es evaluado solo por sus efectos laterales.) -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((foo 2)) - (while (> foo 0) - (insert (format "foo is %d.\n" foo)) - (setq foo (1- foo)))) - - ⇒ foo is 2. - foo is 1. - nil -</pre></div> - -<p>(La función <code>insert</code> inserta sus argumentos en el punto; la -función <code>format</code> devuelve una cadena formateada desde sus -argumentos el camino <code>message</code> formatea sus argumentos; <code>\n</code> -produce una nueva línea.) -</p> -</dd> -<dt><code>re-search-forward</code></dt> -<dd><p>Busca un patrón, y si el patrón se encuentra, mueve el punto al -resto solo después de eso. -</p> -<p>Toma cuatro argumentos, como <code>search-forward</code>: -</p> -<ol> -<li> -Una expresión regular que especifica el patrón para -buscarlo. (¡Recuerda por marcas de comillas alrededor de -este argumento!) - -</li><li> -Opcionalmente, el límite de la búsqueda. - -</li><li> -Opcionalmente, que haces si la búsqueda falla, devuelve <code>nil</code> o -un mensaje de error. - -</li><li> -Opcionalmente, cuántas veces se puede repetir la búsqueda; si es -negativa, la búsqueda va hacia atrás. -</li></ol> - -</dd> -<dt><code>let*</code></dt> -<dd><p>Asocia algunas variables localmente a valores particulares, y entonces -evalúa los argumentos que permanencen, devolviendo el valor del -último. Mientras se asocian las variables locales, se usan los -valores locales de variables asociadas pronto, si acaso. -</p> -<p>Por ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(let* ((foo 7) - (bar (* 3 foo))) - (message "`bar' is %d." bar)) - ⇒ `bar' is 21. -</pre></div> - -</dd> -<dt><code>match-beginning</code></dt> -<dd><p>Devuelve la posición del principio del texto encontrado por la -última búsqueda de la expresión regular. -</p> -</dd> -<dt><code>looking-at</code></dt> -<dd><p>Devuelve <code>t</code> para verdadero si el texto después del punto se -asocia al argumento, que debería ser una expresión. -</p> -</dd> -<dt><code>eobp</code></dt> -<dd><p>Devuelve <code>t</code> para cierto si el punto está en el fin de la parte -accesible de un búffer. El fin de la parte accesible es el fin del -búffer no está encogido; eso es el fin de la parte encogida si el -búffer está encogido. -</p></dd> -</dl> - -<hr> -<a name="Ejercicios-re_002dsearch"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Revisar-regexp" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Buscar-regexp" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicios-con-re_002dsearch_002dforward"></a> -<h2 class="section">12.7 Ejercicios con <code>re-search-forward</code></h2> - -<ul> -<li> -Escribe una función para buscar para una expresión que detecte dos -o más líneas blancas en secuencia. - -</li><li> -Escribe una función para buscar palabras duplicadas, tales como ‘el -el’. See <a href="emacs.html#Regexps">Sintaxis para Expresiones Regulares</a> in <cite>El Manual de GNU Emacs</cite>, para información de cómo escribir un regexp -(una expresión regular) para asociar una cadena que se compone de -dos mitades idénticas. Se puede disponer de varios regexps; algunos -son mejores que otros. La función que se usa es descrito en un -apéndice, a lo largo de varios regexps. Véase la sección <a href="#the_002dthe">Función de Palabras Duplicadas <code>the-the</code></a>. -</li></ul> - -<hr> -<a name="Contando-palabras"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Buscar-regexp" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-re_002dsearch" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Por-qu_00e9-Contar-Palabras" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Contando_003a-repeticion-y-regexps"></a> -<h1 class="chapter">13 Contando: repetición y regexps</h1> -<a name="index-Repeticion-para-contar-palabras"></a> -<a name="index-Expresiones-regulares-para-contar-palabras"></a> - -<p>La repetición y búsqueda de expresiones regulares son herramientas -poderosas que con frecuencia se usan cuando se escribe código en Emacs -Lisp. Este capítulo ilustra el uso de búsqueda de -expresiones regulares a través de la construcción de comandos de -contaje de palabras usando bucles <code>while</code> y recursión. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Por-qu_00e9-Contar-Palabras">Contando palabras</a></td><td> </td><td align="left" valign="top"> Por qué Contar Palabras -</td></tr> -<tr><td align="left" valign="top"><a href="#count_002dwords_002dexample">13.1 La función <code>count-words-example</code></a></td><td> </td><td align="left" valign="top"> Usa un regexp, pero encuentra un problema. -</td></tr> -<tr><td align="left" valign="top"><a href="#recursive_002dcount_002dwords">13.2 Cuenta palabras recursivamente</a></td><td> </td><td align="left" valign="top"> Empezar en caso de que no haya palabras en la - región. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-Contar">13.3 Ejercicio: contando puntuación</a></td><td> </td><td align="left" valign="top"> Ejercicio de Contar -</td></tr> -</table> - -<hr> -<a name="Por-qu_00e9-Contar-Palabras"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Contando-palabras" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#count_002dwords_002dexample" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Contando-palabras-1"></a> -<h2 class="unnumberedsec">Contando palabras</h2> - -<p>La distribución de Emacs estándar contiene una función para -contar el número de líneas en una región. -</p> -<p>Hay cierto tipo de pregunta escrita para contar palabras. De este -modo, si se escribe un ensayo, puede limitarse a 800 palabras; si se -escribe una novela, te puedes disciplinar a ti mismo a escribir 1000 -palabras al día. Parece raro, pero durante mucho tiempo, -a Emacs le faltó un comando para contar palabras. Quizás la gente -usaba Emacs mayoritariamente para codificar o documentar cosas que no -requieren contar palabras, o quizás se restringían al -sistema operativo el comando de contar palabras, <code>wc</code>. De manera -alternativa, la gente puede seguir la convención de las editoriales -y computaban un contaje de palabras dividiendo el número de caracteres -en un documento por cinco. -</p> -<p>Hay mucho caminos para implementar un comando para contar -palabras. Aquí hay algunos ejemplos, que pueden desear -compararse con el comando de Emacs estándar, -<code>count-words-region</code>. -</p> -<hr> -<a name="count_002dwords_002dexample"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Contando-palabras" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Por-qu_00e9-Contar-Palabras" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Dise_00f1ar-count_002dwords_002dexample" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-count_002dwords_002dexample"></a> -<h2 class="section">13.1 La función <code>count-words-example</code></h2> -<a name="index-count_002dwords_002dexample"></a> - -<p>Un comando de contar palabras podría contar palabras en -una línea, párrafo, región, o -búffer. ¿Qué comando funcionaría? Se -podría diseñar el comando para contar el número de -palabras en un búffer completo. Sin embargo, la tradición Emacs -anima a la flexibilidad — se puede querer contar palabras solo en -una sección, en vez de en todo un búffer. Así, tiene -más sentido diseñar el comando para contar el número de palabras -en una región. Una vez tienes un comando <code>count-words-region</code>, -se puede, si desea, contar palabras en un búffer completo -marcándolo con <kbd><span class="nolinebreak">C-x</span> h</kbd> (<code>mark-whole-buffer</code>). -</p> -<p>Claramente, contar palabras es un acto repetitivo: empezando desde el -principio de la región, se cuenta la primera palabra, entonces la -segunda palabra, entonces la tercera palabra, y así, -hasta que logres el fin de la región. Esto significa que contar -palabras se ajusta idealmente a recursión o a un bucle <code>while</code>. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Dise_00f1ar-count_002dwords_002dexample">Diseñando <code>count-words-example</code></a></td><td> </td><td align="left" valign="top"> La definición usando un bucle - <code>while</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Error-de-espacio-en-blanco">13.1.1 El error de espacio en blanco en <code>count-words-example</code></a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="Dise_00f1ar-count_002dwords_002dexample"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Contando-palabras" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#count_002dwords_002dexample" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#count_002dwords_002dexample" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Error-de-espacio-en-blanco" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Disenando-count_002dwords_002dexample"></a> -<h3 class="unnumberedsubsec">Diseñando <code>count-words-example</code></h3> - -<p>Primero, implementaremos el comando de contar palabras con un bucle -<code>while</code>, entonces con la recursión. El comando, de acuerdo, -será interactivo. -</p> -<p>La plantilla para una definición de función interactiva es, como -siempre: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun <var>name-of-function</var> (<var>argument-list</var>) - "<var>documentation</var>…" - (<var>interactive-expression</var>…) - <var>body</var>…) -</pre></div> - -<p>Lo que necesitamos hacer es rellenar los slots. -</p> -<p>El nombre de la función sería auto-explicativo y -similar al nombre del <code>count-lines-region</code> existente. Esto hace -que el nombre sea fácil de recordar. <code>count-words-region</code> es -una buena elección. Puesto que el nombre se usa ahora para el -comando de Emacs estándar para contar palabras, nosotros nombraremos -nuestra implementación como <code>count-words-example</code>. -</p> -<p>La función cuenta palabras con una región. Esto significa que el -argumento lista debe contener símbolos que son asociados -a las dos posiciones, el principio y fin de la región. Estas dos -posiciones puede ser llamadas ‘<samp>beginning</samp>’ y ‘<samp>end</samp>’ -respectivamente. La primera línea de la documentación -sería una frase simple, desde que esto es todo lo que -está impreso como documentación por un comando tal como -<code>apropos</code>. La expresión interactiva será de la forma -‘<samp>(interactive "r")</samp>’, puesto que causará que Emacs pase al -principio y fin de la región a la lista de argumentos de -función. Todo esto es rutina. -</p> -<p>El cuerpo de la función necesita ser escrita para hacer tres tareas: -primero, configurar condiciones bajo las que el bucle <code>while</code> -pueda contar palabras, segundo, ejecutar el bucle <code>while</code>, y -tercero, enviar un mensaje al usuario. -</p> -<p>Cuando un usuario llama a <code>count-words-example</code>, apunta a que -puede estar al principio o fin de la región. Sin embargo, el proceso -de conteo debe empezar al principio de la región. Esto significa que -querremos poner el punto que hay si eso no está -allí. Ejecutando <code>(goto-char beginning)</code> asegura -esto. De acuerdo, querremos devolver el punto a su posición esperada -cuando la función finalice su trabajo. Por esta razón, el cuerpo -debe ser encerrado en una expresión <code>save-excursion</code>. -</p> -<p>La parte central del cuerpo de la función consiste en un bucle -<code>while</code> en el que una expresión salta el punto hacia delante -palabra por palabra, y otra expresión cuenta estos saltos. Si el -test-verdadero-o-falso del bucle <code>while</code> es verdadero, el punto -saltaría hacia adelante, y si es falso el punto -estaría al fin de la región. -</p> -<p>Nosotros podríamos usar <code>(forward-word 1)</code> como la -expresión para mover el punto hacia adelante palabra por palabra, -pero eso es fácil de ver que Emacs identifica como una ‘palabra’ si -se usa una búsqueda de expresión regular. -</p> -<p>Una expresión regular busca lo que encuentra el patrón que se -está buscando deja el punto después del último carácter -emparejado. Esto significa que una sucesión de palabras exitosas -busquen que moverá el punto adelante palabra por palabra. -</p> -<p>Como materia práctica, se quiere que la expresión regular se -busque para saltar a través de un espacio en blanco y puntúe entre -palabras tan bien a través de las palabras en sí. Una -expresión regexp que rechaza para saltar a través de espacios en -blanco entre palabras ¡nunca saltaría más -de una palabra!. Esto significa que el regexp incluiría -el espacio en blanco y la puntuación sigue a una palabra -cualquiera, como la palabra en sí. (Una palabra puede -finalizar un búffer y no tiene cualquier espacio en blanco o -puntuación, así esta parte del regexp debe ser -opcional.) -</p> -<p>De este modo, queremos para el regexp es un patrón definiendo una o -más palabras de caracteres que constituyen caracteres seguidos, -opcionalmente, por uno o más caracteres que no son palabras -constituyentes. La expresión regular para esto es: -</p> -<div class="smallexample"> -<pre class="smallexample">\w+\W* -</pre></div> - -<p>La tabla de sintaxis del búffer determina qué caracteres son y no -son palabras constituyentes. Para más información acerca de -sintaxis, see <a href="elisp.html#Tablas-de-Sintaxis">Tablas de Sintaxis</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>. -</p> -<p>La expresión se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(re-search-forward "\\w+\\W*") -</pre></div> - -<p>(Note que las barras invertidas que preceden el ‘<samp>w</samp>’ y -‘<samp>W</samp>’. Una barra invertida tiene significado especial al -intérprete Emacs Lisp. Eso indica que el caracter siguiente es -interpretado de manera diferente que la normal. Por ejemplo, los dos -caracteres, ‘<samp>\n</samp>’, son una ‘<samp>nueva línea</samp>’, en -vez de una barra invertida seguida por ‘<samp>\n</samp>’. Dos barras -invertidas en una fila para una ‘barra invertida no especial’, -así Emacs Lisp interpreta el fin de mirar una barra -invertida simple seguida por una letra. Así descubre la -letra que es especial.) -</p> -<p>Se necesita un contador para contar cuántas palabras hay; esta -variables debe primero ser asignado a 0 y entonces incrementados cada -vez que Emacs va alrededor del bucle <code>while</code>. La expresión de -incremento es simple: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq count (1+ count)) -</pre></div> - -<p>Finalmente, se quiere contar al usuario cuántas palabras hay en la -región. La función <code>message</code> presenta este tipo de -información al usuario. El mensaje tiene que ser fraseado -de manera que se lea apropiadamente sin cuidado de cuantas palabras -hay en la región: no se quiere decir que “hay una palabra en la -región”. El conflicto entre singular y plural no es gramatical. Se -puede resolver este problema usando una expresión condicional que -evalúa diferentes mensajes dependiendo en el número de palabras en -la región. Hay tres posibilidades: no palabras en la región, una -palabra en la región, y más de una palabra. Esto significa que la -forma especial <code>cond</code> es apropiada. -</p> -<p>Todo esto lidera a la siguiente definición de función: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">¡La Primera versión; tiene errores!</span> -(defun count-words-region (beginning end) - "Imprime el número de palabras en la región. -Las palabras están definidas al menos una palabra -constituida de caracteres seguido por al menos un -caracter que no constituye palabra. La tabla de -sintaxis del búffer determina qué caracteres hay." - (interactive "r") - (message "Contando palaras en la región ... ") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">1. Configurar condiciones apropiadas.</span> - (save-excursion - (goto-char beginning) - (let ((count 0)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">2. Ejecutar el</span> <span class="roman">bucle</span> while. - (while (< (point) end) - (re-search-forward "\\w+\\W*") - (setq count (1+ count))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">3. Enviar un mensaje al usuario.</span> - (cond ((zerop count) - (message - "La región no tiene palabras.")) - ((= 1 count) - (message - "La región tiene 1 palabra.")) - (t - (message - "La región tiene %d palabras." count)))))) -</pre></div> - -<p>Como se escribe, la función funciona, pero no en todas las circunstancias. -</p> -<hr> -<a name="Error-de-espacio-en-blanco"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Contando-palabras" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Dise_00f1ar-count_002dwords_002dexample" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#count_002dwords_002dexample" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#recursive_002dcount_002dwords" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-error-de-espacio-en-blanco-en-count_002dwords_002dexample"></a> -<h3 class="subsection">13.1.1 El error de espacio en blanco en <code>count-words-example</code></h3> - -<p>El comando <code>count-words-example</code> descrito en la sección -precedente tiene dos errores, o incluso, un error con dos -manifestaciones. Primero, si se marca una región conteniendo solo -espacio en blanco en el medio de algún texto el comando -¡<code>count-words-example</code> cuenta que la región -contiene una palabra!. Segundo, si se marca una región conteniendo -solo espacios en blanco al final del búffer o la porción accesible -de un búffer encogido, el comando muestra un mensaje de error que se -parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">Búsqueda fallida: "\\w+\\W*" -</pre></div> - -<p>Si está leyendo esto en Info en GNU Emacs, se puede testear para -estos errores por sí mismo. -</p> -<p>Primero, evalúa la función de la manera usual para instalarlo. -</p> -<p>Si se desea, se puede también instalar este atajo para ser evaluado: -</p> -<div class="smallexample"> -<pre class="smallexample">(global-set-key "\C-c=" 'count-words-example) -</pre></div> - -<p>Para conducir el primer test, asigna marca y punto al principio y fin -de la siguiente línea y entonces escribe <kbd>C-c =</kbd> (o -<kbd>M-x count-words-example</kbd> si no se ha asignado <kbd>C-c =</kbd>): -</p> -<div class="smallexample"> -<pre class="smallexample"> uno dos tres -</pre></div> - -<p>Emacs te contará, correctamente, que la región tiene tres palabras. -</p> -<p>Repite el test, pero marca el lugar al principio de la -línea y emplaza el punto justo <em>antes</em> de la -palabra ‘<samp>uno</samp>’. De nuevo escribe el comando <kbd>C-c =</kbd> (o -<kbd>M-x count-words-example</kbd>). Emacs cuenta que la región no tiene -palabras, puesto que eso está compuesto solo por espacios en blanco -al principio de la línea. ¡Pero en vez de -que Emacs cuente que la región tiene una palabra! -</p> -<p>Para el tercer test, copia la línea de ejemplo al fin -del búffer ‘<tt>*scratch*</tt>’ y entonces escribe varios espacios al fin -de la línea. Posiciona la marca correcta después de la -palabra ‘<samp>tres</samp>’ y apunta al fin de la línea. (El fin -de la línea será el fin del búffer.) Escribe <kbd>C-c -=</kbd> (o <kbd>M-x count-words-example</kbd>) como se hizo antes. De nuevo, -Emacs te contaría que la región no tiene palabras, -puesto que eso está compuesto solo de los espacios en blanco al fin -de la línea. En vez de eso, Emacs muestra un mensaje de -error diciendo ‘<samp>Búsqueda fallida</samp>’. -</p> -<p>Los dos errores queman el mismo problema. -</p> -<p>Considere la primera manifestación del error, en el que el comando -te cuenta que el espacio en blanco al principio de la -línea contiene una palabra. Lo que ocurre es esto: El -comando <code>M-x count-words-example</code> mueve el punto al principio de -la región. El test <code>while</code> si el valor del punto es más -pequeño de lo que el valor de <code>end</code>, que es. Por consiguiente, -en la expresión regular se busca y encuentra la primera palabra. Eso -deja el punto después de la palabra. <code>count</code> que se establece a -uno. El bucle <code>while</code> repite; pero esta vez el valor del punto es -más largo que el valor de <code>end</code>, el bucle sale; y la función -muestra un mensaje diciendo el número de palabras en la región es -uno. En breve, la expresión regular busca y encuentra la palabra -incluso aunque eso esté fuera de la región marcada. -</p> -<p>En la segunda manifestación del error, la región es un espacio en -blanco al fin del búffer. Emacs dice ‘<samp>Búsqueda fallida</samp>’. Lo -que ocurre es que true-or-false-test en el bucle <code>while</code> chequea -verdad, así la expresión de búsqueda es -ejecutada. Pero desde que no hay más palabras en el buffer, la -búsqueda falla. -</p> -<p>En ambas manifestaciones del error, la búsqueda extiende o intenta -extenderse fuera de la región. -</p> -<p>La solución es limitar la búsqueda a la región — esto es una -acción simple y limpia, pero como tu puedes tener que llegar a -esperar, eso no es tan simple como se podría pensar. -</p> -<p>Como se ha visto, la función <code>re-search-forward</code> toma un -patrón de búsqueda como su primer argumento. Pero además de este -primer, argumento obligatorio, se aceptan tres argumentos -opcionales. El segundo argumento opcional asocia la búsqueda. El -tercer argumento opcional, si <code>t</code>, causa la función a devolver -<code>nil</code> en vez de la señal un error si la búsqueda falla. El -cuarto argumento opcional es un contador repetido. (En Emacs, se puede -ver una documentación de la función escribiendo <kbd>C-h f</kbd>, el -nombre de la función, y entonces <RET>.) -</p> -<p>En la definición <code>count-words-example</code>, el valor del fin de la -región es tomada por la variable <code>end</code> que es pasada como un -argumento para la función. De este modo, se puede añadir -<code>end</code> como un argumento para la búsqueda de la expresión de -búsqueda: -</p> -<div class="smallexample"> -<pre class="smallexample">(re-search-forward "\\w+\\W*" fin) -</pre></div> - -<p>Sin embargo, si se crea solo este cambio a la definición -<code>count-words-example</code> y entonces se chequea la nueva versión de -la definición en una extensión de espacio en blanco, se recibirá -un mensaje de error diciendo ‘<samp>Búsqueda fallida</samp>’. -</p> -<p>Lo que ocurre es esto: la búsqueda se limita a la región, y -falla como se espera porque no hay caracteres de palabras -constituyentes en la región. Puesto que eso falla, se recibe un -mensaje de error. Pero no queremos recibir un mensaje de error en este -caso; se quiere recibir el mensaje que "La región no tiene palabras". -</p> -<p>La solución a este problema es proveer <code>re-search-forward</code> con -un tercer argumento de <code>t</code>, que causa la función para devolver -<code>nil</code> en vez la señalar un error si la búsqueda falla. -</p> -<p>Sin embargo, si se crea este cambio y se intenta, se verá el mensaje -“Contando palabras en la región ...” y … se guardará -viendo qué mensaje …, hasta que se escribe <kbd>C-g</kbd> -(<code>keyboard-quit</code>). -</p> -<p>Aquí está lo que ocurre: la búsqueda está limitada -a la región, como antes, y eso falla porque no hay caracteres no -constituyentes de palabras en la región, como se -espera. Por tanto, la expresión <code>re-search-forward</code> -devuelve <code>nil</code>. Eso no hace nada más. En particular, no mueve -el punto, que hace como un efecto lateral si se encuentra la -búsqueda objetiva. Después la expresión <code>re-search-forward</code> -devuelve <code>nil</code>, la siguiente expresión en el bucle <code>while</code> -está evaluado. Esta expresión incrementa el contador. Entonces el -bucle repite. El test true-or-false-test chequea cierto porque el -valor del punto es todavía menor que el valor final, -desde que la expresión <code>re-search-forward</code> no -movería el punto. … y el ciclo repite … -</p> -<p>La definición <code>count-words-example</code> requiere -todavía de otra modificación para causar el -true-or-false-test del bucle <code>while</code> para chequear falso si la -búsqueda falla. Pon otro camino, hay dos condiciones que deben ser -satisfechas en el true-or-false-test antes que el contador de palabras -variable se incremente: el punto debe todavía estar con la -región y la expresiń de búsqueda debe haber encontrado una -palabra para contar. -</p> -<p>Por ambas la primera condición y la segunda condición deben ser -ciertas juntas, las dos expresiones, la región chequea y la -expresión de búsqueda, puede estar unido con una forma especial -<code>and</code> y embebido en el bucle <code>while</code> como el -true-or-false-test, como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(and (< (point) end) (re-search-forward "\\w+\\W*" end t)) -</pre></div> - - -<p>La expresión <code>re-search-forward</code> devuelve <code>t</code> si la -búsqueda es exitosa y como efecto lateral se mueve el -punto. Consiguientemente, como las palabras se encuentran, el punto es -movido a través de la región. Cuando la búsqueda de la expresión -falla para encontrar otra palabra, o cuando el punto logra el fin de -la región, el test true-or-false-test es falso, el bucle <code>while</code> -existe, y la función <code>count-words-example</code> muestra uno u otro de -sus mensajes. -</p> -<p>Después de incorporar estos cambios finales, el -<code>count-words-example</code> funciona sin errores (¡o al -menos, sin los errores que yo haya encontrado!. Aquí está -lo que parece: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Versión final:</span> <code>while</code> -(defun count-words-example (beginning end) - "Imprime número de palabras en la región." - (interactive "r") - (message "Contando palabras en la región ... ") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">1. Configura condiciones apropiadas.</span> - (save-excursion - (let ((count 0)) - (goto-char beginning) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">2. Ejecuta el</span> <span class="roman">bucle</span> while - (while (and (< (point) end) - (re-search-forward "\\w+\\W*" end t)) - (setq count (1+ count))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">3. Enviar un mensaje al usuario.</span> - (cond ((zerop count) - (message - "La región no tiene palabras.")) - ((= 1 count) - (message - "La región tiene 1 palabra.")) - (t - (message - "La región tiene %d palabras." count)))))) -</pre></div> - -<hr> -<a name="recursive_002dcount_002dwords"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Contando-palabras" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Error-de-espacio-en-blanco" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-Contar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Cuenta-palabras-recursivamente"></a> -<h2 class="section">13.2 Cuenta palabras recursivamente</h2> -<a name="index-Cuenta-palabras-recursivamente"></a> -<a name="index-Recursivamente-contando-palabras"></a> -<a name="index-Palabras_002c-contadas-recursivamente"></a> - -<p>Se puede escribir la función para contar palabras tanto de manera -recursiva como con un bucle <code>while</code>. Permita ver cómo se -hace. -</p> -<p>Primero, se necesita reconocer que la función -<code>count-words-example</code> tiene tres trabajos: eso configura las -condiciones apropiadas para contar lo que ocurre; eso cuenta las -palabras en la región; y envía un mensaje al usuario -contando cuántas palabras hay. -</p> -<p>Si se escribe una función recursiva simple para hacer cualquier cosa -se recibirá un mensaje para cada llamada recursiva. Si la región -contiene 13 palabras, se recibirán trece mensajes, uno correcto -después del otro. ¡No queremos esto!. En vez de eso, -se deben escribir dos funciones para hacer el trabajo, una (la -función recursiva) será usada dentro de la otra. Una función -configurará las condiciones y muestra el mensaje; la otra -devolverá el contador de palabras. -</p> -<p>Permítase comenzar con la función que causa el mensaje -que se muestra. Se puede continuar por llamarse <code>count-words-example</code>. -</p> -<p>Esta es la función que el usuario llama. Será interactiva. En -realidad, será similar a nuestras versiones previas de esta -función, excepto que llamará <code>recursive-count-words</code> para -determinar cuántas palabras hay en la región. -</p> -<p>Se puede construir una plantilla legible para esta función, basada -en versiones previas: -</p> -<div class="smallexample"> -<pre class="smallexample">;; <span class="roman">Versión Recursiva; usa la búsqueda de la expresión regular</span> -(defun count-words-example (beginning end) - "<var>documentation</var>…" - (<var>interactive-expression</var>…) -</pre><pre class="smallexample"> -;;; <span class="roman">1. Configura condiciones apropiadas.</span> - (<var>explanatory message</var>) - (<var>set-up functions</var>… -</pre><pre class="smallexample"> -;;; <span class="roman">2. Contar las palabras.</span> - <var>recursive call</var> -</pre><pre class="smallexample"> -;;; <span class="roman">3. Envía un mensaje al usuario.</span> - <var>message providing word count</var>)) -</pre></div> - -<p>La definición parece sencilla, excepto que como el contador devuelve -la llamada recursiva que debe ser pasada al mensaje mostrando el -contaje de palabras. Un pequeño pensamiento sugiere que esto puede -ser hecho haciendo uso de una expresión <code>let</code> al número de -palabras en la región, como se devuelve por la llamada recursiva; y -entonces la expresión <code>cond</code>, que usa la asociación, puede -mostrar el valor al usuario. -</p> -<p>Con frecuencia, uno piensa que se puede asociar una expresión -<code>let</code> como algo secundario al trabajo ‘primario’ de una -función. Pero en este caso, se podría considerar el -trabajo ‘primario’ de la función, contando palabras, esto es hecho -con la expresión <code>let</code>. -</p> -<p>Usando <code>let</code>, la definición de función se parece a: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun count-words-example (beginning end) - "Imprime el número de palabras en la región." - (interactive "r") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">1. Configura condiciones apropiadas.</span> - (message "Contando palabras en la región ... ") - (save-excursion - (goto-char beginning) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">2. Contar las palabras.</span> - (let ((count (recursive-count-words end))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">3. Enviar un mensaje al usuario.</span> - (cond ((zerop count) - (message - "La región no tiene palabras.")) - ((= 1 count) - (message - "La región tiene 1 palabra.")) - (t - (message - "La región tiene %d palabras." count)))))) -</pre></div> - -<p>Lo siguiente, que se necesita es escribir la función de contaje -recursivo. -</p> -<p>Una función recursiva tiene al menos tres partes: el ‘do-again-test’, -la ‘next-step-expression’, y la llamada recursiva. -</p> -<p>El do-again-test determina si la función será o no llamada de -nuevo. Puesto que estamos contando palabras en una región y puede -causar que una función se mueva el punto hacia delante por cada -palabra, el do-again-test puede chequear si el punto está -todavía con la región. El do-again-test -encontraría el valor del punto y determina si el punto -está antes, en, o después del valor del fin de la región. Se -puede usar la función <code>point</code> para localizar el -punto. Claramente, se debe pasar el valor del fin de la región a la -función de contaje recursivo como un argumento. -</p> -<p>Además, el do-again-test también chequea si la búsqueda -encuentra una palabra. Si no, la función no se -llamaría de nuevo. -</p> -<p>La next-step-expression cambia un valor así que cuando -la función recursiva se supone que debe parar de llamarse -así misma, se para. Más precisamente, los cambios de -next-step-expression cambia un valor así en el momento -adecuado, el do-again-test para la función recursiva de la llamada -en sí de nuevo. En este caso, la next-step-expression -puede ser la expresión que mueve el punto hacia adelante, palabra -por palabra. -</p> -<p>La tercera parte de una función recursiva es la llamada recursiva. -</p> -<p>En algún lugar, también, se necesita una parte que hace el -‘trabajo’ de la función, una parte que es el -contaje. ¡Una parte vital! -</p> -<p>Pero ya, tenemos un guión de la función recursiva de contaje: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun recursive-count-words (region-end) - "<var>documentation</var>…" - <var>do-again-test</var> - <var>next-step-expression</var> - <var>recursive call</var>) -</pre></div> - -<p>Ahora se necesita rellenar los slots. Permite comenzar con el caso -más simple primero: si se apunta debajo del fin de la región, no -puede haber palabras en la región, así la función -devuelve cero. De otro modo, si la búsqueda falla no hay palabras -para contar, así la función devolvería cero. -</p> -<p>Por otro lado, si se apunta con la región y la búsqueda tiene -éxito, la función se llamaría de nuevo. -</p> -<p>De este modo, do-again-test se vería así: -</p> -<div class="smallexample"> -<pre class="smallexample">(and (< (point) region-end) - (re-search-forward "\\w+\\W*" region-end t)) -</pre></div> - -<p>Note que la expresión de búsqueda es parte del do-again-test — -la función devuelve <code>t</code> si su búsqueda tiene éxito y -<code>nil</code> si falla. (Véase la sección <a href="#Error-de-espacio-en-blanco">El Error de Espacio en Blanco en <code>count-words-example</code></a>), para una -explicación de cómo <code>re-search-forward</code> funciona.) -</p> -<p>El do-again-test es el test true-or-false de una cláusula -<code>if</code>. Claramente si el do-again-test tiene éxito, la then-part -de la cláusula <code>if</code> llamaría a la función; pero -si eso falla, la else-part devolvería cero desde que el -punto está fuera de la región o la búsqueda falló porque no -había palabras a encontrar. -</p> -<p>Pero antes de considerar la llamada recursiva, se necesita considerar -la next-step-expression. ¿Qué es eso? De manera -interesante, eso es la parte de la búsqueda del do-again-test. -</p> -<p>Además para devolver <code>t</code> o <code>nil</code> para el do-again-test, -<code>re-search-forward</code> mueve el punto hacia adelante como un efecto -lateral de una búsqueda exitosa. Esta es la acción que cambia el -valor de punto así que la función recursiva para de -llamarse a sí misma cuando el punto complete su -movimiento a través de la región. Por consiguiente, la expresión -<code>re-search-forward</code> es la next-step-expression. -</p> -<p>En esquema, entonces, el cuerpo de la función -<code>recursive-count-words</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(if <var>do-again-test-and-next-step-combined</var> - ;; <span class="roman">then</span> - <var>recursive-call-returning-count</var> - ;; <span class="roman">else</span> - <var>return-zero</var>) -</pre></div> - -<p>¿Cómo incorporar el mecanismo que cuenta? -</p> -<p>Si no estás acostumbrado a escribir funciones recursivas, una pregunta -como esta puede ser un problema. Pero eso puede y sería -enfocado sistemáticamente. -</p> -<p>Se sabe que el mecanismo de contaje sería asociado en -algún lugar con la llamada recursiva. En vez de eso, desde que la -next-step-expression mueve el punto hacia adelante por una palabra, y -desde que una llamada recursiva es hecha para cada palabra, el -mecanismo de contaje debe ser una expresión que añade uno al valor -devuelto por una llamada para <code>recursive-count-words</code> -</p> -<p>Considera varias casos: -</p> -<ul> -<li> -Si hay dos palabras en la región, la función devolverá un valor -resultante de añadir uno al valor devuelto al contar la primera -palabra, más el número devuelto al contar las palabras que -permanecen en la región, que en este caso es una. - -</li><li> -Si hay una palabra en la región, la función -devolvería un valor resultante de añadir uno al valor -devuelto cuando eso cuenta esta palabra más el número devuelto -cuando eso cuenta las palabras que permanecen en la región, que en -este caso es cero. - -</li><li> -Si no hay palabras en la región, la función -devolvería cero. -</li></ul> - -<p>Desde el esquema se puede ver que la parte else del <code>if</code> devuelve -cero para el caso en el que no hay palabras. Esto significa que la -parte then del <code>if</code> debe devolver un valor resultante de añadir -uno al valor devuelto desde el contaje de las palabras que permanecen. -</p> -<p>La expresión se parece a esto, donde <code>1+</code> es una función que -añade uno a su argumento. -</p> -<div class="smallexample"> -<pre class="smallexample">(1+ (recursive-count-words region-end)) -</pre></div> - -<p>La función completa <code>recursive-count-words</code> entonces se -parecerá e esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun recursive-count-words (region-end) - "<var>documentation</var>…" - -;;; <span class="roman">1. do-again-test</span> - (if (and (< (point) region-end) - (re-search-forward "\\w+\\W*" region-end t)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">2. then-part: la llamada recursiva</span> - (1+ (recursive-count-words region-end)) - -;;; <span class="roman">3. else-part</span> - 0)) -</pre></div> - -<p>Permíteme examinar cómo esto funciona: -</p> -<p>Si no hay palabras en la región, la parte else de la expresión -<code>if</code> es evaluada y, por tanto, la función devuelve cero. -</p> -<p>Si hay una palabra en la región, el valor del punto es menor que el -valor de <code>region-end</code> y la búsqueda tiene éxito. En este -caso, el true-or-false-test de la expresión <code>if</code> chequea -cierto, y la then-part de la expresión <code>if</code> es evaluada. La -expresión de contaje se evalúa. Esta expresión devuelve un valor -(que será el valor devuelto por la función completa) que es la -suma de uno añadida al valor devuelto por una llamada recursiva. -</p> -<p>Mientras tanto, la next-step-expression ha causado el punto para -saltar a través de la primera (y en este caso única) palabra en la -región. Esto significa que cuando <code>(recursive-count-words -region-end)</code> está evaluada una segunda vez, como un resultado de la -llamada recursiva, el valor del punto será igual o mayor que el -valor de la región final. Así esta vez, -<code>recursive-count-words</code> devolverá cero. El cero será -añadido a uno, y la evaluación original de -<code>recursive-count-words</code> devolverá uno más cero (uno) que es -la cantidad correcta. -</p> -<p>Claramente, si hay dos palabras en la región, la primera llamada a -<code>recursive-count-words</code> devuelve uno que se añade al valor -devuelto por el siguiente <code>recursive-count-words</code> en una región -donde está la palabra que permanece — que es, eso añadir uno a -uno, produciendo dos, que es la cantidad correcta. -</p> -<p>Similarmente, si hay tres palabras en la región, la primera llamada -<code>recursive-count-words</code> devuelve uno añadido al valor devuelto -llamado <code>recursive-count-words</code> en una región conteniendo las -dos palabras que faltan — y así. -</p> -<p>Con documentación completa las dos funciones se parecen a esto: -</p> -<p>La función recursiva: -</p> -<a name="index-recursive_002dcount_002dwords"></a> -<div class="smallexample"> -<pre class="smallexample">(defun recursive-count-words (region-end) - "Número de palabras entre punto y REGION-END." -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">1. do-again-test</span> - (if (and (< (point) region-end) - (re-search-forward "\\w+\\W*" region-end t)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">2. then-part: la llamada recursiva</span> - (1+ (recursive-count-words region-end)) - -;;; <span class="roman">3. else-part</span> - 0)) -</pre></div> - -<p>El envoltorio: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Versión Recursiva</span> -(defun count-words-example (beginning end) - "Imprime el número de palabras en la región. -</pre><pre class="smallexample"> -</pre><pre class="smallexample">Las palabras son definidas como al menos una palabra constituyente -seguida por al menos un caracter que es una palabra constituyente. La -tabla de sintaxis del buffer determina qué caracter hay. -</pre><pre class="smallexample"> (interactive "r") - (message "Contando palabras en la región ... ") - (save-excursion - (goto-char beginning) - (let ((count (recursive-count-words end))) -</pre><pre class="smallexample"> (cond ((zerop count) - (message - "La región no tiene palabras.")) -</pre><pre class="smallexample"> ((= 1 count) - (message "La región tiene 1 palabra.")) - (t - (message - "La región tiene %d palabras." count)))))) -</pre></div> - -<hr> -<a name="Ejercicio-de-Contar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Contando-palabras" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#recursive_002dcount_002dwords" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-palabras" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio_003a-contando-puntuacion"></a> -<h2 class="section">13.3 Ejercicio: contando puntuación</h2> - -<p>Usando un bucle <code>while</code>, escriba una función para contar el -número de marcas de puntuación en una región — periodo, coma, -punto y coma, dos puntos, exclamación, marca y marca de -pregunta. Haga lo mismo usando recursión. -</p> -<hr> -<a name="Palabras-en-una-funci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Contando-palabras" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-Contar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Divide-y-vencer_00e1s" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Contando-palabras-en-una-defun"></a> -<h1 class="chapter">14 Contando palabras en una <code>defun</code></h1> -<a name="index-Contando-palabras-en-un-defun"></a> -<a name="index-Contando-las-palabras-en-un-defun"></a> - -<p>El siguiente proyecto es contar el número de palabras en una -definición de función. Claramente, esto se puede hacer usando -alguna variante de <code>count-words-example</code>. Véase la sección <a href="#Contando-palabras">Contando palabras: repetición y regexps</a>. Si se está -ahora yendo a contar las palabras en una definición, es -suficientemente fácil marcar la definición con el comando -<kbd>C-M-h</kbd> (<code>mark-defun</code>), y entonces se llama a -<code>count-words-example</code>. -</p> -<p>Sin embargo, soy más ambicioso: Yo quiero contar las palabras y -símbolos en cada definición en las fuentes de Emacs y -entonces imprimir un grafo que muestre cuántas funciones hay de cada -tamaño: cuántas contienen de 40 a 49 palabras o -símbolos, cuántas contienen de 50 a 59 palabras o -símbolos, y así. Yo he sido con frecuencia -curioso de cómo es una función típica, y esto se -contará. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Divide-y-vencer_00e1s">Divide y vencerás</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Palabras-y-S_00edmbolos">14.1 ¿Qué contar?</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Sintaxis">14.2 ¿Qué constituye una palabra o símbolo?</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#count_002dwords_002din_002ddefun">14.3 La función <code>count-words-in-defun</code></a></td><td> </td><td align="left" valign="top"> Similar a <code>count-words-example</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Varias-funciones">14.4 Contar varias <code>defuns</code> en un fichero</a></td><td> </td><td align="left" valign="top"> Contando varias funciones en un fichero. -</td></tr> -<tr><td align="left" valign="top"><a href="#Encontrar-un-fichero">14.5 Encontrar un fichero</a></td><td> </td><td align="left" valign="top"> ¿Quieres buscar en un fichero? -</td></tr> -<tr><td align="left" valign="top"><a href="#lengths_002dlist_002dfile">14.6 <code>lengths-list-file</code> en detalle</a></td><td> </td><td align="left" valign="top"> Una lista de los tamaños de muchas - definiciones. -</td></tr> -<tr><td align="left" valign="top"><a href="#Varios-ficheros">14.7 Contar palabras en <code>defuns</code> en diferentes ficheros</a></td><td> </td><td align="left" valign="top"> Contando en definiciones en diferentes - ficheros. -</td></tr> -<tr><td align="left" valign="top"><a href="#Varios-ficheros-recursivamente">14.8 Recursivamente cuenta palabras en diferentes ficheros</a></td><td> </td><td align="left" valign="top"> Recursivamente contando en diferentes - ficheros. -</td></tr> -<tr><td align="left" valign="top"><a href="#Preparar-los-datos">14.9 Preparar los datos para mostrarlos en un grafo</a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="Divide-y-vencer_00e1s"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-y-S_00edmbolos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Divide-y-venceras"></a> -<h2 class="unnumberedsec">Divide y vencerás</h2> - -<p>Descrito en una frase, el proyecto desanima; pero dividido dentro de -numerosos pequeños pasos, cada uno de los que podemos tomar en un -momento, el proyecto llegar ser menos -atemorizante. Permítenos considerar qué pasos deben -ser: -</p> -<ul> -<li> -Primero, escribe una función para contar las palabras en una -definición. Esto incluye el problema de manejar -símbolos tan bien como palabras. - -</li><li> -Segundo, escribe una función para listar los números de palabras -en cada función en un fichero. Esta función puede usar la -función <code>count-words-in-defun</code>. - -</li><li> -Tercero, escribe una función para listar los números de palabras -en cada función en cada uno de varios ficheros. Esto encola -automáticamente encontrando varios ficheros, cambiándolos, y -contando las palabras en las definiciones con ellos. - -</li><li> -Cuarto, escribe una función para convertir la lista de números que -nosotros creamos en tres pasos para un formulario que se ajustará -para imprimir un grafo. - -</li><li> -Quinto, escribe una función para imprimir los resultados como un grafo. -</li></ul> - -<p>¡Esto es un proyecto! Pero si tomamos cada paso -lentamente, eso no será difícil. -</p> -<hr> -<a name="Palabras-y-S_00edmbolos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Divide-y-vencer_00e1s" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Sintaxis" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="g_t_00bfQue-contar_003f"></a> -<h2 class="section">14.1 ¿Qué contar?</h2> -<a name="index-Palabras-y-simbolos-en-defun"></a> - -<p>Cuando nosotros primero empezamos pensando acerca del contaje de -palabras en una definición de función, la primera pregunta es (o -podría ser) ¿qué se va a contar? Cuando -se habla de ‘palabras’ con repecto a una definición de función -Lisp, estamos actualmente hablando, en parte, de -‘símbolos’. Por ejemplo, la siguiente función -<code>multiply-by-seven</code> contiene los cinco símbolos -<code>defun</code>, <code>multipy-by-seven</code>, <code>number</code>, <code>*</code>, y -<code>7</code>. Además, en la cadena de documentación, contiene cuatro -palabras ‘<samp>Multiplicar</samp>’, ‘<samp>NUMBER</samp>’, ‘<samp>por</samp>’, y -‘<samp>siete</samp>’. El símbolo ‘<samp>número</samp>’ es repetido, -así la definición contiene un total de diez palabras y -símbolos. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun multiplicar-por-siete (numero) - "Multiplica NUMERO por siete." - (* 7 numero)) -</pre></div> - -<p>Sin embargo, si se marca la definición <code>multiply-by-seven</code> con -<kbd>C-M-h</kbd> (<code>mark-defun</code>), y entonces se llama a -<code>count-words-example</code> dentro, se encontrará que -<code>count-words-example</code> ¡reclama la definición tiene -once palabras, no diez! ¡Alguna cosa está mal! -</p> -<p>El problema es doble: <code>count-words-example</code> no cuenta el ‘<samp>*</samp>’ -como una palabra, y eso cuenta el símbolo simple, -<code>multiply-by-seven</code>, conteniendo tres palabras. Las conexiones -son tratadas como si fueran espacios entre palabras en vez de -conectores entre palabras ‘<samp>multiply-by-seven</samp>’ se cuenta como si -fuese escrito ‘<samp>multiply-by-seven</samp>’. -</p> -<p>La causa de esta confusión es la expresión regular que busca la -definición <code>count-words-example</code> que mueve el punto hacia -delante palabra por palabra. En la versión canónica de -<code>count-words-example</code>, el regexp es: -</p> -<div class="smallexample"> -<pre class="smallexample">"\\w+\\W*" -</pre></div> - -<p>Esta expresión regular es un patrón definiendo una o más -palabras constituyendo caracteres posiblemente seguidos por uno o -más caracteres que no son palabras constituyentes. Esto significa -que los ‘caracteres que constituyen palabras’ nos traen la cuestión -de la sintaxis, que es el valor de una sección en sí. -</p> -<hr> -<a name="Sintaxis"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-y-S_00edmbolos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#count_002dwords_002din_002ddefun" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="g_t_00bfQue-constituye-una-palabra-o-simbolo_003f"></a> -<h2 class="section">14.2 ¿Qué constituye una palabra o símbolo?</h2> -<a name="index-Categorias-de-sintaxis-y-tablas"></a> - -<p>Emacs trata diferentes caracteres perteneciendo a diferentes -<em>categorías de sintaxis</em>. Por ejemplo, la -expresión regular, ‘<samp>\\w+</samp>’, es un patrón especificando uno o -más caracteres de <em>palabras constituyentes</em>. Los caracteres de -palabras constituyentes son miembros de una categoría de -sintaxis. Otras categoría de sintaxis incluye la clase -de caracteres de puntuación, tales como el espacio en blanco o el -caracter de tabulación. (Para más información, ver -<a href="emacs.html#Sintaxis">La Tabla de Sintaxis</a> in <cite>El Manual GNU Emacs</cite>, y <a href="elisp.html#Tablas-de-Sintaxis">Tablas de Sintaxis</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>.) -</p> -<p>Las tablas de sintaxis especifican qué caracteres pertenecen a qué -categorías. Normalmente un guión no está -especificado como un ‘caracter constituido por una palabra’. En vez de -eso, se especificó como estando en la ‘clase de caracteres que son -parte de los nombres de símbolos, pero no las palabras.’ -Esto significa que la función <code>count-words-example</code> se trata del -mismo modo que trata un espacio en blanco entre palabras, que es el -por qué <code>count-words-example</code> cuenta ‘<samp>multiply-by-seven</samp>’ -como tres palabras. -</p> -<p>Hay dos caminos para causar que Emacs cuente ‘<samp>multiply-by-seven</samp>’ -como un símbolo: modificar la tabla de sintaxis o -modificar la expresión regular. -</p> -<p>Se podría redefinir un guión (<em>hyphen</em>) como un -caracter que constituye una palabra modificando la tabla de sintaxis -que Emacs guarda por cada modo. Esta acción serviría -nuestro propósito, excepto que una conexión es meramente el -caracter más común con símbolos que no son -típicamente un caracter de palabra constituyente; hay -otros, también. -</p> -<p>Alternativamente, se puede redefinir la expresión regular -<em>regexp</em> usada en la definición <code>count-words</code> -así como incluir símbolos. Este -procedimiento tiene el mérito de la claridad, pero la tarea es un -pequeño truco. -</p> -<p>La primera parte es suficientemente simple: el patrón debe asignarse -“al menos un carácter que es una palabra o símbolo -constituyente”. De este modo: -</p> -<div class="smallexample"> -<pre class="smallexample">"\\(\\w\\|\\s_\\)+" -</pre></div> - -<p>El ‘<samp>\\(</samp>’ es la primera parte del constructo que agrupa esto que -incluye el ‘<samp>\\w</samp>’ y el ‘<samp>\\s_</samp>’ como alternativas, separadas -por los ‘<samp>\\|</samp>’. El ‘<samp>\\w</samp>’ asocia cualquier caracter de -palabra constituyente y el ‘<samp>\\s_</samp>’ asocia cualquier caracter que -es parte de un nombre de símbolo pero no una palabra de -caracteres constituyente. El ‘<samp>+</samp>’ sigue al grupo que indica que la -palabra o símbolo constituyan caracteres que deben ser -asociados al menos por uno. -</p> -<p>Sin embargo, la segunda parte de regexp es más difícil -de diseñar. Lo que queremos es seguir la primera parte con -“opcionalmente uno o más caracteres que no constituyen una palabra -o símbolo”. Primero, se pensaba que se -podría definir esto con lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">"\\(\\W\\|\\S_\\)*" -</pre></div> - -<p>Las mayúsculas ‘<samp>W</samp>’ y ‘<samp>S</samp>’ asocian caracteres que <em>no</em> -son constituyente de palabra o -símbolo. Desafortunadamente, esta expresión asocia -cualquier caracter que sea o no una palabra constituyente no un -símbolo constituyente. ¡Esto asocia -cualquier caracter! -</p> -<p>Entonces se notificó que cada palabra o símbolo en mi -región test fué seguida por algún espacio (espacio en blanco, -tabulador, o nueva línea). Así yo -intenté emplazar un patrón para asociar uno o más espacios en -blanco después del patrón para una o más palabras o -símbolos constituyentes. Esto falló, -también. Palabras y símbolos son con frecuencia -separados por espacios en blanco, pero en el código actual los -paréntesis pueden seguir símbolos y puntuación puede -seguir las palabras. Así finalmente, se diseño un -patrón en el que la palabra o símbolo constituyente -es seguido opcionalmente por caracteres que no son espacios en blanco -y entonces son seguidos opcionalmente por espacios en blanco. -</p> -<p>Aquí está la expresión regular completa: -</p> -<div class="smallexample"> -<pre class="smallexample">"\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" -</pre></div> - -<hr> -<a name="count_002dwords_002din_002ddefun"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Sintaxis" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Varias-funciones" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-count_002dwords_002din_002ddefun"></a> -<h2 class="section">14.3 La función <code>count-words-in-defun</code></h2> -<a name="index-Contando-palabras-en-un-defun-1"></a> - -<p>Se ha visto que hay varios caminos para escribir una función -<code>count-word-region</code>. Para escribir un -<code>count-words-in-defun</code>, se necesita solamente adaptar una de -estas versiones. -</p> -<p>La versión que usa un bucle <code>while</code> es fácil de comprender, -así estoy yendo a adaptar esto. Porque -<code>count-words-in-defun</code> será parte de un programa más -complejo, eso no necesita ser interactivo y no necesita mostrar un -mensaje pero solo devuelve el contaje. Estas consideraciones -simplifican la definición un poco. -</p> -<p>Por otro lado, <code>count-words-in-defun</code> será usado con un buffer -que contiene definiciones de función. Consiguientemente, es -razonable preguntar que la función determina si se llamó cuando el -punto está con una definición de función, y eso es, para -devolver el contaje para esta definición. Esto añade complejidad a -la definición, pero nos guarda desde la necesidad de pasar -argumentos a la función. -</p> -<p>Estas consideraciones nos llevan a preparar la siguiente plantilla: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun count-words-in-defun () - "<var>documentation</var>…" - (<var>set up</var>… - (<var>while loop</var>…) - <var>return count</var>) -</pre></div> - -<p>Así, el trabajo es rellenar los slots. -</p> -<p>Primero, la configuración. -</p> -<p>Estamos presuponiendo que esta función será llamada con un -búffer conteniendo definiciones de función. Apunta si será con -una definición de función o no. Para que -<code>count-words-in-defun</code> funcione, el punto debe moverse al -principio de la definición, un contador debe empezar a cero, y el -bucle contando debe parar cuando el punto logre el fin de la definición. -</p> -<p>La función <code>beginning-of-defun</code> busca atrás para un -delimitador de apertura tal como ‘<samp>(</samp>’ al principio de una -línea, y mueve el punto a esta posición, o sino al -límite de la búsqueda. En la práctica, esto significa -que <code>beginning-of-defun</code> mueve el punto al principio de un cierre -o definición de función precedente, o sino al principio del buffer. -</p> -<p>El bucle <code>while</code> requiere un contador para guardar la traza de -las palabras o símbolos siendo contados. Una expresión -<code>let</code> puede ser usado para crear una variable local para este -propósito, y lo asocia a un valor inicial de cero. -</p> -<p>La función <code>end-of-defun</code> funciona como -<code>beginning-of-defun</code> excepto que mueve el punto al fin de la -definición. <code>end-of-defun</code> puede ser usado como parte de una -expresión que determina la posición del fin de la definición. -</p> -<p>La configuración para <code>count-words-in-defun</code> toma forma -rápidamente: primero movemos el punto al principio de la -definición, entonces se crea una variable local para manejar el -conteo, y finalmente, se graba la posición del fin de la -definición así el bucle <code>while</code> conocerá cuando -parar el bucle. -</p> -<p>El código se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(beginning-of-defun) -(let ((count 0) - (end (save-excursion (end-of-defun) (point)))) -</pre></div> - -<p>El código es simple. La única ligera complicación es -probablemente ir al <code>end</code>: eso está asociado a la posición -del fin de la definición por una expresión <code>save-excursion</code> -que devuelve el valor del punto después de <code>end-of-defun</code> -temporalmente se mueve al fin de la definición. -</p> -<p>La segunda parte del <code>count-words-in-defun</code>, después de la -configuración, es el bucle <code>while</code>. -</p> -<p>El bucle debe contener una expresión que mueva el punto hacia -adelante palabra por palabra y símbolo por -símbolo, y otra expresión que cuente los saltos. El -test-verdadero-o-falso para el bucle <code>while</code> chequearía -verdadero tan largo como el punto debería saltar hacia -adelante, y falso si apunta al fin de la definición. Ya se ha -redefinido la expresión regular para esto, así el -bucle es sencillo: -</p> -<div class="smallexample"> -<pre class="smallexample">(while (and (< (point) end) - (re-search-forward - "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" end t) - (setq count (1+ count))) -</pre></div> - -<p>La tercera parte de la definición devuelve el contaje de palabras y -símbolos. Esta parte es la última expresión con el -cuerpo de la expresión <code>let</code>, y puede ser, muy la variable -local <code>count</code>, que cuando se evalúa devuelve el contaje. -</p> -<p>Puesto junto, la definición <code>count-words-in-defun</code> se ve -así: -</p> -<a name="index-count_002dwords_002din_002ddefun"></a> -<div class="smallexample"> -<pre class="smallexample">(defun count-words-in-defun () - "Devuelve el número de palabras y símbolos en una defun." - (beginning-of-defun) - (let ((count 0) - (end (save-excursion (end-of-defun) (point)))) -</pre><pre class="smallexample"> (while - (and (< (point) end) - (re-search-forward - "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" - end t)) - (setq count (1+ count))) - count)) -</pre></div> - -<p>¿Cómo se chequea esto? La función no es interactiva, -pero es fácil poner un envoltorio alrededor de la función para -hacerla interactiva; se puede usar casi el mismo código como la -versión recursiva de <code>count-words-example</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Versión Interactiva.</span> -(defun count-words-defun () - "Número de palabras y símbolos en una definición - de función." - (interactive) - (message - "Contando palabras y símbolos en la definición de función ... ") -</pre><pre class="smallexample"> (let ((count (count-words-in-defun))) - (cond - ((zerop count) - (message - "La definición NO tiene palabras o símbolos.")) -</pre><pre class="smallexample"> ((= 1 count) - (message - "La definición tiene 1 palabra o símbolo.")) - (t - (message - "La definición tiene %d palabras o símbolos." count))))) -</pre></div> - -<p>Permite reutilizar <kbd>C-c =</kbd> como un atajo conveniente: -</p> -<div class="smallexample"> -<pre class="smallexample">(global-set-key "\C-c=" 'count-words-defun) -</pre></div> - -<p>Ahora se puede intentar <code>count-words-defun</code>: instala ambas -funciones <code>count-words-in-defun</code> y <code>count-words-defun</code>, y -asigna el atajo, y entonces emplaza el cursor con la siguiente definición: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun multiply-by-seven (number) - "Multiplicar NUMBER por siete." - (* 7 number)) - ⇒ 10 -</pre></div> - -<p>¡Éxito! La definición tiene 10 palabras y -símbolos. -</p> -<p>El siguiente problema es contar los números de palabras y -símbolos en varias definiciones con un fichero simple. -</p> -<hr> -<a name="Varias-funciones"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#count_002dwords_002din_002ddefun" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Encontrar-un-fichero" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Contar-varias-defuns-en-un-fichero"></a> -<h2 class="section">14.4 Contar varias <code>defuns</code> en un fichero</h2> - -<p>Un fichero tal como ‘<tt>simple.el</tt>’ puede tener un centenar o más -definiciones de función dentro. Nuestro objetivo es recoger -estadísticas en muchos ficheros, pero en un primer -paso, nuestro objetivo inmediato es recoger estadísticas -en un fichero. -</p> -<p>La información será una serie de números, cada número siendo -el tamaño de una definición de función. Se pueden almacenar los -números en una lista. -</p> -<p>Se sabe que se querrá incorporar la información considerando un -fichero con información acerca de muchos otros ficheros; esto -significa que la función para contar el tamaño de contaje con un -fichero solo necesita devolver la lista de tamaños. Eso no necesita -y no mostraría mensajes. -</p> -<p>Los comando de contar palabras contienen una expresión para saltar -el punto hacia adelante palabra por palabra y otra expresión para -contar los saltos. La función devuelve los tamaños de definiciones -que pueden ser diseñadas para trabajar del mismo modo, con una -expresión para saltar el punto hacia la definición por -definición y otra expresión para construir el tamaño de la lista. -</p> -<p>Esta frase del problema hace elemental escribir la definición de -función. Claramente, empezaremos el conteo al principio del fichero, -así el primer comando será <code>(goto-char -(point-min))</code>. Lo siguiente, es empezar el bucle <code>while</code>; y este -true-or-false del bucle puede ser una búsqueda de expresión -regular para la siguiente definición de función — -así en el momento que la búsqueda tiene éxito, el -punto se mueve hacia adelante y entonces el cuerpo del bucle es -evaluado. El cuerpo necesita una expresión que construye la lista de -tamaños. <code>cons</code>, la lista de construcción del comando, puede -ser usado para crear la lista. Esto es casi todo lo que hay. -</p> -<p>Aquí está este fragmento de código que se ve -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(goto-char (point-min)) -(while (re-search-forward "^(defun" nil t) - (setq lengths-list - (cons (count-words-in-defun) lengths-list))) -</pre></div> - -<p>Dejamos fuera el mecanismo para encontrar el fichero que contiene las -definiciones de función. -</p> -<p>En ejemplos previos, nosotros habíamos usado esto, el -fichero Info, o cambiamos atrás y adelante a algún otro búffer, -tal como el búffer ‘<tt>*scratch*</tt>’. -</p> -<p>Encontrar un fichero es un nuevo proceso que no tenemos -todavía discutido. -</p> -<hr> -<a name="Encontrar-un-fichero"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Varias-funciones" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#lengths_002dlist_002dfile" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Encontrar-un-fichero-1"></a> -<h2 class="section">14.5 Encontrar un fichero</h2> -<a name="index-Encontrar-un-fichero"></a> - -<p>Para encontrar un fichero en Emacs, se usa el comando <kbd>C-x C-f</kbd> -(<code>find-file</code>). Este comando es casi, pero no bastante correcto -para el problema de tamaños. -</p> -<p>Permita mirar el fuente para <code>find-file</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun find-file (filename) - "Edita el fichero FILENAME. -Cambia a un búffer visitando el fichero FILENAME, -creando uno si no existe ya." - (interactive "FFind file: ") - (switch-to-buffer (find-file-noselect filename))) -</pre></div> - -<p>(La versión más reciente de la definición de función -<code>find-file</code> permite comodines especiales para visitar múltiples -ficheros; que hacen la definición más compleja y no se discutirá -aquí, ya que no es relevante. Se pueden ver sus fuentes -usando <kbd>M-.</kbd> (<code>find-tag</code>) o <kbd>C-h f</kbd> -(<code>describe-function</code>).) -</p> - -<p>La definición que se está mostrando posee una documentación -corta, pero completa y una especificación interactiva que muestra un -nombre de fichero cuando se usa el comando interactivamente. El cuerpo -de la definición contiene dos funciones, <code>find-file-noselect</code> y -<code>switch-to-buffer</code>. -</p> -<p>De acuerdo a su documentación como muestra por <kbd>C-h f</kbd> (el -comando <code>describe-function</code>), la función -<code>find-file-noselect</code> lee el fichero nombrado dentro de un -búffer y devuelve el búffer. (Su versión más reciente incluye -un argumento comodín, también, así como -otro para leer un fichero literalmente y otro que suprime mensajes de -aviso. Estos argumentos opcionales son irrelevantes.) -</p> -<p>Sin embargo, la función <code>find-file-noselect</code> no selecciona el -búffer en el que se pone el fichero. Emacs no cambia su atención -(o la tuya si estás usando <code>find-file-noselect</code>) al búffer -seleccionado. Esto es lo que <code>switch-to-buffer</code> hace: eso cambia -el búffer al que se dirige la atención de Emacs; y eso cambia el -búffer mostrado en la ventana al nuevo búffer. Se ha discutido el -búffer cambiando a otro lugar. (Véase la sección <a href="#Cambiando-b_00faffers">Cambiando búffers</a>.) -</p> -<p>En este proyecto de histograma, no se necesita mostrar cada fichero en -la pantalla como el programa determina el tamaño de cada -definición con eso. En vez de emplear <code>switch-to-buffer</code>, se -puede trabajar con <code>set-buffer</code>, que redirige la atención del -programa de ordenador para un búffer diferente pero no lo muestra en -pantalla. Así en vez llamar a <code>find-file</code> para -hacer el trabajo, debe escribir nuestra expresión. -</p> -<p>La tarea es fácil: usar <code>find-file-noselect</code> y <code>set-buffer</code>. -</p> -<hr> -<a name="lengths_002dlist_002dfile"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Encontrar-un-fichero" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Varios-ficheros" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="lengths_002dlist_002dfile-en-detalle"></a> -<h2 class="section">14.6 <code>lengths-list-file</code> en detalle</h2> - -<p>El núcleo de la función <code>lengths-list-file</code> es un bucle -<code>while</code> conteniendo una función para mover el punto hacia -delante ‘función a función’ y una función para contar el -número de palabras y símbolos en cada función. Este -núcleo debe ser rodeado por funciones que hacen otras tareas varias, -incluyendo encontrar el fichero, y asegurando que el punto empieza al -principio del fichero. La definición de la función se parece a: -<a name="index-lengths_002dlist_002dfile"></a> -</p> -<div class="smallexample"> -<pre class="smallexample">(defun lengths-list-file (filename) - "Devuelve la lista de tamaños de definiciones con FILE. -La lista devuelta es una lista de números. -Cada número es el número de palabras o -símbolos en una definición." -</pre><pre class="smallexample"> (message "Trabajando en `%s' ... " filename) - (save-excursion - (let ((buffer (find-file-noselect filename)) - (lengths-list)) - (set-buffer buffer) - (setq buffer-read-only t) - (widen) - (goto-char (point-min)) - (while (re-search-forward "^(defun" nil t) - (setq lengths-list - (cons (count-words-in-defun) lengths-list))) - (kill-buffer buffer) - lengths-list))) -</pre></div> - -<p>La función pasa un argumento, el nombre del fichero en el que se -trabajará. Eso tiene cuatro líneas de documentación, -pero sin especificación interactiva. Para evitar la preocupación -de si se ha estropeado el programa o no, la primera -línea del cuerpo es un mensaje de aviso. -</p> -<p>La siguiente línea contiene un <code>save-excursion</code> que -devuelve a Emacs la atención al actual búffer cuando la función -se completa. Esto es útil en caso de embeber esta función en otra -función que presume que el punto restaura el búffer original. -</p> -<p>En la varlist de la expresión <code>let</code>, Emacs encuentra el fichero -y ajusta la variable local <code>buffer</code> al búffer conteniendo el -fichero. Al mismo tiempo, Emacs crea <code>lengths-list</code> como una -variable local. -</p> -<p>Lo siguiente, Emacs cambia su atención al búffer. -</p> -<p>En la siguiente línea, Emacs crea el búffer de solo -lectura. Idealmente, esta línea no es necesaria. Ninguna -de las funciones para contar palabras y símbolos en una -definición de función cambiaría el búffer. Debajo, -el búffer no está yendo para ser guardado, incluso si eso fuese -cambiado. Esta línea es enteramente la consecuencia -grata, quizás excesiva precaución. La razón para la precaución -es que esta función y esta se llama a trabajar en las fuentes para -Emacs y eso es un inconveniente si están inadvertidamente -modificadas. Eso va sin decir que no se realizó una necesidad para -esta línea hasta que un experimento fué cambiado hacia -un lado y empezó a modificar mis ficheros de fuentes Emacs … -</p> -<p>Lo siguiente llama a alargar el búffer si eso está encogido. Esta -función es normalmente innecesaria — Emacs crea un búffer fresco -si ninguno ya existe; pero si un búffer está visitando el fichero -que ya existe que Emacs devuelve uno. En este caso, el búffer puede -ser encogido y debe ser amplio. Si se quiere ser completamente ‘amigo -del usuario’, se pondría en orden para guardar la -restricción y la localización del punto, pero no. -</p> -<p>La expresión <code>(goto-char (point-min))</code> mueve el punto al -principio del búffer. -</p> -<p>Entonces llega un bucle <code>while</code> en el que se devuelve el -‘trabajo’ de la función. En el bucle, Emacs determina el tamaño de -cada definición y construye una lista de tamaños conteniendo la -información. -</p> -<p>Emacs corta el búffer después de trabajar a través de eso. Esto -es guardar espacio dentro de Emacs. Mi versión de GNU Emacs 19 -contenía 300 ficheros fuente de interés; GNU Emacs 22 -contiene a través de un millar de ficheros fuente. Otra función -aplicará <code>lengths-list-file</code> a cada uno de los ficheros. -</p> -<p>Finalmente, la última expresión con la expresión <code>let</code> es -la variable <code>lengths-list</code>; su valor es devuelto como el valor de -la función completa. -</p> -<p>Se puede probar esta función instalándolo en el modo -usual. Entonces posiciona tu cursor después de la siguiente -expresión y escribe <kbd>C-x C-e</kbd> (<code>eval-last-sexp</code>). -</p> -<div class="smallexample"> -<pre class="smallexample">(lengths-list-file - "/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el") -</pre></div> - -<p>(Se puede necesitar cambiar la ruta del fichero; el único -aquí es para GNU Emacs versión 22.1.1. Para cambiar la -expresión, cópialo al búffer ‘<tt>*scratch*</tt>’ y -edítalo. -</p> -<p>(También, para ver el tamaño completo de la lista, en vez de una -versión truncada se puede tener que evaluar lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(custom-set-variables '(eval-expression-print-length nil)) -</pre></div> - -<p>(Véase la sección <a href="#defcustom">Especificando Variables usando <code>defcustom</code></a>. Entonces evalúa la expresión -<code>lengths-list-file</code>.) -</p> -<p>La lista de tamaños para ‘<tt>debug.el</tt>’ toma menos de un segundo -para producirse esto en GNU Emacs 22: -</p> -<div class="smallexample"> -<pre class="smallexample">(83 113 105 144 289 22 30 97 48 89 25 52 52 88 28 29 77 49 43 290 232 587) -</pre></div> - -<p>(Usando mi vieja máquina, la versión 19 lista tamaños para -‘<tt>debug.el</tt>’ que en siete segundos para producen esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(75 41 80 62 20 45 44 68 45 12 34 235) -</pre></div> - -<p>(La versión nueva de ‘<tt>debug.el</tt>’ contiene más defuns que la -temprana; y mi nueva máquina es más rápida que la vieja. -</p> -<p>Nótese que el tamaño de la última definición en el fichero es -el primero en la lista. -</p> -<hr> -<a name="Varios-ficheros"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#lengths_002dlist_002dfile" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#lengths_002dlist_002dmany_002dfiles" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Contar-palabras-en-defuns-en-diferentes-ficheros"></a> -<h2 class="section">14.7 Contar palabras en <code>defuns</code> en diferentes ficheros</h2> - -<p>En la sección previa, se creaba una función que devuelve una lista -de los tamaños de cada definición en un fichero. Ahora, se quiere -definir una función para devolver una lista maestra de los tamaños -de las definiciones en una lista de ficheros. -</p> -<p>Trabajar en cada elemento de una lista de ficheros es un acto repetitivo, -así se puede usar un bucle <code>while</code> o recursión. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#lengths_002dlist_002dmany_002dfiles">Determina las longitudes de <code>defuns</code></a></td><td> </td><td align="left" valign="top"> Devolver una lista de tamaños de funciones. -</td></tr> -<tr><td align="left" valign="top"><a href="#append">14.7.1 La función <code>append</code></a></td><td> </td><td align="left" valign="top"> Adjuntar una lista a otra. -</td></tr> -</table> - -<hr> -<a name="lengths_002dlist_002dmany_002dfiles"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Varios-ficheros" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Varios-ficheros" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#append" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Determina-las-longitudes-de-defuns"></a> -<h3 class="unnumberedsubsec">Determina las longitudes de <code>defuns</code></h3> - -<p>El diseño usando un bucle <code>while</code> es rutina. El argumento que -se pasaba a la función es una lista de ficheros. Como se vió -pronto (véase la sección <a href="#Ejemplo-de-bucle">Un bucle <code>while</code> y una lista</a>), se puede escribir un bucle -<code>while</code> de un modo que el cuerpo del bucle es evaluado si tal -lista contiene elementos, pero sale del bucle si la lista está -vacía. Para que este diseño funcione, el cuerpo del -bucle debe contener una expresión que ordene la lista cada vez que -el cuerpo es evaluado, de modo que finalmente la lista esté -vacía. La técnica normal es asignar el valor de la -lista para el valor del <small>CDR</small> de la lista cada vez que el cuerpo es -evaluado. -</p> -<p>La plantilla se ve así: -</p> -<div class="smallexample"> -<pre class="smallexample">(while <var>test-whether-list-is-empty</var> - <var>body</var>… - <var>set-list-to-cdr-of-list</var>) -</pre></div> - -<p>También, recuérdanos que un bucle <code>while</code> devuelve <code>nil</code> -(el resultado de evaluar el true-or-false-test), no el resultado de -cualquier evaluación con su cuerpo. (Las evaluaciones con el cuerpo -del bucle son hechas para sus efectos laterales.) Sin embargo, la -expresión que asigna la lista de tamaños es parte del cuerpo — y -que es el valor que queremos devuelto por la función como un -todo. Para hacer esto cerramos el bucle <code>while</code> con una -expresión <code>let</code>, y pone en orden que el último elemento de la -expresión <code>let</code> contiene el valor de lista de -tamaños. (Véase la sección <a href="#Ejemplo-de-Incremento">El Ejemplo del Bucle con un Contador de Incremento</a>.) -</p> -<a name="index-lengths_002dlist_002dmany_002dfiles"></a> -<p>Estas consideraciones lideran directamente a la función en -sí: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Usar bucle <code>while</code>.</span> -(defun lengths-list-many-files (list-of-files) - "Devuelve la lista de tamaños de funciones en LIST-OF-FILES." -</pre><pre class="smallexample"> (let (lengths-list) - -;;; <span class="roman">true-or-false-test</span> - (while list-of-files - (setq lengths-list - (append - lengths-list - -;;; <span class="roman">Genera una lista de tamaños.</span> - (lengths-list-file - (expand-file-name (car list-of-files))))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; <span class="roman">Crea una lista ordenada de ficheros.</span> - (setq list-of-files (cdr list-of-files))) - -;;; <span class="roman">Devuelve la lista final de valores de tamaños.</span> - lengths-list)) -</pre></div> - -<p><code>expand-file-name</code> es una función construida que convierte un -nombre de fichero al absoluto, forma de nombre de ruta. La función -emplea el nombre del directorio en el que la función se llama. -</p> -<p>De este modo, si <code>expand-file-name</code> es llamado en <code>debug.el</code> -cuando Emacs está visitando el directorio -‘<tt>/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/</tt>’ -</p> -<div class="smallexample"> -<pre class="smallexample">debug.el -</pre></div> - -<p>llega a ser -</p> -<div class="smallexample"> -<pre class="smallexample">/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el -</pre></div> - -<p>El único nuevo elemento de esta definición de función es la -todavía no estudiada función <code>append</code>, que merece -una corta sección en sí. -</p> -<hr> -<a name="append"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#lengths_002dlist_002dmany_002dfiles" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Varios-ficheros" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Varios-ficheros-recursivamente" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-append"></a> -<h3 class="subsection">14.7.1 La función <code>append</code></h3> - -<p>La función <code>append</code> adjunta una lista a otra. De este modo, -</p> -<div class="smallexample"> -<pre class="smallexample">(append '(1 2 3 4) '(5 6 7 8)) -</pre></div> - -<p>produce la lista -</p> -<div class="smallexample"> -<pre class="smallexample">(1 2 3 4 5 6 7 8) -</pre></div> - -<p>Esto es exactamente cómo queremos adjuntar dos listas de tamaños -producidas por <code>lengths-list-file</code> a cualquier otra. Los -resultados contrastan con <code>cons</code>, -</p> -<div class="smallexample"> -<pre class="smallexample">(cons '(1 2 3 4) '(5 6 7 8)) -</pre></div> - -<p>que construye una nueva lista en el que el primer argumento para -<code>cons</code> llega a ser el primer elemento de la nueva lista: -</p> -<div class="smallexample"> -<pre class="smallexample">((1 2 3 4) 5 6 7 8) -</pre></div> - -<hr> -<a name="Varios-ficheros-recursivamente"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#append" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Preparar-los-datos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Recursivamente-cuenta-palabras-en-diferentes-ficheros"></a> -<h2 class="section">14.8 Recursivamente cuenta palabras en diferentes ficheros</h2> - -<p>Bajo un bucle <code>while</code>, se puede trabajar cada lista de ficheros -con recursión. Una versión recursiva de -<code>lengths-list-many-files</code> es corta y simple. -</p> -<p>La función recursiva tiene las partes normales: el ‘do-again-test’, -la ‘next-step-expression’, y la llamada recursiva. El ‘do-again-test’ -determina si la función se llamaría, que hará si la -<code>list-of-files</code> contiene los elementos que permanecen; la -‘next-step-expression’ resetea el <code>list-of-files</code> al <small>CDR</small> en -sí, así finalmente la lista será -vacía; y la llamada recursiva llama en sí -a la lista ordenada. ¡La función completa está -ordenada por esta descripción! -<a name="index-recursive_002dlengths_002dlist_002dmany_002dfiles"></a> -</p> -<div class="smallexample"> -<pre class="smallexample">(defun recursive-lengths-list-many-files (list-of-files) - "Devuelve la lista de tamaños de cada defun en LIST-OF-FILES." - (if list-of-files ; <span class="roman">do-again-test</span> - (append - (lengths-list-file - (expand-file-name (car list-of-files))) - (recursive-lengths-list-many-files - (cdr list-of-files))))) -</pre></div> - -<p>En una frase, la función devuelve de tamaños de la lista para la -el primero de la <code>list-of-files</code> al resultado de llamarse -así mismo al resto de <code>list-of-files</code>. -</p> -<p>Aquí hay un test -<code>recursive-lengths-list-many-files</code>, a lo largo de los resultados -de ejecutar <code>lengths-list-file</code> en cada uno de los ficheros -individualmente. -</p> -<p>Instala <code>recursive-lengths-list-many-files</code> y -<code>lengths-list-file</code>, si es necesario, y entonces evalúa las -siguientes expresiones. Se puede necesitar cambiar las rutas de -ficheros; aquí se trabaja cuando este fichero Info -y las fuentes de Emacs están localizadas en sus lugares -personales. Para cambiar las expresiones, cópialas al búffer -‘<tt>*scratch*</tt>’, edítalos y entonces evalúalos. -</p> -<p>Los resultados son mostrados después del ‘<samp>⇒</samp>’. (Estos -resultados son para ficheros de Emacs versión 22.1.1; ficheros desde -otras versiones de Emacs puede producir diferentes resultados.) -</p> -<div class="smallexample"> -<pre class="smallexample">(cd "/usr/local/share/emacs/22.1.1/") - -(lengths-list-file "./lisp/macros.el") - ⇒ (283 263 480 90) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(lengths-list-file "./lisp/mail/mailalias.el") - ⇒ (38 32 29 95 178 180 321 218 324) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(lengths-list-file "./lisp/makesum.el") - ⇒ (85 181) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (recursive-lengths-list-many-files - '("./lisp/macros.el" - "./lisp/mail/mailalias.el" - "./lisp/makesum.el")) - ⇒ (283 263 480 90 38 32 29 95 178 180 321 218 324 85 181) -</pre></div> - -<p>La función <code>recursive-lengths-list-many-files</code> produce la -salida que queremos. -</p> -<p>El siguiente paso es preparar el dato en la lista para mostrarlo en un -grafo. -</p> -<hr> -<a name="Preparar-los-datos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Varios-ficheros-recursivamente" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Datos-para-mostrar-en-detalle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Preparar-los-datos-para-mostrarlos-en-un-grafo"></a> -<h2 class="section">14.9 Preparar los datos para mostrarlos en un grafo</h2> - -<p>La función <code>recursive-lengths-list-many-files</code> devuelve una -lista de números. Cada número graba el tamaño de una -definición de función. Lo que se necesita hacer ahora es -transformar estos datos dentro de una lista de números ajustado para -generar un grafo. La nueva lista contará cuántas definiciones de -funciones contienen menos de 10 palabras y símbolos, -cuantas contienen entre 10 y 19 palabras y símbolos, -cuántas contienen entre 20 y 29 palabras y símbolos, y -así. -</p> -<p>En breve, se necesita ir a través el tamaño de la lista producida -por la función <code>recursive-lengths-list-many-files</code> y contar el -número de defuns con cada rango de tamaños, y produce una lista de -esto de números. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Datos-para-mostrar-en-detalle">El dato para mostrar en detalle</a></td><td> </td><td align="left" valign="top"> Datos para mostrar en detalle -</td></tr> -<tr><td align="left" valign="top"><a href="#Ordenando">14.9.1 Ordenando listas</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Listar-ficheros">14.9.2 Creando una lista de ficheros</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#Contando-definiciones-de-funci_00f3n">14.9.3 Contando definiciones de función</a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="Datos-para-mostrar-en-detalle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Preparar-los-datos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Preparar-los-datos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ordenando" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-dato-para-mostrar-en-detalle"></a> -<h3 class="unnumberedsubsec">El dato para mostrar en detalle</h3> - -<p>Basado en lo que hemos hecho antes, se prevee que no -sería difícil escribir una función que -‘<small>CDR</small>s’ bajo la lista de tamaños, parece que cada elemento, -determina que rango de tamaños está dentro, e incrementa un -contador para este rango. -</p> -<p>Sin embargo, antes de empezar a escribir tal función, nosotros -consideraríamos las ventajas de ordenar los tamaños de -la lista primero, así los números son ordenados desde -el más pequeño al más largo. Primero, ordenando se hará -fácil contar los números en cada rango, desde dos números -adyacentes será el mismo rango del tamaño en rangos -adyacentes. Segundo, inspeccionando una lista ordenada, se puede -descubrir el número mayor y menor, y esto significa determinar el -rango de tamaño mayor y menor que necesitará. -</p> -<hr> -<a name="Ordenando"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Datos-para-mostrar-en-detalle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Preparar-los-datos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Listar-ficheros" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ordenando-listas"></a> -<h3 class="subsection">14.9.1 Ordenando listas</h3> -<a name="index-sort"></a> - -<p>Emacs contiene una función para listas ordenadas, llamadas (como se -podría adivinar) <code>sort</code>. La función <code>sort</code> -toma dos argumentos, la lista es ordenada, y un predicado que -determina si la primera de dos elementos de lista es “menor” que la -segunda. -</p> -<p>Como se vió antes (véase la sección <a href="#Tipo-incorrecto-de-argumento">Usando el Tipo Incorrecto de Objeto como un Argumento</a>), un predicado es una -función que determina si alguna propiedad es verdadera o falsa. La -función <code>sort</code> reordenará una lista de acuerdo a lo que la -propiedad del predicado usa; esto significa que <code>sort</code> puede ser -usado para ordenar listas no numéricas por un criterio no numérico -— eso puede, por ejemplo, alfabetizar una lista. -</p> -<p>La función <code><</code> se usa cuando se ordena una lista -numérica. Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(sort '(4 8 21 17 33 7 21 7) '<) -</pre></div> - -<p>produce esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(4 7 7 8 17 21 21 33) -</pre></div> - -<p>(Note que en este ejemplo, ambos argumentos se citan -así que los símbolos no se evalúan -antes de ser pasados por <code>sort</code> como argumentos.) -</p> -<p>Ordenando la lista devuelta por la función -<code>recursive-lengths-list-many-files</code> es honesta; eso usa la -funciń <code><</code>: -</p> - -<div class="smallexample"> -<pre class="smallexample">(sort - (recursive-lengths-list-many-files - '("./lisp/macros.el" - "./lisp/mailalias.el" - "./lisp/makesum.el")) - '<) -</pre></div> - -<p>que produce: -</p> -<div class="smallexample"> -<pre class="smallexample">(29 32 38 85 90 95 178 180 181 218 263 283 321 324 480) -</pre></div> - -<p>(Note que en este ejemplo, el primer argumento para <code>sort</code> no -está citado, desde que la expresión debe ser evaluado -así como producir la lista que es pasada para <code>sort</code>.) -</p> -<hr> -<a name="Listar-ficheros"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ordenando" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Preparar-los-datos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-definiciones-de-funci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Creando-una-lista-de-ficheros"></a> -<h3 class="subsection">14.9.2 Creando una lista de ficheros</h3> - -<p>La función <code>recursive-lengths-list-many-files</code> requiere una -lista de fichero como argumento. Para nuestros ejemplos de test, se -construyeron tal como una lista a mano; pero el directorio fuente de -Emacs Lisp es demasiado grande para hacer esto. Así, se -escribirá una función para hacer el trabajo. En esta función, -se usa tanto un bucle <code>while</code> como una llamada recursiva. -</p> -<a name="index-directory_002dfiles"></a> -<p>En viejas versiones de GNU Emacs no hizo falta tener que escribir esta -función, puesto que todos los ficheros ‘<samp>.el</samp>’ en un -directorio. En vez de eso, se puede ser capaz de usar la función -<code>directory-files</code>, que lista los nombres de fichero que hay en un -directorio simple. -</p> -<p>Sin embargo, las versiones reciente Emacs emplazan ficheros de Emacs -Lisp en subdirectorios del directorio de alto nivel ‘<tt>lisp</tt>’. Esto -facilita la navegación. Por ejemplo, todos los ficheros de correo -relacionados que están en el subdirectorio llamado ‘<tt>mail</tt>’. Pero al -mismo tiempo, esta facilidad fuerza a crear un fichero listando la -función que desciende dentro de los subdirectorios. -</p> -<a name="index-files_002din_002dbelow_002ddirectory"></a> -<p>Se puede crear esta función, llamada -<code>files-en-below-directory</code>, usando funciones familiares tales -como <code>car</code>, <code>nthcdr</code>, y <code>substring</code> en conjunción con -una función existente llamada -<code>directory-files-and-attributes</code>. Esta última función no solo -listas de ficheros en un directorio, incluyendo los nombres de -subdirectorios, pero también sus atributos. -</p> -<p>Para empezar nuestro objetivo: crear una función que nos permita -alimentas ficheros a <code>recursive-lengths-list-many-files</code> como una -lista que se parece a esto (pero con más elementos): -</p> -<div class="smallexample"> -<pre class="smallexample">("./lisp/macros.el" - "./lisp/mail/rmail.el" - "./lisp/makesum.el") -</pre></div> - -<p>La función <code>directory-files-and-attributes</code> devuelve una lista -de listas. Cada una de las listas con la lista principal consiste de -13 elementos. El primer elemento es una cadena que contiene el nombre -del fichero – que, en GNU/Linux, puede ser un ‘directorio fichero’, -que dice, un fichero con los atributos especiales de un directorio. El -segundo elemento de la lista es <code>t</code> para un directorio, es una -cadena para el enlace simbólico (la cadena es el nombre enlazado), o -<code>nil</code>. -</p> -<p>Por ejemplo, el primer fichero ‘<samp>.el</samp>’ en el directorio es -‘<tt>abbrev.el</tt>’. Su nombre es -‘<tt>/usr/local/share/emacs/22.1.1/lisp/abbrev.el</tt>’ y no es un -directorio o un enlace simbólico. -</p> -<p>Esto es cómo <code>directory-files-and-attributes</code> lista este -fichero y sus atributos: -</p> -<div class="smallexample"> -<pre class="smallexample">("abbrev.el" -nil -1 -1000 -100 -</pre><pre class="smallexample">(20615 27034 579989 697000) -(17905 55681 0 0) -(20615 26327 734791 805000) -13188 -"-rw-r--r--" -</pre><pre class="smallexample">nil -2971624 -773) -</pre></div> - -<p>Por otro lado, ‘<tt>mail/</tt>’ es un directorio con el directorio -‘<tt>lisp/</tt>’. El principio del listado se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">("mail" -t -… -) -</pre></div> - -<p>(Para aprender acerca de los diferentes atributos, mira en la -documentación de <code>file-attributes</code>. Tenga en mente que la -función <code>file-attributes</code> no lista el nombre del fichero, -así su primer elemento es -<code>directory-files-and-attributes</code> que es el segundo elemento.) -</p> -<p>Se querrán nuestras nuevas funciones, -<code>files-in-below-directory</code>, para listar los fichero ‘<samp>.el</samp>’ en -el directorio eso es contado para chequear, y en los directorios bajo -este directorio. -</p> -<p>Esto nos da una sugestión de como construir -<code>files-in-below-directory</code>: con un directorio, la función -añadir los nombres de ficheros ‘<samp>.el</samp>’ a una lista; y si, con un -directorio, la función viene con un subdirectorio, -iría dentro de este subdirectorio y repite sus acciones. -</p> -<p>Sin embargo, nosotros notaríamos que cada directorio -contiene un nombre que se refiere a sí mismo, llamado -‘<tt>.</tt>’, (“dot”) y un nombre que se refiere a su directorio padre, -llamado ‘<tt>..</tt>’ (“doble punto”). (En ‘<tt>/</tt>’, el directorio -raíz, ‘<tt>..</tt>’ se refiere así mismo, -desde que ‘<tt>/</tt>’ no tiene padre.) Claramente, no que se quiere -nuestra función <code>files-in-below-directory</code> para introducir -estos directorio, desde que ellos siempre nos lideran, directamente o -indirectamente, al directorio actual. -</p> -<p>Consecuentemente, nuestra función <code>files-in-below-directory</code> -debe hacer varias tareas: -</p> -<ul> -<li> -Chequee para ver si se está mirando en un nombre de fichero que -finaliza en ‘<samp>.el</samp>’ y si es así, se añade el nombre -a una lista. - -</li><li> -Chequee para ver si está mirando en un nombre de fichero que es el -nombre de un directorio; y si es así, - -<ul class="no-bullet"> -<li>- -Chequee para ver si está mirando en ‘<tt>.</tt>’ o ‘<tt>..</tt>’; y si es -así sal. - -</li><li>- -O además, ve dentro de este directorio y repite el proceso. -</li></ul> -</li></ul> - -<p>Se permite escribir una definición de función para hacer estas -tareas. Se usará un bucle <code>while</code> para mover de un nombre de -fichero a otro con un directorio chequeando lo que necesita ser hecho; -y se usa una llamada recursiva para repetir las acciones en cada -subdirectorio. El patrón recursivo es ‘acumular’ (véase la sección <a href="#Acumular">Patrón recursivo: <em>accumulate</em></a>) usando <code>append</code> para -combinar. -</p> - - -<p>Aquí está la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun files-in-below-directory (directory) - "Lista los ficheros .el en DIRECTORIO y en sus subdirectorios." - ;; Aunque la función será usada no interactivamente, - ;; será fácil chequear si lo hacemos interactivo. - ;; El directorio tendrá un nombre tal como - ;; "/usr/local/share/emacs/22.1.1/lisp/" - (interactive "DNombre del Directorio: ") -</pre><pre class="smallexample"> (let (el-files-list - (current-directory-list - (directory-files-and-attributes directory t))) - ;; mientras estamos en el directorio actual - (while current-directory-list -</pre><pre class="smallexample"> (cond - ;; chequee para ver si el nombre del fichero finaliza en `.el' - ;; y si es así, añade su nombre a una lista. - ((equal ".el" (substring (car (car current-directory-list)) -3)) - (setq el-files-list - (cons (car (car current-directory-list)) el-files-list))) -</pre><pre class="smallexample"> ;; chequee si el nombre del fichero es un directorio - ((eq t (car (cdr (car current-directory-list)))) - ;; decide si salir o hacer recursión - (if - (equal "." - (substring (car (car current-directory-list)) -1)) - ;; entonces no hagas nada puesto que el nombre del fichero es - ;; el actual directorio o padre, "." o ".." - () -</pre><pre class="smallexample"> ;; else desciende dentro del directorio y repite el proceso - (setq el-files-list - (append - (files-in-below-directory - (car (car current-directory-list))) - el-files-list))))) - ;; mueve al siguiente fichero en la lista; esto también - ;; ordena la lista así mientras el bucle - ;; eventualmente llega a un fin - (setq current-directory-list (cdr current-directory-list))) - ;; devuelve los ficheros - el-files-list)) -</pre></div> - - -<p>Las funciones <code>files-in-below-directory</code> <code>directory-files</code> -toma un argumento, el nombre de un directorio. -</p> -<p>De este modo, en mi sistema, -</p> - -<div class="smallexample"> -<pre class="smallexample">(length - (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/")) -</pre></div> - -<p>se cuenta que dentro y debajo de mi directorio de fuentes Lisp hay -1031 ficheros ‘<samp>.el</samp>’ -</p> -<p><code>files-in-below-directory</code> devuelve una lista en orden -alfabético inverso. Una expresión para ordenar la lista en orden -que parece como este: -</p> -<div class="smallexample"> -<pre class="smallexample">(sort - (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/") - 'string-lessp) -</pre></div> - - -<hr> -<a name="Contando-definiciones-de-funci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Listar-ficheros" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Preparar-los-datos" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Contando-definiciones-de-funcion"></a> -<h3 class="subsection">14.9.3 Contando definiciones de función</h3> - -<p>Nuestro objetivo inmediato es generar una lista que cuenta, cuantas -definiciones de funciones contienen menos de 10 palabras y -símbolos, cuantas contienen entre 10 y 19 palabras y -símbolos, cuantas contienen entre 20 y 29 palabras y -símbolos, y así. -</p> -<p>Con una lista ordenada de números, es fácil: se cuentan cuantos -elementos de la lista son más pequeños de 10, entonces, se -devuelven los números contados, se cuenta cuantos son más -pequeños de 20, entonces se devuelven los números contados, -después se cuentan los que son más pequeños de 30, y -así. Cada uno de los números, 10, 20, 30, 40, y como, -es más grande que el tope de este rango. Se puede llamar a la lista -de tales números, la lista <code>top-of-ranges</code>. -</p> -<p>Si se desea, se podría generar esta lista -automáticamente, pero es más simple escribir una lista -manualmente. Aquí está: -<a name="index-top_002dof_002dranges"></a> -</p> -<div class="smallexample"> -<pre class="smallexample">(defvar top-of-ranges - '(10 20 30 40 50 - 60 70 80 90 100 - 110 120 130 140 150 - 160 170 180 190 200 - 210 220 230 240 250 - 260 270 280 290 300) - "Listar especificando rangos para `defuns-per-range'.") -</pre></div> - -<p>Para cambiar los rangos, se edita esta lista. -</p> -<p>Lo siguiente, que se necesita es escribir la función que crea la -lista del número de definiciones con cada rango. Claramente, esta -función debe tomar el <code>sorted-lengths</code> y las listas -<code>top-of-ranges</code> listas como argumentos. -</p> -<p>La función <code>defuns-per-range</code> debe hacer dos cosas una y otra -vez: eso debe contar el número de definiciones con un rango -específico por el actual valor top-of-range; y eso debe -dividir al siguiente gran valor en la lista <code>top-of-ranges</code> -después de contar el número de definiciones en el rango -actual. Desde que cada una de estas acciones es repetitiva, se puede -usar los bucles <code>while</code> para el trabajo. Un bucle cuenta el -número de definiciones en el rango definido por el valor actual -top-of-range, y el otro bucle selecciona cada uno de los valores -top-of-range en turno. -</p> -<p>Varias entradas de la lista <code>sorted-lengths</code> se cuentan para -cada rango; esto significa que el bucle para la lista -<code>sorted-lengths</code> será dentro del bucle para la lista -<code>top-of-ranges</code>, como un pequeño adorno dentro de un gran adorno. -</p> -<p>El bucle interno cuenta el número de definiciones con el rango. Eso -es un simple contaje del tipo en el que se ha visto -antes. (Véase la sección <a href="#Incrementando-el-Bucle">Un bucle con un contador de incremento</a>). El test true-or-false del bucle chequea si el valor -desde la lista <code>sorted-lengths</code> es más pequeña que el actual -valor de lo alto del rango. Si es así, la función -incrementa el contador y se chequea el siguiente valor desde la lista -<code>sorted-lengths</code>. -</p> -<p>El bucle interno se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(while <var>length-element-smaller-than-top-of-range</var> - (setq number-within-range (1+ number-within-range)) - (setq sorted-lengths (cdr sorted-lengths))) -</pre></div> - -<p>El bucle de fuera debe empezar con el valor más bajo de la lista -<code>top-of-ranges</code>, y entonces se asigna a cada uno de los valores -superiores exitosos a su vez. Esto puede ser hecho con un bucle como -este: -</p> -<div class="smallexample"> -<pre class="smallexample">(while top-of-ranges - <var>body-of-loop</var>… - (setq top-of-ranges (cdr top-of-ranges))) -</pre></div> - -<p>Se ponen juntos, los dos bucles como este: -</p> -<div class="smallexample"> -<pre class="smallexample">(while top-of-ranges - - ;; <span class="roman">Contar el número de elementos con el actual rango.</span> - (while <var>length-element-smaller-than-top-of-range</var> - (setq number-within-range (1+ number-within-range)) - (setq sorted-lengths (cdr sorted-lengths))) - - ;; <span class="roman">Mover al siguiente rango.</span> - (setq top-of-ranges (cdr top-of-ranges))) -</pre></div> - -<p>Además, en cada circuito del bucle exterior, Emacs -grabaría el número de definiciones con este rango (el -valor de <code>number-within-range</code>) en una lista. Se puede usar -<code>cons</code> para este propósito. (Véase la sección <a href="#cons"><code>cons</code></a>.) -</p> -<p>La función <code>cons</code> trabaja bien, excepto que la lista que se -construye contendrá el número de definiciones para el alto rango y -su principio el número de definiciones para el más bajo rango a su -fin. Esto es porque <code>cons</code> adjunta nuevos elementos de la lista -al principio de la lista, y desde los dos bucles que hacen cálculos -a través de la lista de tamaños desde lo bajo finaliza primero, el -<code>defuns-per-range-list</code> finalizará el primer número más -largo. Pero lo que se quiere es imprimir nuestro grafo con pequeños -valores primero y el más grande después. La solución es invertir -el orden del <code>defuns-per-range-list</code>. Nosotros podemos hacer esto -usando la función <code>nreverse</code>, que invierte el orden de una -lista. -<a name="index-nreverse"></a> -</p> -<p>Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(nreverse '(1 2 3 4)) -</pre></div> - -<p>produce: -</p> -<div class="smallexample"> -<pre class="smallexample">(4 3 2 1) -</pre></div> - -<p>Note que la función <code>nreverse</code> es “destructiva” — que es, -cambiar la lista a la que se aplica; esto contrasta con las -funciones <code>car</code> y <code>cdr</code>, que no son destructivas. En este -caso, no se quiere que el original <code>defuns-per-range-list</code>, -de manera que no hay materia que se destruya. (La función -<code>reverse</code> provee un copia inversa de una lista, dejando la lista -original como es.) -<a name="index-reverse"></a> -</p> -<p>Pon todo junto, el <code>defuns-per-range</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun defuns-per-range (sorted-lengths top-of-ranges) - "funciones de SORTED-LENGTHS en cada rango TOP-OF-RANGES." - (let ((top-of-range (car top-of-ranges)) - (number-within-range 0) - defuns-per-range-list) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Bucle Exterior.</span> - (while top-of-ranges -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Bucle Interno.</span> - (while (and - ;; <span class="roman">Necesita el número para el test numérico.</span> - (car sorted-lengths) - (< (car sorted-lengths) top-of-range)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Contar número de definiciones con el rango actual.</span> - (setq number-within-range (1+ number-within-range)) - (setq sorted-lengths (cdr sorted-lengths))) - - ;; <span class="roman">Sal del bucle interno pero permanece con el bucle externo.</span> -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (setq defuns-per-range-list - (cons number-within-range defuns-per-range-list)) - (setq number-within-range 0) ; <span class="roman">Resetear el contaje a cero.</span> -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Mover al siguiente rango.</span> - (setq top-of-ranges (cdr top-of-ranges)) - ;; <span class="roman">Especifica el siguiente mejor rango de valores.</span> - (setq top-of-range (car top-of-ranges))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Salir del bucle externo y contar el número de defuns más - ;; largas que</span> - ;; <span class="roman">el valor más largo del valor top-of-range.</span> - (setq defuns-per-range-list - (cons - (length sorted-lengths) - defuns-per-range-list)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Devuelve una lista del número de definiciones con cada rango,</span> - ;; <span class="roman"> del más pequeño al más largo.</span> - (nreverse defuns-per-range-list))) -</pre></div> - -<p>La función es simple excepto para una pequeña funcionalidad. El -test verdadero-o-falso para el bucle interno se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(and (car sorted-lengths) - (< (car sorted-lengths) top-of-range)) -</pre></div> - -<p>en vez de algo como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(< (car sorted-lengths) top-of-range) -</pre></div> - -<p>El propósito del test es determinar si el primer ítem -en la lista <code>sorted-lengths</code> es menor que el valor de lo mejor -del rango. -</p> -<p>La versión simple del test trabaja bien a menos que la lista -<code>sorted-lengths</code> tiene un valor <code>nil</code>. En este caso, la -expresión <code>(car sorted-lengths)</code> devuelve <code>nil</code>. La -función <code><</code> no se puede compara un número a <code>nil</code>, que -es una lista vacía, así Emacs señala un -error y para la función desde el intento de continuar la ejecución. -</p> -<p>La lista <code>sorted-lengths</code> siempre llega a ser <code>nil</code> cuando -el contador logra el fin de la lista. Esto significa que cualquier -intento de usar la función <code>defuns-per-range</code> con la versión -simple del test fallará. -</p> -<p>Se resuelve el problema usando <code>(car sorted-lengths)</code> en -conjunción con la expresión <code>and</code>. La expresión <code>(car -sorted-lengths)</code> devuelve un valor no <code>nil</code> tan largo como la -lista que tiene al menos un número con eso, pero devuelve <code>nil</code> -si la lista está vacía. La expresión <code>and</code> -primero evalúa el <code>(car sorted-lengths)</code>, y si eso es -<code>nil</code>, devuelve falso <em>sin</em> evaluar la expresión <code><</code> - y devuelve este valor como el valor de la expresión <code>and</code>. -</p> -<p>Este camino, evita un error. -</p> -<p>Aquí hay un pequeño test de la función -<code>defuns-per-range</code>. Primero, evalúa la expresión que ajusta -(una resumida) lista <code>top-of-ranges</code> a la lista de valores, -entonces evalúa la expresión para ajustar la lista -<code>sorted-lengths</code>, y entonces evalúa la función -<code>defuns-per-range</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">;; <span class="roman">(La lista ordenada que usará después.)</span> -(setq top-of-ranges - '(110 120 130 140 150 - 160 170 180 190 200)) - -(setq sorted-lengths - '(85 86 110 116 122 129 154 176 179 200 265 300 300)) - -(defuns-per-range sorted-lengths top-of-ranges) -</pre></div> - -<p>La lista devuelta se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(2 2 2 0 0 1 0 2 0 0 4) -</pre></div> - -<p>Dentro, hay dos elementos de la lista <code>sorted-lengths</code> menores de -110, dos elementos entre 110 y 119, dos elementos entre 120 y 129 y -así. Hay cuatro elementos con un valor de 200 o superior. -</p> -<hr> -<a name="Leyendo-un-grafo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Palabras-en-una-funci_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Contando-definiciones-de-funci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Columnas-de-un-grafo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Leyendo-un-grafo-1"></a> -<h1 class="chapter">15 Leyendo un grafo</h1> -<a name="index-Leyendo-un-grafo"></a> -<a name="index-Grafo-prototipo"></a> -<a name="index-Prototipo-de-grafo"></a> -<a name="index-Cuerpo-de-grafo"></a> - -<p>Nuestro objetivo es construir un grafo mostrando los números de -definiciones de función de varios tamaños en las fuentes de Emacs lisp. -</p> -<p>Como una materia práctica, si se estuviese creando un grafo, -probablemente usarías un programa tal como -<code>gnuplot</code> para hacer el trabajo. (<code>gnuplot</code> está bien -integrado dentro de GNU Emacs.) En este caso, sin embargo, creamos uno -desde cero, y en el proceso lo reconstruimos nosotros mismos con algo de -lo que se aprende antes y así poder aprender más. -</p> -<p>En este capítulo, primero se escribe un grafo simple -imprimiendo la función. Esta primera definición será un -<em>prototipo</em>, una función escrita rápidamente nos permite -reconocer este territorio de crear un grafo. Se descubren dragones, o -resulta que son mitos. Después de olisquear el terreno, nos -sentiremos más confidentes y mejoraremos la función para etiquetar -las coordenadas automáticamente. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Columnas-de-un-grafo">Imprimiendo las columnas de un grafo</a></td><td> </td><td align="left" valign="top"> Columnas de un grafo -</td></tr> -<tr><td align="left" valign="top"><a href="#graph_002dbody_002dprint">15.1 La función <code>graph-body-print</code></a></td><td> </td><td align="left" valign="top"> Cómo imprimir el cuerpo de un grafo. -</td></tr> -<tr><td align="left" valign="top"><a href="#recursive_002dgraph_002dbody_002dprint">15.2 La función <code>recursive-graph-body-print</code></a></td><td> </td><td align="left" valign="top"> recursive-graph-body-print -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejes-Impresos">15.3 Necesidad para ejes impresos</a></td><td> </td><td align="left" valign="top"> Ejes Impresos -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicio-de-L_00ednea-de-Grafo">15.4 Ejercicio</a></td><td> </td><td align="left" valign="top"> Ejercicio de - Línea de Grafo -</td></tr> -</table> - -<hr> -<a name="Columnas-de-un-grafo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#graph_002dbody_002dprint" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Imprimiendo-las-columnas-de-un-grafo"></a> -<h2 class="unnumberedsec">Imprimiendo las columnas de un grafo</h2> - -<p>Puesto que Emacs está diseñado para ser flexible y trabajar con -todo tipo de terminales, incluyendo los terminales de caracteres, el -grafo necesitará ser hecho desde símbolos de -‘escritura’. Un asterisco hará; como nosotros mejoramos la función -de impresión del grafo, se puede crear la elección del -símbolo como una opción de usuario. -</p> -<p>Se puede llamar a esta función <code>graph-body-print</code>; se tomará -un <code>numbers-list</code> como su único argumento. En esta fase, no se -etiquetará el grafo, pero se imprime su cuerpo. -</p> -<p>La función <code>graph-body-print</code> inserta una columna vertical de -asteriscos para cada elemento en la lista <code>numbers-list</code>. La -altura de cada línea está determinada por el valor de -este elemento de la <code>numbers-list</code>. -</p> -<p>Insertar columnas es un acto repetitivo; que significa que esta -función debe ser escrita con un bucle <code>while</code> o -recursivamente. -</p> -<p>Nuestro primer reto es descubrir como imprimir una columna de -asteriscos. Normalmente, en Emacs, se imprimen caracteres dentro de -una pantalla horizontalmente, línea a -línea, escribiendo. Se tienen dos rutas que se pueden -seguir: escribir nuestra función column-insertion o descubrir si una -que exista en Emacs. -</p> -<p>Para ver si hay uno en Emacs, se puede usar el comando <kbd>M-x -apropos</kbd>. Este comando es como el comando <kbd>C-h a</kbd> -(<code>command-apropos</code>), excepto que último encuentra solo estas -funciones que son comandos. El comando <kbd>M-x apropos</kbd> lista todos -los símbolos que se asocian a una expresión regular, -incluyendo funciones que no son interactivas. -<a name="index-apropos"></a> -</p> -<p>Lo que se quiere buscar es algún comando que imprima o inserte -columnas. Muy probablemente, el nombre de la función contendrá la -palabra ‘print’ o la palabra ‘insert’ o la palabra ‘column’. Por esta -razón, podemos simplemente escribir <kbd>M-x apropos RET print -\|insert\|column RET</kbd> y se ve el resultado. En mi sistema, este comando -toma todavía algún tiempo, y entonces se produce una -lista de 79 funciones y variables. Ahora no se tarda mucho y se -produce una lista de 211 funciones y variables. Escaneando la lista, -la única función que se ve como si se pudiera hacer el trabajo que -es <code>insert-rectangle</code>. -</p> -<p>En realidad, esta es la función que queremos; su documentación dice: -</p> -<div class="smallexample"> -<pre class="smallexample">insert-rectangle: -Insertar texto de RECTANGLE con la esquina izquierda a punto -La primera línea de RECTANGLE es insertada al punto -su segunda línea es insertada a un punto verticalmente -bajo el punto, etc. -El RECTANGLE debería ser una lista de cadenas. -Después de este comando, la marca está en la esquina izquierda -superior y el punto en la esquina derecha inferior. -</pre></div> - -<p>Se puede ejecutar un test rápido, para asegurar que hace lo que se -espera de eso. -</p> -<p>Aquí está el resultado de emplazar el cursor después -de la expresión <code>insert-rectangle</code> y escribiendo <kbd>C-u C-x -C-e</kbd> (<code>eval-last-sexp</code>). La función inserta las cadenas -‘<samp>"primero"</samp>’, ‘<samp>"segundo"</samp>’, y ‘<samp>"tercero"</samp>’ en el -punto. También la función devuelve <code>nil</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(insert-rectangle '("primero" "segundo" "tercer"))primero - segundo - terceronil -</pre></div> - -<p>De acuerdo, no se inserta el texto de la expresión -<code>insert-rectangle</code> en sí dentro del búffer en el -que se marca el grafo, pero se llamará la función de nuestro -programa. Nosotros, sin embargo, tenemos que asegurar que el punto -está en el búffer en el lugar donde la función -<code>insert-rectangle</code> insertará la columna de cadenas. -</p> -<p>Si se está leyendo esto en Info, se puede ver como este trabajo -cambia a otro búffer, tal como el búffer ‘<tt>*scratch*</tt>’, -emplazando el punto a algún lugar en el búffer, se escribe -<kbd>M-:</kbd>, después se escribe la expresión <code>insert-rectangle</code> -dentro del minibúffer en la consola, y entonces se escribe -<RET>. Esto causa que Emacs evalúe la expresión en el -minibúffer, pero usa como el valor del punto la posición del punto -en el búffer ‘<tt>*scratch*</tt>’. (<kbd>M-:</kbd> es el atajo para -<code>eval-expression</code>. <code>nil</code> tampoco aparece en el búffer -‘<tt>*scratch*</tt>’ desde que la expresión se evalúa en el -minibúffer.) -</p> -<p>Se encuentra cuando hacer esto hasta el punto que finaliza al fin de -la última línea insertada — es decir, esta función -mueve el punto como un efecto lateral. Si se iba a repetir el comando, -con el punto en esta posición, la siguiente inserción -sería debajo y a la derecha de la inserción -previa. ¡Nosotros no queremos esto!. Si se está yendo a -crear un gráfico de barras, las columnas necesitan estar debajo unas -de otras. -</p> -<p>Así se descubre que cada ciclo del bucle <code>while</code> -de column-inserting debe reposicionar el punto al lugar que queremos, -y este lugar estará arriba, no abajo, de la columna. Más allá, -se recuerda que cuando se imprime un grafo, no esperan todas las -columnas para estar a la misma altura. Esto significa que el alto de -cada columna puede estar a una altura diferente desde una -previa. Nosotros simplemente reposicionamos el punto a la misma -línea cada vez, pero movido cubriendo a la derecha — o -quizás se puede … -</p> -<p>Estamos planeando crear las columnas de la barra gráfica sin -asteriscos. El número de asteriscos en la columna es el número -específico por el elemento actual del -<code>numbers-list</code>. Necesitamos construir una lista de asteriscos del -tamaño derecho para cada llamada a <code>insert-rectangle</code>. Si esta -lista consiste únicamente del número requerido de asteriscos, -entonces tendremos la posición de punto el número correcto de -líneas bajo la base del gráfico para imprimirse -correctamente. Esto podría ser difícil. -</p> -<p>Alternativamente, si podemos figurarnos algún camino para pasar -<code>insert-rectangle</code> del mismo tamaño cada vez, entonces podemos -posicionar el punto en la misma línea cada vez, pero se -mueve a través de una columna a la derecha por cada nueva -columna. Si hacemos esto, sin embargo, alguna de las entradas en la -lista pasaba a <code>insert-rectangle</code> y deben ser espacios en blanco -en vez de asteriscos. Por ejemplo, si la altura máxima del grafo es -5, pero la altura de la columna es 3, entonces <code>insert-rectangle</code> -requiere un argumento que se parezca a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(" " " " "*" "*" "*") -</pre></div> - -<p>Esta última propuesta no es tan difícil, de hecho se -puede determinar la altura de la columna. Hay dos caminos para -nosotros especificar la altura de la columna: se puede arbitrariamente -situar lo que será, lo que funcionaría bien para -gráficas de esta altura; o podemos buscar a través de la lista de -números y usar la altura máxima de la lista como la altura -máxima del grafo. Si la última operación fuera -difícil, entonces el procedimiento formal -sería fácil, pero hay una función construida en -Emacs para determinar el máximo de sus argumentos. Se puede usar -esta función. La función se llamaba <code>max</code> y eso devuelve el -mayor de sus argumentos, que deben ser números. De este modo, por -ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(max 3 4 6 5 7 3) -</pre></div> - -<p>devuelve 7. (Una función correspondiente llamada <code>min</code> devuelve -lo más pequeño de todos sus argumentos.) -<a name="index-max"></a> -<a name="index-min"></a> -</p> -<p>Sin embargo, no podemos simplemente llama a <code>max</code> en el -<code>numbers-list</code>; la función <code>max</code> espera números como sus -argumentos, no una lista de números. De este modo, la siguiente -expresión, -</p> -<div class="smallexample"> -<pre class="smallexample">(max '(3 4 6 5 7 3)) -</pre></div> - -<p>produce el siguiente mensaje error; -</p> -<div class="smallexample"> -<pre class="smallexample">Mal tipo de argumento: number-or-marker-p, (3 4 6 5 7 3) -</pre></div> - -<a name="index-apply"></a> -<p>Se necesita una función que pasa una lista de argumentos a una -función. Esta función es <code>apply</code>. Esta función ‘aplica’ su -primer argumento (una función) para los argumentos que permanecen, -el último puede ser una lista. -</p> -<p>Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(apply 'max 3 4 7 3 '(4 8 5)) -</pre></div> - -<p>devuelve 8 -</p> -<p>(Incidentalmente, yo no sabría cómo aprender acerca de -esta función sin un libro tal como este. Eso es posible descubrir -otras funciones, como <code>search-forward</code> o <code>insert-rectangle</code>, -adivinando una parte de sus nombres y entonces usando -<code>apropos</code>. Incluso aunque su base metafórica es clara — -‘apply’ su primer argumento al resto — dudo que un novicio -vendría con esta palabra particular usando -<code>apropos</code> u otra ayuda. De acuerdo, podría ser -incorrecto; después de todo, la función fué primero llamada por -alguien quien lo había inventado. -</p> -<p>El segundo y subsiguientes argumentos para <code>apply</code> son -opcionales, así se puede usar <code>apply</code> para llamar a -una función y pasan los elementos de una lista, como este, que -también devuelve 8: -</p> -<div class="smallexample"> -<pre class="smallexample">(apply 'max '(4 8 5)) -</pre></div> - -<p>Este camino tardío usará <code>apply</code>. La función -<code>recursive-lengths-list-many-files</code> devuelve una lista de -números que se puede aplicar a <code>max</code> (se podría -también aplicar <em>(hacer apply)</em> a la lista de números -ordenados; eso no importa si la lista está o no). -</p> -<p>Aquí, la operación para encontrar el tamaño máximo -del grafo es este: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq max-graph-height (apply 'max numbers-list)) -</pre></div> - -<p>Ahora se puede devolver la pregunta de como crear una lista de cadenas -para una columna del grafo. Cuenta la máxima altura del grafo y el -número de asteriscos que aparecerían en la columna, la -función devolverá una lista de cadenas para el comando a insertar -<code>insert-rectangle</code>. -</p> -<p>Cada columna se realiza con asteriscos o espacios en blanco. Puesto que -la función pasa el valor del alto de la columna y el número de -asteriscos en el columna, el número de espacios en blanco puede ser -encontrado sustrayendo el número de asteriscos desde lo alto de la -columna. Dado el número de espacios en blanco y el número de -asteriscos, dos bucles <code>while</code> puede ser usado para construir la -lista: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Primera versión.</span> -(defun column-of-graph (max-graph-height actual-height) - "Devuelve la lista de cadenas que una columna de un grafo." - (let ((insert-list nil) - (number-of-top-blanks - (- max-graph-height actual-height))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Llenar asteriscos.</span> - (while (> actual-height 0) - (setq insert-list (cons "*" insert-list)) - (setq actual-height (1- actual-height))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Rellena espacios en blanco.</span> - (while (> number-of-top-blanks 0) - (setq insert-list (cons " " insert-list)) - (setq number-of-top-blanks - (1- number-of-top-blanks))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Devuelve la lista completa.</span> - insert-list)) -</pre></div> - -<p>Si se instala esta función y entonces evalúa la siguiente -expresión se verá que devuelve la lista como se desea: -</p> -<div class="smallexample"> -<pre class="smallexample">(column-of-graph 5 3) -</pre></div> - -<p>devuelve -</p> -<div class="smallexample"> -<pre class="smallexample">(" " " " "*" "*" "*") -</pre></div> - -<p>Como está escrito, <code>column-of-graph</code> contiene una grieta mayor: -los símbolos usados para el espacio en blanco para las -entradas marcadas en la columna son ‘codificadas duras’ como un -espacio y un asterisco. Esto está bien para un prototipo, pero tu, u -otro usuario, puede desear usar otros símbolos. Por -ejemplo, chequeando la función grafo, tu quieres usar un periodo en -vez del espacio, asegura el punto que está siendo reposicionando -apropiadamente cada vez que la función <code>insert-rectangle</code> se -llama; o se podría querer sustituir un signo ‘<samp>+</samp>’ u -otro símbolo para el asterisco. Se podría -incluso querer hacer un graph-column que es más que un ancho de -columna. El programa debería ser más flexible. El -camino para hacer esto es reemplazar el espacio en blanco y el -asterisco con dos variables que se puede llamar <code>graph-blank</code> y -<code>graph-symbol</code> y define estas variables separadamente. -</p> -<p>También la documentación no está escrita. Estas consideraciones -nos llevan también a la segunda versión de la función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defvar graph-symbol "*" - "Cadena usada como símbolo en grafo, normalmente un asterisco.") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(defvar graph-blank " " - "La cadena como un espacio en blanco en grafo, normalmente un - espacio en blanco. -graph-blank debe ser el mismo número de columnas amplio como graph-symbol.") -</pre></div> - -<p>(Para una explicación de <code>defvar</code>, ver <a href="#defvar">Inicializando una Variable con <code>defvar</code></a>.) -</p> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Segunda versión.</span> -(defun column-of-graph (max-graph-height actual-height) - "Devuelve cadenas MAX-GRAPH-HEIGHT; ACTUAL-HEIGHT son - símbolos de grafos. - -</pre><pre class="smallexample">Los graph-symbols son entradas contiguo al fin de la lista. -La lista será insertado como una columna de un grafo. -Las cadenas son tanto graph-blank o graph-symbol. -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (let ((insert-list nil) - (number-of-top-blanks - (- max-graph-height actual-height))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Rellenar en <code>graph-symbols</code>.</span> - (while (> actual-height 0) - (setq insert-list (cons graph-symbol insert-list)) - (setq actual-height (1- actual-height))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> ;; <span class="roman">Rellenar en <code>graph-blanks</code>.</span> - (while (> number-of-top-blanks 0) - (setq insert-list (cons graph-blank insert-list)) - (setq number-of-top-blanks - (1- number-of-top-blanks))) - - ;; <span class="roman">Devuelve la lista completa.</span> - insert-list)) -</pre></div> - -<p>Si se desea, podríamos reescribir <code>column-of-graph</code> -una tercera vez para proporcionar opcionalmente un gráfico de -líneas, como gráfico de barras. Esto no -sería duro de hacer. Un camino para pensar en un grafo -de líneas es que no es más que un grafo de barras en -el que la parte de cada barra que está debajo del alto es -blanco. Para construir una columna para gráfico de -líneas, la función primero construyen una lista de -espacios en blanco que es una más ordenada que el valor, entonces -usa <code>cons</code> para adjuntar un símbolo gráfico a la -lista; entonces eso usa <code>cons</code> de nuevo para adjuntar el ‘alto de -espacios en blanco’ a la lista. -</p> -<p>Es fácil ver como escribir tal función, pero puesto que no se -necesita eso, no se hará. Pero el trabajo podría ser -hecho, y si eso se hiciera, se haría con -<code>column-of-graph</code>. Incluso más importante, no se valora nada -más que pocos cambios que tendrían que ser hechos de -cualquier otra manera. La mejora, que se desea hacer, es simple. -</p> -<p>Ahora, finalmente, volvemos a nuestra primera función de grafo -impresa. Esto imprime el cuerpo de un grafo, no las etiquetas para los -ejes horizontal y vertical, así se puede llamar este -<code>graph-body-print</code>. -</p> -<hr> -<a name="graph_002dbody_002dprint"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Columnas-de-un-grafo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#recursive_002dgraph_002dbody_002dprint" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-graph_002dbody_002dprint"></a> -<h2 class="section">15.1 La función <code>graph-body-print</code></h2> -<a name="index-graph_002dbody_002dprint"></a> - -<p>Después de nuestra preparación en la sección precedente, la -función <code>graph-body-print</code> es simple. La función imprimirá -la columna después de la columna de asteriscos y espacios en blanco, -usando los elementos de la lista de números para especificar el -número de asteriscos en cada columna. Esto es un acto repetitivo, -que significa que se puede usar un bucle <code>while</code> que decrementa o -una función recursiva para el trabajo. En esta sección, se -escribirá la definición usando un bucle <code>while</code>. -</p> -<p>La función <code>column-of-graph</code> requiere el alto del grafo como un -argumento, así se asigna y guarda esto como una variable -local. -</p> -<p>Esto lidera a la siguiente plantilla para el bucle <code>while</code> -versión de esta función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun graph-body-print (numbers-list) - "<var>documentation</var>…" - (let ((height … - …)) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (while numbers-list - <var>insert-columns-and-reposition-point</var> - (setq numbers-list (cdr numbers-list))))) -</pre></div> - -<p>Necesitamos rellenar los slots de la plantilla. -</p> -<p>Claramente, se puede usar la expresión <code>(apply 'max -numbers-list)</code> para determinar el alto del grafo. -</p> -<p>El bucle <code>while</code> iterará a través de <code>numbers-list</code> un -elemento a la vez. Como eso está ordenado por la expresión -<code>(setq numbers-list (cdr numbers-list))</code>, el <small>CAR</small> de cada -instancia de la lista es el valor del argumento para <code>column-of-graph</code>. -</p> -<p>En cada ciclo del bucle <code>while</code>, la función -<code>insert-rectangle</code> inserta la lista devuelta por -<code>column-of-graph</code>. Desde que la función -<code>insert-rectangle</code>, se necesita guardar la localización de -punto al tiempo que el rectángulo se inserta, mueve atrás a esta -posición después de que el rectángulo es insertado, y entonces -se mueve horizontalmente al siguiente lugar desde el que -<code>insert-rectangle</code> se llama. -</p> -<p>Si las columnas se insertan en un carácter amplio, será si los -espacios en blanco y asteriscos se usan, el comando de reposición -es simple <code>(forward-char 1)</code>; sin embargo, el ancho de una -columna puede ser más grande que uno. Esto significa que el comando -de reposicionamiento sería escrito <code>(forward-char -symbol-width)</code>. El mejor lugar para asociar la variable -<code>symbol-width</code> al valor del width de la columna grafo está en -la varlist de la expresión <code>let</code>. -</p> -<p>Estas consideraciones lideran a la siguiente definición de función: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun graph-body-print (numbers-list) - "Imprime un gráfico de barras de la NUMBERS-LIST. -La numbers-list consiste en los valores del eje Y." - - (let ((height (apply 'max numbers-list)) - (symbol-width (length graph-blank)) - from-position) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (while numbers-list - (setq from-position (point)) - (insert-rectangle - (column-of-graph height (car numbers-list))) - (goto-char from-position) - (forward-char symbol-width) -</pre><pre class="smallexample"> ;; <span class="roman">Dibuja la columna del grafo por columna.</span> - (sit-for 0) - (setq numbers-list (cdr numbers-list))) -</pre><pre class="smallexample"> ;; <span class="roman">Emplaza el punto para etiquetas de ejes X.</span> - (forward-line height) - (insert "\n") -)) -</pre></div> - -<p>La expresión inesperada en esta función es la expresión -<code><span class="nolinebreak">(sit-for</span> 0)</code> en el bucle <code>while</code>. Esta expresión hace que el grafo -imprima la operación más interesante para vigilar lo que -sería de otro modo. La expresión causa que Emacs pare -(sit-for 0) para un momento cero y entonces redibuje la -pantalla. Puesto aquí, eso causa que Emacs redibuje la -pantalla columna por columna. Sin eso, Emacs no -redibujaría la pantalla hasta que la función exista. -</p> -<p>Se puede chequear <code>graph-body-print</code> con una pequeña lista de -números. -</p> -<ol> -<li> -Instala <code>graph-symbol</code>, <code>graph-blank</code>, -<code>column-of-graph</code>, que están en -and <code>graph-body-print</code>. - -</li><li> -Copia la siguiente expresión: - -<div class="smallexample"> -<pre class="smallexample">(graph-body-print '(1 2 3 4 6 4 3 5 7 6 5 2 3)) -</pre></div> - -</li><li> -Cambia al búffer ‘<tt>*scratch*</tt>’ y emplaza el cursor donde quiere -que el grafo empiece. - -</li><li> -Escribe <kbd>M-:</kbd> (<code>eval-expression</code>). - -</li><li> -Pega la expresión <code>graph-body-print</code> dentro del minibúffer con -<kbd>C-y</kbd> (<code>yank</code>). - -</li><li> -Presiona <RET> para evaluar la expresión <code>graph-body-print</code> -</li></ol> - -<p>Emacs imprimirá un grafo como este: -</p> -<div class="smallexample"> -<pre class="smallexample"> * - * ** - * **** - *** **** - ********* * - ************ - ************* -</pre></div> - -<hr> -<a name="recursive_002dgraph_002dbody_002dprint"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#graph_002dbody_002dprint" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejes-Impresos" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-recursive_002dgraph_002dbody_002dprint"></a> -<h2 class="section">15.2 La función <code>recursive-graph-body-print</code></h2> -<a name="index-recursive_002dgraph_002dbody_002dprint"></a> - -<p>La función <code>graph-body-print</code> puede también ser escrito -recursivamente. La solución recursiva es dividida dentro de dos -partes: una fuera ‘wrapper’ <em>envoltorio</em> que usa una expresión -<code>let</code> para determinar los valores varias variables que solo -necesitan ser encontradas una vez, tal como la máxima altura del -grafo, y una función dentro que es llamada recursivamente para -imprimir el grafo. -</p> -<p>El ‘envoltorio’ no es complicado: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun recursive-graph-body-print (numbers-list) - "Imprime un gráfico de barras del NUMBERS-LIST. -El numbers-list consiste en los valores del eje Y." - (let ((height (apply 'max numbers-list)) - (symbol-width (length graph-blank)) - from-position) - (recursive-graph-body-print-internal - numbers-list - height - symbol-width))) -</pre></div> - -<p>La función recursiva es un poco más difícil. Eso -tiene cuatro partes: el ‘do-again-test’, el código impreso, la -llamada recursiva, y la ‘next-step-expression’. El ‘do-again-test’ es -una expresión <code>when</code> determina si la <code>numbers-list</code> -contiene cualquier elemento que permanece; si hace eso, la función -imprime una columna del grafo usando el código impreso y se llama -así mismo de nuevo. La función se llama así -misma de nuevo de acuerdo al valor producido por la -‘next-step-expression’ que causa para llamar a actuar en una versión -ordenada de la <code>numbers-list</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun recursive-graph-body-print-internal - (numbers-list height symbol-width) - "Imprime un gráfico de barras. -Usado con la función recursive-graph-body-print." -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (when numbers-list - (setq from-position (point)) - (insert-rectangle - (column-of-graph height (car numbers-list))) -</pre><pre class="smallexample"> (goto-char from-position) - (forward-char symbol-width) - (sit-for 0) ; <span class="roman">Dibuja un gráfico columna por columna.</span> - (recursive-graph-body-print-internal - (cdr numbers-list) height symbol-width))) -</pre></div> - -<p>Después de la siguiente instalación, esta expresión puede ser -chequeada; aquí hay un ejemplo: -</p> -<div class="smallexample"> -<pre class="smallexample">(recursive-graph-body-print '(3 2 5 6 7 5 3 4 6 4 3 2 1)) -</pre></div> - -<p>Aquí está lo que <code>recursive-graph-body-print</code> produce: -</p> -<div class="smallexample"> -<pre class="smallexample"> * - ** * - **** * - **** *** - * ********* - ************ - ************* -</pre></div> - -<p>Cada una de estas dos funciones, <code>graph-body-print</code> o -<code>recursive-graph-body-print</code>, crea el cuerpo de un grafo. -</p> -<hr> -<a name="Ejes-Impresos"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#recursive_002dgraph_002dbody_002dprint" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-L_00ednea-de-Grafo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Necesidad-para-ejes-impresos"></a> -<h2 class="section">15.3 Necesidad para ejes impresos</h2> - -<p>Un grafo necesita ejes impresos, así se puede orientar a -tí mismo. Para un proyecto do-once, eso puede ser -razonable dibujar los ejes a mano usando el modo de emacs Picture, -pero un grafo dibuja la función que puede ser usada más de una vez. -</p> -<p>Por esta razón, se han escrito mejoras a la función básica -<code>print-graph-body</code> que automáticamente imprime etiquetas para -los ejes horizontal y vertical. Puesto que la etiqueta de imprimir -funciones no contiene mucho material nuevo, se ha emplazado su -descripción en un apéndice Véase la sección <a href="#Grafo-completo">Un Grafo con Ejes Etiquetados</a>. -</p> -<hr> -<a name="Ejercicio-de-L_00ednea-de-Grafo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejes-Impresos" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicio-3"></a> -<h2 class="section">15.4 Ejercicio</h2> - -<p>Escribe una versión de línea de grafo de la funciones -de impresión del grafo. -</p> -<hr> -<a name="Inicializaci_00f3n-de-Emacs"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Leyendo-un-grafo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicio-de-L_00ednea-de-Grafo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Configuraci_00f3n-por-defecto" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Tu-fichero-_002eemacs"></a> -<h1 class="chapter">16 Tu fichero ‘<tt>.emacs</tt>’</h1> -<a name="index-fichero-_002eemacs"></a> -<a name="index-Personalizando-tu-fichero-_002eemacs"></a> -<a name="index-Fichero-inicializacion"></a> - -<p>“No te tiene que gustar Emacs para lo que te gusta” — esto que -parece una frase paradójica es el secreto de GNU Emacs. En realidad, -Emacs es una herramienta genérica. La mayoría de la -gente que usa Emacs, lo personaliza para ajustarlo a sus necesidades. -</p> -<p>GNU Emacs está mayoritariamente escrito en Emacs Lisp; esto -significa que escribiendo expresiones en Emacs Lisp se puede modificar -o extender Emacs. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Configuraci_00f3n-por-defecto">Configuración por defecto de Emacs</a></td><td> </td><td align="left" valign="top"> Configuración por defecto -</td></tr> -<tr><td align="left" valign="top"><a href="#Site_002dwide-Init">16.1 Fichero de inicialización site-wide</a></td><td> </td><td align="left" valign="top"> Se puede escribir site-wide ficheros init. -</td></tr> -<tr><td align="left" valign="top"><a href="#defcustom">16.2 Especificar variables usando <code>defcustom</code></a></td><td> </td><td align="left" valign="top"> Emacs escribirá código para ti. -</td></tr> -<tr><td align="left" valign="top"><a href="#Empezando-un-fichero-_002eemacs">16.3 Empieza por un fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td align="left" valign="top"> Cómo escribir un <code>fichero .emacs</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td><td> </td><td align="left" valign="top"> Corta líneas automáticamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#Alias-de-correo">16.5 Alias de correo</a></td><td> </td><td align="left" valign="top"> Usar abreviaciones para direcciones de correo - electrónico. -</td></tr> -<tr><td align="left" valign="top"><a href="#Indentar-modo-de-tabulaciones">16.6 Indentar modo de tabulaciones</a></td><td> </td><td align="left" valign="top"> No usar tabulaciones con TeX -</td></tr> -<tr><td align="left" valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td><td> </td><td align="left" valign="top"> Crear algunos atajos de teclado personales. -</td></tr> -<tr><td align="left" valign="top"><a href="#Mapas-de-teclado">16.8 Mapas de teclado</a></td><td> </td><td align="left" valign="top"> Más acerca de atajos de teclado. -</td></tr> -<tr><td align="left" valign="top"><a href="#Cargando-ficheros">16.9 Cargando ficheros</a></td><td> </td><td align="left" valign="top"> Cargar (por ej. evaluar) ficheros - automáticamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#Autocarga">16.10 Autoloading</a></td><td> </td><td align="left" valign="top"> Crear funciones disponibles. -</td></tr> -<tr><td align="left" valign="top"><a href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></td><td> </td><td align="left" valign="top"> Definir una función; enlazarla a una tecla. -</td></tr> -<tr><td align="left" valign="top"><a href="#Colores-X11">16.12 Colores X11</a></td><td> </td><td align="left" valign="top"> Colores en X. -</td></tr> -<tr><td align="left" valign="top"><a href="#Miscel_00e1nea">16.13 Configuraciones misceláneas para un fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td align="left" valign="top"> Miscelánea -</td></tr> -<tr><td align="left" valign="top"><a href="#Mode-Line">16.14 Una línea modificada</a></td><td> </td><td align="left" valign="top"> Cómo personalizar tu mode line. -</td></tr> -</table> - -<hr> -<a name="Configuraci_00f3n-por-defecto"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Site_002dwide-Init" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Configuracion-por-defecto-de-Emacs"></a> -<h2 class="unnumberedsec">Configuración por defecto de Emacs</h2> - -<p>Hay quien aprecia la configuración por defecto de Emacs. Después -de todo, Emacs empieza en modo C cuando se edita un fichero C, empieza -en modo Fortran cuando se edita un fichero Fortran, y empieza en modo -Fundamental cuando se edita un fichero no adornado. Esto tiene -sentido, si no sabes quien está yendo a usar -Emacs. ¿Quién sabe lo que una persona espera hacer con -un fichero no adornado? El modo fundamental es el modo correcto por -defecto para tal fichero, tal como el modo C es lo correcto para -editar código C. (Suficientes lenguajes de programación tienen -sintaxis que permiten compartir funcionalidades, tal como el modo C es -ahora proporcionado por el modo CC, la ‘Colección C’.) -</p> -<p>Pero cuando se conoce quien está yendo a usar Emacs — tu, tu mismo -– entonces eso tiene sentido para personalizar Emacs. -</p> -<p>Por ejemplo, yo raramente quiero el modo Fundamental cuando edito un -fichero de otro modo no distinguido; yo quiero el modo Texto. Esto es -por lo que yo personalizo Emacs: así eso se ajusta a -mí. -</p> -<p>Se puede personalizar y extender Emacs escribiendo o adaptando un -fichero ‘<tt>~/.emacs</tt>’. Esto es un fichero de inicialización -personal; sus contenidos, escritos en Emacs Lisp, cuentan a Emacs qué -hacer.<a name="DOCF14" href="#FOOT14">(14)</a> -</p> -<p>Un fichero ‘<tt>~/.emacs</tt>’ contiene código Emacs Lisp. Se puede -escribir este código por uno mismo; o se puede usar la funcionalidad -<code>customize</code> para escribir el código para ti. Se puede combinar -tus propias expresiones y expresiones auto-escritas personalizadas en -tu fichero ‘<tt>.emacs</tt>’. -</p> -<p>(Yo prefiero por mí mismo escribir mis propias -expresiones, excepto para estas, fuentes particularmente, que se -encuentran fáciles de manipular usando el comando -<code>customize</code>. Yo combino los dos métodos.) -</p> -<p>La mayoría de este capítulo es acerca de -escribir expresiones por uno mismo. Eso describe un fichero -‘<tt>.emacs</tt>’ simple; para más información, mira <a href="emacs.html#Fichero-de-Inicio">El Fichero de Inicio</a> in <cite>El Manual GNU Emacs</cite>, y la -<a href="elisp.html#Fichero-de-Inicio">El Fichero de Inicio</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>. -</p> -<hr> -<a name="Site_002dwide-Init"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Configuraci_00f3n-por-defecto" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#defcustom" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Fichero-de-inicializacion-site_002dwide"></a> -<h2 class="section">16.1 Fichero de inicialización site-wide</h2> - -<a name="index-fichero-de-inicio-default_002eel"></a> -<a name="index-fichero-inicio-site_002dinit_002eel"></a> -<a name="index-fichero-site_002dload_002eel"></a> -<p>Además de tu fichero de inicialización personal, Emacs -automáticamente carga varios ficheros de inicialización amplios, -si existen. Tienen la misma forma que tu fichero ‘<tt>.emacs</tt>’, pero -se cargan por cualquiera. -</p> -<p>Dos ficheros de incialización, ‘<tt>site-load.el</tt>’ y -‘<tt>site-init.el</tt>’, están cargados dentro de Emacs y volcados -<em>dumped</em> sin una versión dumped de Emacs se creó, como es -más común. (Las copias dumped de Emacs cargan más -rápidamente. Sin embargo, puesto que un fichero se carga y compila, -un cambio no llega a ser un cambio en Emacs a menos que se cargue por -uno mismo o se recompile Emacs. See <a href="elisp.html#Construyendo-Emacs">Construyendo Emacs</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, -y el fichero ‘<tt>INSTALL</tt>’) -</p> -<p>Los otros tres ficheros de inicialización se cargan -automáticamente cada vez que se inicia Emacs, si existen. Son -‘<tt>site-start.el</tt>’, que se carga <em>antes</em> que tu fichero -‘<tt>.emacs</tt>’, y ‘<tt>default.el</tt>’, y el tipo de fichero terminal, que -se cargan <em>después</em> de tu fichero ‘<tt>.emacs</tt>’. -</p> -<p>Las configuraciones y definiciones en tu fichero ‘<tt>.emacs</tt>’ -sobreescribirán las configuraciones en conflicto y definiciones en -un fichero ‘<tt>site-start.el</tt>’, si eso existe; pero las -configuraciones y definiciones en un ‘<tt>default.el</tt>’ o el tipo de -fichero terminal sobreescribirá estos en tu fichero -‘<tt>.emacs</tt>’. (Se pueden prevenir interferencias desde un tipo de -fichero terminal configurando <code>term-file-prefix</code> para -<code>nil</code>. Véase la sección <a href="#Extensi_00f3n-simple">Una extensión simple</a>.) -</p> -<p>El fichero ‘<tt>INSTALL</tt>’ que viene en la distribución contiene -descripciones de los fichero ‘<tt>site-init.el</tt>’ y ‘<tt>site-load.el</tt>’. -</p> -<p>Los ficheros ‘<tt>loadup.el</tt>’, ‘<tt>startup.el</tt>’, y ‘<tt>loaddefs.el</tt>’ -controlan la carga. Estos ficheros están en el directorio -‘<tt>lisp</tt>’ de la distribución Emacs y tiene valor de uso. -</p> -<p>El fichero ‘<tt>loaddefs.el</tt>’ contiene buenas sugerencias como las que -poner dentro de tu propio fichero ‘<tt>.emacs</tt>’, o dentro de un -fichero de inicialización amplio. -</p> -<hr> -<a name="defcustom"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Site_002dwide-Init" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Empezando-un-fichero-_002eemacs" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Especificar-variables-usando-defcustom"></a> -<h2 class="section">16.2 Especificar variables usando <code>defcustom</code></h2> -<a name="index-defcustom"></a> - -<p>Se pueden especificar variables usando <code>defcustom</code> -así que la gente pueda usar la funcionalidad de -Emacs <code>customize</code> para asignar sus valores. (No se puede usar -<code>customize</code> para escribir definiciones de función; pero se -pueden escribir <code>defuns</code> en tu fichero ‘<tt>.emacs</tt>’. En vez de -eso, se puede escribir cualquier expresión Lisp en tu fichero -‘<tt>.emacs</tt>’). -</p> -<p>La funcionalidad <code>customize</code> depende de la forma especial -<code>defcustom</code>. Aunque se puede usar <code>defvar</code> o <code>setq</code> -para las variables que los usuarios asignan, la forma especial -<code>defcustom</code> está diseñada para el trabajo. -</p> -<p>Se puede usar tu conocimiento de <code>defvar</code> para escribir los -primeros tres argumentos para <code>defcustom</code>. El primer argumento -para <code>defcustom</code> es el nombre de la variable. El segundo -argumento es el valor inicial de la variable, cualquiera; y este -valor es asignado solo si el valor no ha sido ya asignado. El tercer -argumento es la documentación. -</p> -<p>El cuarto y subsiguientes argumentos para <code>defcustom</code> especifican -los tipos y opciones; estos no son funcionales en <code>defvar</code>. (Estos -argumentos son opcionales.) -</p> -<p>Cada uno de estos argumentos consiste de una palabra seguido de una -palabra por un valor. Cada palabra clave empieza con los dos puntos -‘<samp>:</samp>’. -</p> -<p>Por ejemplo, la variable de opciones personalizable -<code>text-mode-hook</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defcustom text-mode-hook nil - "El hook normal se ejecuta cuando se introduce en modo texto y - muchos modos relacionados." - :type 'hook - :options '(turn-on-auto-fill flyspell-mode) - :group 'data) -</pre></div> - -<p>El nombre de la variable es <code>text-mode-hook</code>; no tiene valor por -defecto; y su cadena de documentación cuenta lo que hace. -</p> -<p>La palabra clave <code>:type</code> le cuenta a Emacs el tipo de datos para -los que <code>text-mode-hook</code> sería asignado y como -muestra el valor en un búffer de Personalización. -</p> -<p>La palabra clave <code>:options</code> especifica una lista sugerida de -valores para la variable. Normalmente, <code>:options</code> se asocia a un -gancho (<em>hook</em>. La lista es solo una sugerencia; esa no es -exclusiva; una persona quien asigna la variable puede asignarse a -otros valores; la lista mostrada siguiendo la palabra clave -<code>:options</code> se pretende ofrecer elecciones convenientes a un -usuario. -</p> -<p>Finalmente, la palabra clave <code>:group</code> cuenta el comando de -Personalización de Emacs en el que el grupo de la variable está -localizado. Esto cuenta dónde encontralo. -</p> -<p>La función <code>defcustom</code> reconoce más de una docena de palabras -clave. Para más información, mire <a href="elisp.html#Personalizaci_00f3n">Escribiendo las Definiciones de Personalización</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>. -</p> -<p>Considere <code>text-mode-hook</code> como un ejemplo. -</p> -<p>Hay dos caminos para personalizar esta variable. Se puede usar el -comando de personalización o escribir las expresiones apropiadas por -uno mismo. -</p> -<p>Usando el comando de personalización, se puede escribir: -</p> -<div class="smallexample"> -<pre class="smallexample">M-x customize -</pre></div> - -<p>y encuentre que el grupo para editar ficheros de datos se llama -‘datos’. Introduzca este grupo. El Hook <em>Disparador</em> es el primer -miembro. Se puede hacer click en sus opciones varias, tal como -<code>turn-on-auto-fill</code>, para asignar los valores. Después de hacer -click en el botón. -</p> -<div class="smallexample"> -<pre class="smallexample">Guárdalo para Futuras Sesiones -</pre></div> - -<p>Emacs escribirá una expresión en tu fichero ‘<tt>.emacs</tt>’. Se -parecerá a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(custom-set-variables - ;; custom-set-variables fué añadido por Custom. - ;; Si se edita a mano, tu podrías liarte, - ;; así que ten cuidado. - ;; Tu fichero init contendría solo esta instancia. - ;; Si hay más de uno, ellos no quieren trabajar. - '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify)))) -</pre></div> - -<p>(La función <code>text-mode-hook-identify</code> cuenta -<code>toggle-text-mode-auto-fill</code> que buffers hay en modo Texto. Eso -viene automáticamente) -</p> -<p>La función <code>custom-set-variables</code> funciona de alguna manera -diferente más de un <code>setq</code>. Mientras yo nunca he aprendido las -diferencias, yo modifico las expresiones <code>custom-set-variable</code> en -mi fichero ‘<tt>.emacs</tt>’ a mano: yo creo los cambios en los que -aparecen a mi para ser una manera razonable y no tener -problemas. Otros prefieren usar el comando de Personalización y -permitir a Emacs hacer el trabajo para ellos. -</p> -<p>Otra función <code>custom-set-…</code> es -<code>custom-set-faces</code>. Esta función asigna varios tipos de -fuentes. A través del tiempo, yo he asignado un considerable -número de tipos. Algo de tiempo, yo las reseteo usando -<code>customize</code>; otras veces, simplemente edito la expresión -<code>custom-set-faces</code> en mi fichero ‘<tt>.emacs</tt>’ en sí. -</p> -<p>El segundo modo de personalizar tu <code>text-mode-hook</code> es asignarte -a tí mismo en tu fichero ‘<tt>.emacs</tt>’ usando código -que no tiene nada que hacer con las funciones <code>custom-set-…</code>. -</p> -<p>Cuando se hace esto, y después usa <code>customize</code>, se verá un -mensaje que dice: -</p> -<div class="smallexample"> -<pre class="smallexample">CHANGED fuera de Personalizar; operando dentro aquí -puede ser no confiable. -</pre></div> - -<p>Este mensaje es solo un aviso. Si se puede cliquear en el botón a -</p> -<div class="smallexample"> -<pre class="smallexample">Guárdalo para Futuras Sesiones -</pre></div> - -<p>Emacs escribirá una expresión <code>custom-set-…</code> cerca del -fin de tu fichero ‘<tt>.emacs</tt>’ que será evaluado después de que -tu expresión sea escrita a mano. Por esta razón, se -sobreescribirá tu expresión escrita a mano. Ningún daño será -hecho. Cuando se haga esto, sin embargo, ten cuidado para recordar que -expresión está activa; si olvidas, puedes confundirte por -tí mismo. -</p> -<p>Tan largo como se recuerda donde los valores son configurados, no -habrá problemas. En cualquier eventos, los valores son siempre -configurados en tu fichero de inicialización, que es normalmente -llamado ‘<tt>.emacs</tt>’. -</p> -<p>Yo mismo hago un <code>customize</code> para cualquier -cosa. Mayoritariamente, escribo expresiones por mí -mismo. -</p> -<a name="index-defsubst"></a> -<a name="index-defconst"></a> -<p>Incidentalmente, para ser una definición concerniente más -completa: <code>defsubst</code> define una función inline. La sintaxis es -solo como esta de <code>defun</code>. <code>defconst</code> define un -símbolo como una constante. El intento es que ningún -programa o usuario cambiarían un valor asignado por -<code>defconst</code>. (Se puede cambiar; el valor asignado es una variable; -pero por favor no lo haga.) -</p> -<hr> -<a name="Empezando-un-fichero-_002eemacs"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#defcustom" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Texto-y-Autorelleno" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Empieza-por-un-fichero-_002eemacs"></a> -<h2 class="section">16.3 Empieza por un fichero ‘<tt>.emacs</tt>’</h2> -<a name="index-fichero-_002eemacs_002c-empezando"></a> - -<p>Cuando se abre Emacs, se carga tu fichero ‘<tt>.emacs</tt>’ a menos que -se cuente que no se especifique ‘<samp>-q</samp>’ en la línea de -comandos. (El comando <code>emacs -q</code> tu da un Emacs plano, fuera.) -</p> -<p>Un fichero ‘<tt>.emacs</tt>’ contiene expresiones Lisp. Con frecuencia, no -hay más expresiones para configura valores; algunas veces esas son -definiciones de funciones. -</p> -<p>See <a href="emacs.html#Fichero-de-Inicio">El Fichero de Inicio ‘<tt>~/.emacs</tt>’</a> in <cite>El Manual GNU Emacs</cite>, para una corta descripción de fichero -de inicialización. -</p> -<p>Este capítulo cubre algo del mismo suelo, pero es un -paseo entre extractos desde un completo, largamente usado fichero -‘<tt>.emacs</tt>’ — por mí. -</p> -<p>La primera parte del fichero consiste en comentario: me recuerdo a -mí mismo. Por ahora, yo recuerdo estas cosas, pero -cuando empecé, no. -</p> -<div class="smallexample"> -<pre class="smallexample">;;;; fichero .emacs de Bob -; Robert J. Chassell -; 26 de Septiembre de 1985 -</pre></div> - -<p>¡Mira en esta fecha! Yo empecé este fichero hace mucho -tiempo. Yo he estado añadiendo cosas desde siempre. -</p> -<div class="smallexample"> -<pre class="smallexample">; Cada sección en este fichero es introducido por una -; línea empezando con cuatro puntos y comas y cada -; entrada es introducida por una línea empezando con -; tres puntos y comas. -</pre></div> - -<p>Esto describe las convenciones usuales para comentarios en Emacs -Lisp. Cada cosa en una línea que sigue un punto y coma -es un comentario. Dos, tres, y cuatro puntos y coma son usados como -subsección y marcas de sección. (See <a href="elisp.html#Comentarios">Comentarios</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>, para más comentarios.) -</p> -<div class="smallexample"> -<pre class="smallexample">;;;; La Tecla de Ayuda -; Control-h es la tecla de ayuda; -; después escribiendo control-h, escribe una letra a -; indica el asunto acerca del que quieres ayuda. -; Para una explicación de la facilidad de ayuda, -; escribe control-h dos veces en una fila. -</pre></div> - -<p>Solo recuerda: escribe <kbd>C-h</kbd> dos veces para ayudar. -</p> -<div class="smallexample"> -<pre class="smallexample">; Para informarse acerca de cualquier modo, escribe control-h m -; mientras esté en este modo. Por ejemplo, para encontrar -; acerca del modo correo, introduce el modo correo y entonces -; escribe control-h m. -</pre></div> - -<p>‘Modo ayuda’, como yo llamo a esto, es muy útil. Usualmente, se -cuenta todo lo que se necesita saber. -</p> -<p>De acuerdo, no se necesitan incluir comentarios y ficheros como estos -‘<tt>.emacs</tt>’. Yo los incluí en el mío -porque se olvida el Modo ayuda o las convenciones para comentarios — -pero era capaz de recordar ver aquí recordármelo a -mí mismo. -</p> -<hr> -<a name="Texto-y-Autorelleno"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Empezando-un-fichero-_002eemacs" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Alias-de-correo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Modo-texto-y-auto-relleno"></a> -<h2 class="section">16.4 Modo texto y auto relleno</h2> - -<p>Ahora regresa a la parte que ‘vuelve’ al modo Texto y modo Auto Relleno. -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Modo texto modo Auto Fill -;; Las siguiente dos líneas puestas en Emacs dentro de -;; modo Texto y en el modo Auto Fill, son para escritores que -;; quieren empezar a escribir prosa en vez de código. -(setq-default major-mode 'text-mode) -(add-hook 'text-mode-hook 'turn-on-auto-fill) -</pre></div> - -<p>¡Aquí está la primera parte de este -fichero ‘<tt>.emacs</tt>’ que hace alguna cosa bajo recuerdo de un humano -olvidado! -</p> -<p>La primera de las dos líneas entre paréntesis cuentan a -Emacs a cambiar al modo Texto que se encuentra un fichero, <em>a menos -que</em> el fichero iría dentro de algún otro modo, tal -como el modo C. -</p> -<a name="index-Por-buffer_002c-lista-de-variables-locales"></a> -<a name="index-Lista-de-variables-locales_002c-por-buffer_002c"></a> -<a name="index-Seleccion-de-modo-automatico"></a> -<a name="index-Modo-de-seleccion_002c-automatico"></a> -<p>Cuando Emacs lee un fichero, eso parece la extensión al nombre del -fichero. (La extensión es la parte que viene después de un -‘<samp>.</samp>’.) Si el fichero finaliza con una extensión ‘<samp>.c</samp>’ o -‘<samp>.h</samp>’ entonces Emacs cambia al modo C. También, Emacs parece al -principio una línea no blanca del fichero; si la -línea dice ‘<samp><span class="nolinebreak">-*-</span> C <span class="nolinebreak">-*-</span></samp>’, Emacs cambia al modo -C. Emacs posee una lista de extensiones y especificaciones que usa -automáticamente. Además, Emacs se ve cerca de la última página -por buffer, “lista variables locales”. -</p> - -<p>Ahora, regresa al fichero ‘<tt>.emacs</tt>’. -</p> -<p>Aquí está la línea de nuevo; -¿cómo funciona? -</p> -<a name="index-Modo-Texto-activado"></a> -<div class="smallexample"> -<pre class="smallexample">(setq major-mode 'text-mode) -</pre></div> - -<p>Esta línea es un resumen, pero completa la expresión -Emacs Lisp. -</p> -<p>Ya estamos familiarizados con <code>setq</code>. Eso asigna la siguiente -variable, <code>major-mode</code>, al subsiguiente valor, que es -<code>text-mode</code>. La marca de cita simple antes de <code>text-mode</code> -cuenta a Emacs como tratar directamente con el símbolo, -no con cualquier cosa que pudiera existir. Véase la sección <a href="#set-y-setq">Configurando el Valor de una Variable</a>, por un recuerdo de como -<code>setq</code> funciona. El principal punto es que no hay diferencia -entre el procedimiento que se usa para asignar un valor en su fichero -‘<tt>.emacs</tt>’ y el procedimiento que se usa en cualquier lugar más -en Emacs. -</p> -<p>Aquí está la siguiente línea: -</p> -<a name="index-Modo-de-autoajuste-activado"></a> -<a name="index-add_002dhook"></a> -<div class="smallexample"> -<pre class="smallexample">(add-hook 'text-mode-hook 'turn-on-auto-fill) -</pre></div> - -<p>En esta línea, el comando <code>add-hook</code> añade -<code>turn-on-auto-fill</code> para la variable. -</p> -<p>¡<code>turn-on-auto-fill</code> es el nombre de un programa, -que se adivina!, cambia al modo Auto Fill. -</p> -<p>Cada vez que Emacs cambia al modo texto, Emacs ejecuta el comando -‘hooked’ dentro de modo Texto. Así que cada vez que -Emacs cambia al modo Texto, Emacs también cambia al modo de -autoajuste. -</p> -<p>En breve, la primera línea causa a Emacs a entrar en -modo Texto cuando se edite un fichero, a menos que la extensión del -nombre del fichero, una línea no en blanco, variables -locales para contar a Emacs de otro modo. -</p> -<p>El modo texto entre otras acciones, asigna la tabla de sintaxis para -trabajar adecuadamente a escritores. En modo texto, Emacs considera un -apóstrofe como parte de una palabra como una letra; pero Emacs no -considera un período o un espacio como parte de una -palabra. De este modo, <kbd>M-f</kbd> se mueve hacia tí a -través de ‘<samp>eso</samp>’. Por otro lado, en modo C, <kbd>M-f</kbd> para solo -después del ‘<samp>t</samp>’ de ‘<samp>eso</samp>’. -</p> -<p>La segunda línea causa que Emacs active el modo Auto -Fill cuando cambia al modo Texto. En modo Auto Fill, Emacs -automáticamente rompe una línea que es demasiado -amplio y trae la parte excesivamente amplia de la línea -de debajo a la siguiente línea. Emacs rompe -líneas entre palabras con ellas. -</p> -<p>Cuando el modo Auto Fill está desactivado, las líneas -continúan a la derecha como se escriben. Dependiendo de como -configuras el valor de <code>truncate-lines</code>, las palabras que se -escribe si desaparecen al lado derecho de la pantalla, o lo demás -son mostradas, en un modo feo e ilegible, como una línea -de continuación en la pantalla. -</p> -<p>Además, en esta parte de mi fichero ‘<tt>.emacs</tt>’, yo cuento a Emacs -el ajuste de comandos para insertar dos espacios después de dos -puntos: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq colon-double-space t) -</pre></div> - -<hr> -<a name="Alias-de-correo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Texto-y-Autorelleno" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Indentar-modo-de-tabulaciones" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Alias-de-correo-1"></a> -<h2 class="section">16.5 Alias de correo</h2> - -<p>Aquí hay un <code>setq</code> que ‘activa’ el alias de correo, -para más ocasiones. -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Modo Correo -; Para entrar en el modo correo, escribe `C-x m' -; Para introducir RMAIL (para leer el correo), -; escribe `M-x rmail' -(setq mail-aliases t) -</pre></div> - -<a name="index-Alias-de-correo"></a> -<p>Este comando <code>setq</code> asigna el valor de la variable -<code>mail-aliases</code> al <code>t</code>. Desde que <code>t</code> significa cierto, -la línea dice, en efecto, “Sí uso alias -de correo.” -</p> -<p>Los alias de correo son nombres cortos convenientes para largas -direcciones de correo o para listas de direcciones de correo. El -fichero donde guardar tus ‘aliases’ es ‘<tt>~/.mailrc</tt>’. Se escribe -un alias como este: -</p> -<div class="smallexample"> -<pre class="smallexample">alias geo george@foobar.wiz.edu -</pre></div> - -<p>Cuando se escribe un mensaje a Jorge, la dirección a ‘<samp>geo</samp>’; el -correo automáticamente expandirá ‘<samp>geo</samp>’ a la dirección completa. -</p> -<hr> -<a name="Indentar-modo-de-tabulaciones"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Alias-de-correo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Atajos-de-teclado" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Indentar-modo-de-tabulaciones-1"></a> -<h2 class="section">16.6 Indentar modo de tabulaciones</h2> -<a name="index-Tabuladores_002c-previniendo"></a> -<a name="index-indent_002dtabs_002dmode"></a> - -<p>Por defecto, Emacs inserta tabulaciones en lugar en múltiples -espacios cuando se formatea una región. (Por ejemplo, se -podrían indentar muchas líneas de texto -todo a la vez con el comando <code>indent-region</code>.) Los tabuladores se -ven bien en un terminal o con impresión ordinaria, pero ellos -producen mala salida de indentación cuando se usa TeX o Texinfo -puesto que TeX ignora tabuladores. -</p> -<p>Lo siguiente desactiva el modo de Indentar Tabulaciones: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Prevenir Tabulaciones Extrañas -(setq-default indent-tabs-mode nil) -</pre></div> - -<p>Note que esta línea usa <code>setq-default</code> en vez de el -comando <code>setq</code> que hemos visto antes. El comando -<code>setq-default</code> asigna valores solo en búffers que no tienen sus -propios valores locales para la variable. -</p> - -<hr> -<a name="Atajos-de-teclado"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Indentar-modo-de-tabulaciones" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Mapas-de-teclado" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Algunos-atajos"></a> -<h2 class="section">16.7 Algunos atajos</h2> - -<p>Ahora para algunos atajos personales: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Compara ventanas -(global-set-key "\C-cw" 'compare-windows) -</pre></div> - -<a name="index-compare_002dwindows"></a> -<p><code>compare-windows</code> es un comando excelente que compara el texto en -tu ventana actual con texto de la siguiente ventana. Eso hace la -comparación empezando al punto en cada ventana, moviendo a través -del texto en cada ventana tan lejos como ellos asocian. Yo uso este -comando todo el tiempo. -</p> -<p>Esto también muestra como configurar una tecla globalmente, para -todo los modos -</p> -<a name="index-Configurando-una-tecla-globalmente"></a> -<a name="index-Asignar-tecla-global"></a> -<a name="index-Asignando-tecla-globalmente"></a> -<a name="index-global_002dset_002dkey"></a> -<p>El comando es <code>global-set-key</code>. Es seguido por el atajo. En un -fichero ‘<tt>.emacs</tt>’, el atajo es escrito como se ve: <code>\C-c</code> que -se asocia a ‘control-c’, que significa ‘presionar la tecla de control -y la tecla <c> al mismo tiempo’. La <code>w</code> significa ‘presionar -la tecla <w>’. El atajo es rodeado por dobles comillas. En la -documentación, se escribiría esto como <kbd><span class="nolinebreak">C-c</span> w</kbd>. (Si estuviera asociando una tecla <META>, tal como <kbd>M-c</kbd>, -en vez de una tecla de <CTRL>, se escribiría -<code><span class="nolinebreak">\M-c</span></code> en su fichero ‘<tt>.emacs</tt>’. See <a href="emacs.html#Reasociando-Init">Reasociando Teclas en Su Fichero Init</a> in <cite>El Manual de GNU Emacs</cite>, -para más detalles.) -</p> -<p>El comando invocado por las teclas es <code>compare-windows</code>. Note que -<code>compare-windows</code> es precedido por una comilla simple; de otro -modo, Emacs primero intentaría evaluar el -símbolo para determinar su valor. -</p> -<p>Estas tres cosas, las marcas de dobles comillas, la barra invertida -antes de la ‘<samp>C</samp>’, y la marca de comilla simple son partes -necesarias de atajos de teclado que tiendo a olvidar. Afortunadamente, -he llegado a recordar que miraría mi fichero -‘<tt>.emacs</tt>’ existente, y lo adaptaría a lo que hay. -</p> -<p>Como para el atajo en sí: <kbd>C-c w</kbd>, combina la tecla -prefija, <kbd>C-c</kbd>, con un caracter simple, en este caso, -<kbd>w</kbd>. Este conjunto de teclas, <kbd>C-c</kbd> seguido por un caracter -simple, es estrictamente reservado para un uso propio -individual. (Esto se llama teclas ‘propias’, puesto que estas son para -su propio uso). Siempre sería capaz de crear tal atajo -para el uso propio sin pisar fuerte en algún atajo más. Si siempre -se escribe una extensión a Emacs, por favor, evite tomar cualquiera -de estas teclas para uso público. Se cree que una tecla como -<kbd>C-c C-w</kbd> en vez de eso. De otra manera, ejecutará sin sus -‘propias’ teclas. -</p> -<p>Aquí hay otro atajo, con un comentario: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Atajo para `occur' -; Yo uso mucho occur, así permite asignarlo a una tecla: -(global-set-key "\C-co" 'occur) -</pre></div> - -<a name="index-occur"></a> -<p>El comando <code>occur</code> muestra todas las líneas en el -buffer actual que contiene un emparejamiento para una expresión -regular. Asociar las líneas que se muestran en un -búffer llamado ‘<tt>*Occur*</tt>’. Este buffer sirve como un menu para -saltar a ocurrencias. -</p> -<a name="index-global_002dunset_002dkey"></a> -<a name="index-Disociando-la-tecla"></a> -<a name="index-Desasociar-Tecla-a-Comando"></a> -<p>Aquí se muestra como desasignar una tecla, -así no funciona: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Desasociar `C-x f' -(global-unset-key "\C-xf") -</pre></div> - -<p>Hay una razón para esta no asociación: Yo encontré -inadvertidamente escrito <kbd><span class="nolinebreak">C-x</span> f</kbd> cuando significó escribir -<kbd>C-x C-f</kbd>. En vez de encontrar un fichero, como se pretende, -accidentalmente asigna el ancho para el fichero lleno, casi siempre a -un tamaño que no quería. Puesto que duramente se -reseteó mi ancho por defecto, yo simplemente disocié la tecla. -</p> -<a name="index-list_002dbuffers_002c-reasociar"></a> -<a name="index-buffer_002dmenu_002c-asociado-a-tecla"></a> -<p>Lo siguiente reasocia una tecla existente: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Reasocia `C-x C-b' al `buffer-menu' -(global-set-key "\C-x\C-b" 'buffer-menu) -</pre></div> - -<p>Por defecto, <kbd>C-x C-b</kbd> ejecute el comando -<code>list-buffers</code>. Este comando lista sus buffers en <em>otra</em> -ventana. Desde que casi siempre se quiere hacer alguna cosa en esta -ventana, se prefiere el comando <code>buffer-menu</code>, que no solo lista -los buffers, pero mueve el punto dentro de esta ventana. -</p> -<hr> -<a name="Mapas-de-teclado"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Atajos-de-teclado" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Cargando-ficheros" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Mapas-de-teclado-1"></a> -<h2 class="section">16.8 Mapas de teclado</h2> -<a name="index-Mapas-de-teclado"></a> -<a name="index-Reasociando-teclas"></a> - -<p>Emacs usa <em>keymaps</em> para grabar qué teclas llaman a qué -comandos. Cuando se use <code>global-set-key</code> para asignar los atajos -de teclados a un simple comando en todo <code>current-global-map</code>. -</p> -<p>Modos específicos, tales como modo C o modo Texto, tiene -sus propios mapas de teclado; mapas de teclado de modo -específico sobreescribe el mapa global que es compartido -por todos los buffers. -</p> -<p>La función <code>global-set-key</code> asocia, o reasocia, el mapa de -teclado global. Por ejemplo, las siguientes asociaciones la tecla -<kbd>C-x C-b</kbd> a la función <code>buffer-menu</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(global-set-key "\C-x\C-b" 'buffer-menu) -</pre></div> - -<p>Mapas de teclado específico de modo son asociados usando -la función <code>define-key</code>, que toma un mapa de teclado -específico como un argumento, tan bien como la tecla y -el comando. Por ejemplo, mi fichero ‘<tt>.emacs</tt>’ contiene la -siguiente expresión asociada al comando -<code>texinfo-insert-@group</code> comando a <kbd>C-c C-c g</kbd>: -</p> -<div class="smallexample"> -<pre class="smallexample">(define-key texinfo-mode-map "\C-c\C-cg" 'texinfo-insert-@group) -</pre></div> - -<p>La función <code>texinfo-insert-@group</code> en sí es una -pequeña extensión del modo Texinfo que inserta ‘<samp>@group</samp>’ dentro -de un fichero Texinfo. Se usa este comando todo el tiempo y se prefieren -escribir los tres atajos <kbd>C-c C-c g</kbd> en vez de los seis atajos -<kbd>@ g r o u p</kbd>. (‘<samp>@group</samp>’ y su asociación ‘<samp>@end -group</samp>’ son comandos que guarda todo el texto cerrado junto a una -página; muchos ejemplos multi-línea en este libro -están rodeados por ‘<samp>@group … @end group</samp>’.) -</p> -<p>Aquí está la definición de función -<code>texinfo-insert-@group</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun texinfo-insert-@group () - "Inserta la cadena @group en un búffer Texinfo." - (interactive) - (beginning-of-line) - (insert "@group\n")) -</pre></div> - -<p>(De acuerdo, podría haber usado el modo Abbrev para -dejar de escribir, en vez de escribir una función para insertar una -palabra; pero prefiero atajos de teclado consitentes con otro modo -Texinfo para atajos de teclado.) -</p> -<p>Verá numerosas expresiones <code>define-key</code> en ‘<tt>loaddefs.el</tt>’ -tan bien como en varios modos de librerías, tal como -‘<tt>cc-mode.el</tt>’ y ‘<tt>lisp-mode.el</tt>’. -</p> -<p>See <a href="emacs.html#Atajos-de-Teclado">Personalizando Atajos de Teclado</a> in <cite>El Manual GNU Emacs</cite>, y <a href="elisp.html#Mapas-de-Teclado">Mapas de Teclado</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>, para más -información acerca de mapas de teclado. -</p> -<hr> -<a name="Cargando-ficheros"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Mapas-de-teclado" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Autocarga" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Cargando-ficheros-1"></a> -<h2 class="section">16.9 Cargando ficheros</h2> -<a name="index-Cargando-ficheros"></a> - -<p>Muchas personas en la comunidad de GNU Emacs han escrito extensiones a -Emacs. Hace tiempo, que estas extensiones son con frecuencia incluidas -en las nuevas entregas <em>releases</em>. Por ejemplo, los paquetes -Calendario y Diario son ahora parte del estándar GNU Emacs, como es Calc. -</p> -<p>Se puede usar un comando <code>load</code> para evaluar un fichero completo -que significa instalar todas las funciones y variables en el fichero -Emacs. Por ejemplo: -</p> - -<div class="smallexample"> -<pre class="smallexample">(load "~/emacs/slowsplit") -</pre></div> - -<p>Esto evalúa, por ej. carga, el fichero ‘<tt>slowsplit.el</tt>’ o si -eso existe, lo más rápido, el fichero compilado -‘<tt>slowsplit.elc</tt>’ desde el subdirectorio ‘<tt>emacs</tt>’ del -directorio home. El fichero contiene la función -<code>split-window-quietly</code>, que John Robinson escribió en 1989. -</p> -<p>La función <code>split-window-quietly</code> divide una ventana con el -mínimo de redisplay. Yo lo instalé en 1989 porque -trabajó bien con los terminales de 1200 baudios que entonces estaba -usando. Ahora, ocasionalmente vengo a través de una conexión -lenta, pero continúa usando la función porque me gusta el camino -que deja arriba del búffer en el bajo de las nuevas ventanas y -arriba en la ventana superior. -</p> -<p>Para reemplazar el atajo de teclado por defecto -<code>split-window-vertically</code>, se debe también desasignar esta -tecla y asociar las teclas a <code>split-window-quietly</code>, como este: -</p> -<div class="smallexample"> -<pre class="smallexample">(global-unset-key "\C-x2") -(global-set-key "\C-x2" 'split-window-quietly) -</pre></div> - -<a name="index-load_002dpath"></a> -<p>Si se cargan muchas extensiones, como yo hago, entonces en vez de -especificar la posición exacta del fichero, como se muestra arriba, -se puede especificar que directorio como parte del <code>load-path</code> de -Emacs. Entonces, cuando Emacs carga un fichero, buscará que -directorio tan bien como su lista por defecto de directorios. (La -lista por defecto es especificada en ‘<tt>paths.h</tt>’ cuando Emacs se -construye.) -</p> -<p>El comando siguiente añade tu directorio ‘<tt>~/emacs</tt>’ a la ruta -existente: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Ruta Emacs -(setq load-path (cons "~/emacs" load-path)) -</pre></div> - -<p>Incidentalmente, <code>load-library</code> es un interfaz interactivo a la -función <code>load</code>. La función se parece a esto: -</p> -<a name="index-load_002dlibrary"></a> -<div class="smallexample"> -<pre class="smallexample">(defun load-library (library) - "Carga la librería llamada LIBRARY. -Esto es una interfaz a la función `load'." - (interactive - (list (completing-read "Carga la librería: " - (apply-partially 'locate-file-completion-table - load-path - (get-load-suffixes))))) - (load library)) -</pre></div> - -<p>El nombre de la función, <code>load-libray</code>, viene desde el uso de -‘library’ como un sinónimo para ‘file’. La fuente para el comando -<code>load-library</code> está en la librería ‘<tt>files.el</tt>’. -</p> -<p>Otro comando interactivo que hace un trabajo ligeramente diferente es -<code>load-file</code>. See <a href="emacs.html#Librer_00edas-Lisp">Librerías de Código Lisp para Emacs</a> in <cite>El Manual GNU Emacs</cite>, para información en la distinción entre -<code>load-library</code> y este comando. -</p> -<hr> -<a name="Autocarga"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Cargando-ficheros" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Extensi_00f3n-simple" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Autoloading"></a> -<h2 class="section">16.10 Autoloading</h2> -<a name="index-autoload"></a> - -<p>En vez de instalar una función cargando el fichero que lo contiene, -o evaluando la definición de función, se puede hacer la función -disponible pero actualmente no se instala hasta la primera vez -llamada. Este proceso se llama <em>autocarga</em> (<em>autoloading</em>). -</p> -<p>Cuando se ejecuta una función de autocarga, Emacs automáticamente -evalúa el fichero que contiene la definición, y entonces llama a -la función. -</p> -<p>Emacs empieza rápido con funciones de autocarga, puesto que sus -librerías no se cargan bien; pero si necesita esperar un -momento cuando su primer uso tal como una función, mientras que el -fichero que lo contiene se evalúa. -</p> -<p>Raramente las funciones usadas son frecuentemente autocargadas. La -librería ‘<tt>loaddefs.el</tt>’ coniene cientos de funciones -autocargadas, desde <code>bookmark-set</code> a <code>wordstar-mode</code>. Si se -usa una función ‘rara’ frecuentemente, se debería -cargar este fichero de función con una expresión de <code>load</code> en -tu fichero ‘<tt>.emacs</tt>’. -</p> -<p>En mi fichero ‘<tt>.emacs</tt>’, se cargan 14 librerías que -contienen funciones que de otro modo serían -autocargadas. (Actualmente, eso habría sido mejor para -incluir estos ficheros en mi Emacs ‘volcado’, pero se -olvida. See <a href="elisp.html#Construyendo-Emacs">Construyendo Emacs</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>, y el fichero ‘<tt>INSTALL</tt>’ para -más acerca de volcados.) -</p> -<p>Se puede también querer incluir expresiones autocargadas en tu -fichero ‘<tt>.emacs</tt>’. <code>autoload</code> es una función construida que -toma cinco argumento, los tres finales de los que son opcionales. El -primer argumento es el nombre de la función para ser autocargada. El -segundo es el nombre del fichero para ser cargado. El tercer -argumento es documentación para la función, y el cuarto cuenta si -la función puede ser llamada interactivmente. El quinto argumento -cuenta que tipo de objeto — <code>autoload</code> puede manejar un mapa de -teclado o macro tan bien como una función (por defecto es una función). -</p> -<p>Aquí hay un ejemplo típico: -</p> -<div class="smallexample"> -<pre class="smallexample">(autoload 'html-helper-mode - "html-helper-mode" "Editar documentos HTML" t) -</pre></div> - -<p>(<code>html-helper-mode</code> es una vieja alternativa a <code>html-mode</code>, -que es una parte estándar de la distribución.) -</p> -<p>Esta expresión autocarga la función <code>html-helper-mode</code>. Esto -se toma desde el fichero ‘<tt>html-helper-mode-el</tt>’ (o desde la -versión compilada ‘<tt>html-helper-mode.elc</tt>’, si eso existe). El -fichero debe ser localizado en un directorio específico -por <code>load-path</code>. La documentación dice que esto es un modo para -ayudar a editar documentos escritos en Lenguaje de Marcas de Hiper -Texto. Se puede llamar este modo interactivamente escribiendo <kbd>M-x -html-helper-mode</kbd>. (Se necesitan duplicar las funciones regulares de -documentación en la expresión de autocarga porque la función -regular no está todavía cargada, así su -documentación no está disponible.) -</p> -<p>See <a href="elisp.html#Autocarga">Autocarga</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, para más información. -</p> -<hr> -<a name="Extensi_00f3n-simple"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Autocarga" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Colores-X11" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-extension-simple_003a-line_002dto_002dtop_002dof_002dwindow"></a> -<h2 class="section">16.11 Una extensión simple: <code>line-to-top-of-window</code></h2> -<a name="index-line_002dto_002dtop_002dof_002dwindow"></a> -<a name="index-Extension-simple-en-fichero-_002eemacs"></a> - -<p>Aquí hay una simple extensión a Emacs que mueve el -punto de línea arriba de la ventana. Yo uso esto todo el -tiempo, para hacer fácil de leer el texto. -</p> -<p>Se puede poner el siguiente código dentro de un fichero separado y -entonce cargarlo desde tu fichero ‘<tt>.emacs</tt>’, o se puede incluir -con tu fichero ‘<tt>.emacs</tt>’. -</p> -<p>Aquí está la definición -</p> -<div class="smallexample"> -<pre class="smallexample">;;; Línea a lo alto de la ventana; -;;; reemplaza tres secuencias de atajos de teclado C-u 0 C-l -(defun line-to-top-of-window () - "Mueve la línea que apunta a lo alto de la ventana." - (interactive) - (recenter 0)) -</pre></div> - -<p>Ahora el atajo. -</p> -<p>En estos días, las teclas de función así -como los eventos del ratón y caracteres no <small>ASCII</small> son escritos -con corchetes, sin marcas de citas. (En Emacs versión 18 y -anteriores, se tenía que escribir diferentes teclas de -función asignadas por cada diferente creación del terminal.) -</p> -<p>Se puede asociar <code>line-to-top-of-window</code> a la tecla de función -<F6> así: -</p> -<div class="smallexample"> -<pre class="smallexample">(global-set-key [f6] 'line-to-top-of-window) -</pre></div> - -<p>Para más información, mira <a href="emacs.html#Reasociando-el-Init">Reasociando Teclas en tu fichero init</a> in <cite>El Manual GNU Emacs</cite>. -</p> -<a name="index-Condicional-marcaran-estas-dos-versiones-de-Emacs"></a> -<a name="index-Version-de-Emacs_002c-eligiendo"></a> -<a name="index-Version-de-Emacs_002c-eligiendo-1"></a> -<p>Si ejecutas dos versiones de GNU Emacs, tal como las versiones 22 y -23, y usas un fichero ‘<tt>.emacs</tt>’, se puede seleccionar qué código -evalúa el siguiente condicional: -</p> -<div class="smallexample"> -<pre class="smallexample">(cond - ((= 22 emacs-major-version) - ;; evalúa la version 22 - ( … )) - ((= 23 emacs-major-version) - ;; evalúa la version 23 - ( … ))) -</pre></div> - -<p>Por ejemplo, en versiones más recientes se ocultan los cursores por -defecto. Si se odia tal ocultación se escribe lo siguiente en mi -fichero ‘<tt>.emacs</tt>’<a name="DOCF15" href="#FOOT15">(15)</a>: -</p> -<div class="smallexample"> -<pre class="smallexample">(when (>= emacs-major-version 21) - (blink-cursor-mode 0) - ;; Inserta la nueva línea cuando se presiona `C-n' (next-line) - ;; al fin del búffer - (setq next-line-add-newlines t) -</pre><pre class="smallexample"> ;; Cambia la imagen viendo - (auto-image-file-mode t) -</pre><pre class="smallexample"> ;; Activa la barra de menu (esta barra tiene texto) - ;; (Usa un argumento numérico para activarlo) - (menu-bar-mode 1) -</pre><pre class="smallexample"> ;; Desactiva la barra de herramientas (esta barra tiene iconos) - ;; (Usa argumentos numéricos para activarlo) - (tool-bar-mode nil) -</pre><pre class="smallexample"> ;; Desactiva el modo tooltip para la tool bar - ;; (Este modo causa explicaciones de iconos al pop up) - ;; (Usa el argumento numérico para activarlo) - (tooltip-mode nil) - ;; Si los tooltips activados, crea consejos aparecen en el prompt - (setq tooltip-delay 0.1) ; por defecto es de 0.7 segundos - ) -</pre></div> - -<hr> -<a name="Colores-X11"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Extensi_00f3n-simple" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Miscel_00e1nea" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Colores-X11-1"></a> -<h2 class="section">16.12 Colores X11</h2> - -<p>Se pueden especificar colores cuando se usa Emacs con el Sistema de -Ventanas X del MIT. -</p> -<p>Si disgustan los colores por defecto y especifica unos propios. -</p> -<p>Aquí están las expresiones en un fichero ‘<tt>.emacs</tt>’ -que establecen los valores: -</p> -<div class="smallexample"> -<pre class="smallexample">;; Asigna el color del cursor -(set-cursor-color "white") - -;; Asigna el color del ratón -(set-mouse-color "white") - -;; Asigna foreground y background -(set-foreground-color "white") -(set-background-color "darkblue") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;;; Asigna colores para isearch y drag -(set-face-foreground 'highlight "white") -(set-face-background 'highlight "blue") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(set-face-foreground 'region "cyan") -(set-face-background 'region "blue") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(set-face-foreground 'secondary-selection "skyblue") -(set-face-background 'secondary-selection "darkblue") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; Asigna colores al calendario -(setq calendar-load-hook - '(lambda () - (set-face-foreground 'diary-face "skyblue") - (set-face-background 'holiday-face "slate blue") - (set-face-foreground 'holiday-face "white"))) -</pre></div> - -<p>Las varias sombras de azul disparan mi ojo y me preveen de ver la -ventana desplegada. -</p> -<p>Alternativamente, se podrían haber configurado mis -especificaciones en varios ficheros inicialización de X. Por -ejemplo, se podría asignar el foreground, background, -cursor y puntero (por ej., ratón) colores en mi fichero -‘<tt>~/.Xresources</tt>’ como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">Emacs*foreground: white -Emacs*background: darkblue -Emacs*cursorColor: white -Emacs*pointerColor: white -</pre></div> - -<p>En cualquier evento que no es parte de Emacs, se asigna el color -raíz de mi ventana X en mi fichero ‘<tt>~/.xinitrc</tt>’, -como este<a name="DOCF16" href="#FOOT16">(16)</a> -</p> -<div class="smallexample"> -<pre class="smallexample">xsetroot -solid Navy -fg white & -</pre></div> - -<hr> -<a name="Miscel_00e1nea"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Colores-X11" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Mode-Line" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Configuraciones-miscelaneas-para-un-fichero-_002eemacs"></a> -<h2 class="section">16.13 Configuraciones misceláneas para un fichero ‘<tt>.emacs</tt>’</h2> - -<p>Aquí hay unas pocas configuraciones misceláneas: -</p><br> - -<ul class="no-bullet"> -<li>- -Asigna la forma y color del ratón del cursor: - -<div class="smallexample"> -<pre class="smallexample">; Formas de Cursor están definidas en -; `/usr/include/X11/cursorfont.h'; -; por ejemplo, el cursor `objetivo' es número 128; -; el cursor `top_left_arrow' es el número 132. -</pre><pre class="smallexample"> -</pre><pre class="smallexample">(let ((mpointer (x-get-resource "*mpointer" - "*emacs*mpointer"))) - ;; Si no se ha asignado tu puntero de ratón - ;; entonces asignalo, de otro modo, déjalo así: - (if (eq mpointer nil) - (setq mpointer "132")) ; top_left_arrow -</pre><pre class="smallexample"> (setq x-pointer-shape (string-to-int mpointer)) - (set-mouse-color "white")) -</pre></div> - -</li><li>- -O se pueden asignar los valores de una variedad de funcionalidades en -una alist, como esta: - -<div class="smallexample"> -<pre class="smallexample">(setq-default - default-frame-alist - '((cursor-color . "white") - (mouse-color . "white") - (foreground-color . "white") - (background-color . "DodgerBlue4") - ;; (cursor-type . bar) - (cursor-type . box) -</pre><pre class="smallexample"> (tool-bar-lines . 0) - (menu-bar-lines . 1) - (width . 80) - (height . 58) - (font . - "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1") - )) -</pre></div> - -</li><li>- -Convierte <kbd><CTRL>-h</kbd> dentro <DEL> y <DEL> dentro de -<kbd><CTRL>-h</kbd>.<br> (Algunos viejos teclados lo necesitan, aunque yo -no he visto el problema recientemente.) - -<div class="smallexample"> -<pre class="smallexample">;; Traducir `C-h' a <DEL>. -; (keyboard-translate ?\C-h ?\C-?) - -;; Traducir <DEL> a `C-h'. -(keyboard-translate ?\C-? ?\C-h) -</pre></div> - -</li><li>- ¡Desactiva un cursor oculto! - -<div class="smallexample"> -<pre class="smallexample">(if (fboundp 'blink-cursor-mode) - (blink-cursor-mode -1)) -</pre></div> - -<p>o empieza GNU Emacs con el comando <code>emacs -nbc</code>. -</p> -</li><li>- Cuando se usa ‘grep’<br> -‘<samp>-i</samp>’ Ignore distinciones de letras<br> ‘<samp>-n</samp>’ El -prefijo de cada línea de la salida con el número de -líneas<br> ‘<samp>-H</samp>’ Imprime el nombre de fichero -para cada cadena encontrada.<br> ‘<samp>-e</samp>’ Protege patrones -empezando con un caracter de guión, ‘<samp>-</samp>’ - -<div class="smallexample"> -<pre class="smallexample">(setq grep-command "grep -i -nH -e ") -</pre></div> - - -</li><li>- Encuentra un búffer existente, incluso si eso tiene un nombre -diferente<br> -Esto evita problemas con enlaces simbólicos. - -<div class="smallexample"> -<pre class="smallexample">(setq find-file-existing-other-name t) -</pre></div> - -</li><li>- Configura tu entorno de lenguaje y el método de entrada por defecto - -<div class="smallexample"> -<pre class="smallexample">(set-language-environment "latin-1") -;; Recuerda que se puede habilitar o deshabilitar el texto de lenguaje -;; multilingüe con el comando <code>toggle-input-method'</code> (<kbd>C-\</kbd>) -(setq default-input-method "latin-1-prefix") -</pre></div> - -<p>Si se quiere escribir con el caracter Chino ‘GB’, asigna esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(set-language-environment "Chinese-GB") -(setq default-input-method "chinese-tonepy") -</pre></div> -</li></ul> - -<a name="Arreglando-Atajos-de-Teclados"></a> -<h4 class="subsubheading">Arreglando Atajos de Teclados</h4> -<a name="index-Atajos-de-Teclado_002c-arreglando"></a> -<a name="index-Asociaciones_002c-teclas_002c-arreglando"></a> - -<p>Algunos sistemas asocian teclas de maneras no agradables. Algunas -veces, por ejemplo, la tecla <CTRL> en un modo perverso en vez de -la lejanía a la izquierda de la fila. -</p> -<p>Normalmente, cuando las personas arreglan estos atajos de teclado, no -se cambia su fichero ‘<tt>~/.emacs</tt>’. En vez de eso, se asocian las -teclas apropiadas en sus consolas con los comandos <code>loadkeys</code> o -<code>install-keymap</code> en su script de inicio y entonces incluyen -comandos <code>xmodmap</code> en su fichero ‘<tt>.xinitrc</tt>’ o -‘<tt>.Xsession</tt>’ para X Windows. -</p> -<p>Para un script de inicio: -</p> -<div class="smallexample"> -<pre class="smallexample">loadkeys /usr/share/keymaps/i386/qwerty/emacs2.kmap.gz -or -install-keymap emacs2 -</pre></div> - -<p>Para un fichero ‘<tt>.xinitrc</tt>’ o un fichero ‘<tt>.Xsession</tt>’ cuando la -tecla <Caps Lock> es que tan lejos de la fila del home: -</p> -<div class="smallexample"> -<pre class="smallexample"># Asocia la tecla etiquetada `Caps Lock' a `Control' -# (Tal como un interfaz de usuario roto sugiere que el teclado hecho -# piensa que los ordenadores son máquinas de escribir desde 1885.) - -xmodmap -e "clear Lock" -xmodmap -e "add Control = Caps_Lock" -</pre></div> - -<p>En un ‘<tt>.xinitrc</tt>’ o ‘<tt>.Xsession</tt>’, para convertir una tecla -<ALT> a una tecla <META>: -</p> -<div class="smallexample"> -<pre class="smallexample"># Algunos teclados mal diseñados tienen una tecla etiquetada ALT y no Meta -xmodmap -e "keysym Alt_L = Meta_L Alt_L" -</pre></div> - -<hr> -<a name="Mode-Line"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Miscel_00e1nea" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-linea-modificada"></a> -<h2 class="section">16.14 Una línea modificada</h2> -<a name="index-mode_002dline_002dformat"></a> -<a name="index-Formato-de-Modo-Linea"></a> - -<p>Finalmente, una funcionalidad que realmente me gusta: un mode line -modificado. -</p> -<p>Cuando se trabaja a través de una red, se olvida que máquina se -está usando. También, se tiende a perder la traza de donde se -está, y a qué línea se apunta. -</p> -<p>Así se resetea mi mode line para que se parezca a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">-:-- foo.texi rattlesnake:/home/bob/ Line 1 (Texinfo Fill) Top -</pre></div> - -<p>Estoy visitando un fichero llamado ‘<tt>foo.texi</tt>’, en mi máquina -‘<tt>rattlesnake</tt>’ en mi búffer ‘<tt>/home/bob</tt>’. Yo estoy en la -línea 1, en modo Texinfo, y estoy arriba del búffer. -</p> -<p>Mi fichero ‘<tt>.emacs</tt>’ tiene una sección que se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">;; Asigna un Mode Line que nos cuente que máquina, que directorio, -;; y que línea estoy on, más la información de client. -(setq-default mode-line-format - (quote - (#("-" 0 1 - (help-echo - "mouse-1: select window, mouse-2: delete others ...")) - mode-line-mule-info - mode-line-modified - mode-line-frame-identification - " " -</pre><pre class="smallexample"> mode-line-buffer-identification - " " - (:eval (substring - (system-name) 0 (string-match "\\..+" (system-name)))) - ":" - default-directory - #(" " 0 1 - (help-echo - "mouse-1: select window, mouse-2: delete others ...")) - (line-number-mode " Line %l ") - global-mode-string -</pre><pre class="smallexample"> #(" %[(" 0 6 - (help-echo - "mouse-1: select window, mouse-2: delete others ...")) - (:eval (mode-line-mode-name)) - mode-line-process - minor-mode-alist - #("%n" 0 2 (help-echo "mouse-2: widen" local-map (keymap ...))) - ")%] " - (-3 . "%P") - ;; "-%-" - ))) -</pre></div> - -<p>Aquí, se redefine el mode line por defecto. La -mayoría de las partes son desde el original; pero yo -creo unos pocos cambios. Yo asigno el formato de mode line -<em>default</em> así como permitir varios modos, tales -como Info, para sobreescribirlo. -</p> -<p>Muchos elementos en la lista son auto-explicativos: -<code>mode-line-modified</code> es una variable que cuenta si el búffer ha -sido modificado, <code>mode-name</code> cuenta el nombre del modo, y -así. Sin embargo, el formato parece complicado porque -las dos funcionalidades no han sido discutidas. -</p> -<a name="index-Propiedades_002c-en-el-ejemplo-del-modo-linea"></a> -<p>The first string in the mode line is a dash or hyphen, ‘<samp>-</samp>’. In the old -days, it would have been specified simply as <code>"-"</code>. But nowadays, -Emacs can add properties to a string, such as highlighting or, as in this -case, a help feature. If you place your mouse cursor over the hyphen, some -help information appears (By default, you must wait seven-tenths of a second -before the information appears. You can change that timing by changing the -value of <code>tooltip-delay</code>.) -</p> -<p>La nueva cadena de formato tiene una sintaxis especial: -</p> -<div class="smallexample"> -<pre class="smallexample">#("-" 0 1 (help-echo "mouse-1: select window, ...")) -</pre></div> - -<p>El <code>#(</code> empieza una lista. El primer elemento de la lista es la -cadena en sí, solo un ‘<samp>-</samp>’. El segundo y tercer -elemento especifica el rango a través del cuarto elemento -aplicado. Un rango empieza <em>después</em> un carácter, -así un cero significa el rango que empieza solo -después del primer caracter; un 1 significa que el rango finaliza -solo después del primer caracter. El tercer elemento es la propiedad -para el rango. Eso consiste en una lista de propiedades, un nombre de -propiedad, en este caso, ‘<samp>help-echo</samp>’, seguido por un valor, en -este caso, una cadena. El segundo, tercer y cuarto elemento de este -nuevo formato de cadena puede ser repetido. -</p> -<p>See <a href="elisp.html#Propiedades-de-Texto">Propiedades de Texto</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, y ver <a href="elisp.html#Formato-Mode-Line">Formato Mode Line</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, -para más información. -</p> -<p><code>mode-line-buffer-identification</code> muestra el nombre del -buffer. Eso es una lista empezando por <code>(#("%12b" 0 4 -…</code>. El <code>#(</code> empieza la lista. -</p> -<p>El ‘<samp>"%12b"</samp>’ muestra el nombre del actual búffer, usando la -función <code>buffer-name</code> con la que estamos familiarizados; el -‘12’ especifica el número máximo de caracteres que serán -mostrados. Cuando un nombre tiene pocos caracteres, el espacio en -blanco se añade para rellenar este número. (Los nombres del -búffer puede y con frecuencia serán más largos de 12 caracteres; -esta longitud funciona bien en la típica ventana de 80 -columnas de ancho.) -</p> -<p><code>:eval</code> dice evaluar la siguiente forma y usa el resultado como -una cadena para mostrarse. En este caso, la expresión muestra el -primer componente del sistema completo. El fin del primer componente -es un ‘<samp>.</samp>’ (‘periodo’), así se usa la función -<code>string-match</code> para contar el tamaño del primer componente. La -subcadena desde el caracter cero a este tamaño del primer -componente. La subcadena desde el caracter cero a este tamaño es el -nombre de la máquina. -</p> -<p>Esta es la expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(:eval (substring - (system-name) 0 (string-match "\\..+" (system-name)))) -</pre></div> - -<p>‘<samp>%[</samp>’ y ‘<samp>%]</samp>’ causa un par de corchetes que aparezcan por cada -edición nivel de edición recursiva editando el nivel. ‘<samp>%n</samp>’ -dice ‘Encoger’ cuando esto puede hacerse. ‘<samp>%P</samp>’ te cuenta el -porcentaje del búffer que está debajo de la ventana, o ‘arriba’, -‘abajo’, o ‘todo’. (Una minúscula ‘<samp>p</samp>’ cuenta el porcentaje bajo -el alto de la ventana.) ‘<samp>%-</samp>’ inserta suficientes guiones para -rellenar la línea. -</p> -<p>Recuerda, “No tiene que gustarte Emacs para que le gustes” — Emacs -puede tener diferentes colores, diferentes comandos, y diferentes -teclas que un Emacs por defecto. -</p> -<p>Por otro lado, si se quiere traer un plano ‘fuera de la caja’ Emacs, -sin personalización, escribe: -</p> -<div class="smallexample"> -<pre class="smallexample">emacs -q -</pre></div> - -<p>Esto inicializará un Emacs que <em>no</em> cargue tu ‘<tt>~/.emacs</tt>’ -fichero de inicialización. Uno plano, el que trae Emacs por -defecto. Nada más. -</p> -<hr> -<a name="Depurando"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Inicializaci_00f3n-de-Emacs" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Mode-Line" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#depurar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Depurando-1"></a> -<h1 class="chapter">17 Depurando</h1> -<a name="index-depurando"></a> - -<p>GNU Emacs tiene dos depuradores, <code>debug</code> y <code>edebug</code>. El -primero es construido dentro de las tripas de Emacs y está siempre -contigo; el segundo requiere que exista una función antes de que se -pueda usar. -</p> -<p>Ambos depuradores son descritos extensivamente en <a href="elisp.html#Depurando">Depurando Programas Lisp</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>. En este capítulo, se explicará un breve ejemplo -de esto. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#depurar">17.1 <code>depurar</code></a></td><td> </td><td align="left" valign="top"> Cómo usar el depurador construido. -</td></tr> -<tr><td align="left" valign="top"><a href="#debug_002don_002dentry">17.2 <code>debug-on-entry</code></a></td><td> </td><td align="left" valign="top"> Empezar depurando cuando se llama a una - función. -</td></tr> -<tr><td align="left" valign="top"><a href="#debug_002don_002dquit">17.3 <code>debug-on-quit</code> y <code>(debug)</code></a></td><td> </td><td align="left" valign="top"> Empezar depurando cuando se sale con <kbd>C-g</kbd>. -</td></tr> -<tr><td align="left" valign="top"><a href="#edebug">17.4 El depurador de nivel de fuentes <code>edebug</code></a></td><td> </td><td align="left" valign="top"> Cómo usar Edebug, un depurador a nivel de - fuentes. -</td></tr> -<tr><td align="left" valign="top"><a href="#Ejercicios-de-depuraci_00f3n">17.5 Ejercicios de depuración</a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="depurar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Depurando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#debug_002don_002dentry" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="depurar-1"></a> -<h2 class="section">17.1 <code>depurar</code></h2> -<a name="index-depurar"></a> - -<p>Supón que se ha escrito una definición de función que se -pretende devolver la suma de los números 1 a través de un número -dado. (Esta es la función <code>triangle</code> discutida -pronto. Véase la sección <a href="#Ejemplo-de-Decremento">Ejemplo con Contador de Decremento</a>, para una discusión.) -</p> -<p>Sin embargo, tu definición de función tiene un error. Se ha -malescrito ‘<samp>1=</samp>’ por ‘<samp>1-</samp>’. Aquí está la -definición rota: -</p> -<a name="index-triangle_002dbugged"></a> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-bugged (number) - "Devuelve suma de números 1 a través de NUMBER inclusive." - (let ((total 0)) - (while (> number 0) - (setq total (+ total number)) - (setq number (1= number))) ; <span class="roman">Error aquí.</span> - total)) -</pre></div> - -<p>Si se está leyendo esto en Info, se puede evaluar esta definición -en el modo normal. Se verá que <code>triangle-bugged</code> aparece en el -área echo. -</p> -<p>Ahora evalúa la función <code>triangle-bugged</code> con un argumento de -4: -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle-bugged 4) -</pre></div> - -<p>En un GNU Emacs reciente, se creará e introducirá un búffer -‘<tt>*Backtrace*</tt>’ que dice: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--Lisp error: (void-function 1=) - (1= number) - (setq number (1= number)) - (while (> number 0) (setq total (+ total number)) - (setq number (1= number))) - (let ((total 0)) (while (> number 0) (setq total ...) - (setq number ...)) total) - triangle-bugged(4) -</pre><pre class="smallexample"> eval((triangle-bugged 4)) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>(Se ha reformateado este ejemplo ligeramente; el depurador no contiene -muchas líneas. Así, se puede salir del -depurador escribiendo <kbd>q</kbd> en el buffer ‘<tt>*Backtrace*</tt>’.) -</p> -<p>En la práctica, debido a un error tan simple como este, la -línea de ‘error Lisp’ explica lo que se necesita saber -para corregir la definición. La función <code>1=</code> está -‘vacía’. -</p> - -<p>Sin embargo, si no se conoce con bastante certeza lo que está -pasando, se puede leer la traza completa. -</p> -<p>En este caso, se necesita ejecutar una versión reciente de GNU -Emacs, que automáticamente empieza el depurador que pone en el -búffer ‘<tt>*Backtrace*</tt>’; o además, se necesita para empezar el -depurador manualmente como se describe debajo. -</p> -<p>Lee el búffer ‘<tt>*Backtrace*</tt>’ de abajo a arriba; eso cuenta lo -que le hizo a Emacs tener un error. Emacs hace una llamada interactiva -a <kbd>C-x C-e</kbd> (<code>eval-last-sexp</code>), que lleva a la evaluación -de la expresión <code>triangle-bugged</code>. Cada línea de -debajo cuenta lo que el intérprete Lisp evaluó. -</p> -<p>La tercera línea desde lo alto del búffer es -</p> -<div class="smallexample"> -<pre class="smallexample">(setq number (1= number)) -</pre></div> - -<p>Emacs intentó evaluar esta expresión; para hacerlo -así, se intentó evaluar la expresión interna para -ser mostrada en la segunda línea desde arriba: -</p> -<div class="smallexample"> -<pre class="smallexample">(1= number) -</pre></div> - -<p>Aquí es donde el error ocurre; como se dice en la -línea de arriba: -</p> -<div class="smallexample"> -<pre class="smallexample">Debugger entered--Lisp error: (void-function 1=) -</pre></div> - -<p>Se puede corregir el error, reevalúa la definición de función, y -entonces se puede testear de nuevo. -</p> -<hr> -<a name="debug_002don_002dentry"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Depurando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#depurar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#debug_002don_002dquit" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="debug_002don_002dentry-1"></a> -<h2 class="section">17.2 <code>debug-on-entry</code></h2> -<a name="index-debug_002don_002dentry"></a> - -<p>Un GNU Emacs actual abre el depurador automáticamente cuando la -función tiene un error. -</p> - -<p>Incidentalmente, se puede empezar el depurador manualmente para todas -las versiones de Emacs; la ventaja es que el depurador se ejecuta -incluso si no se tiene un error en su código. Algunas veces, -¡su código estará libre de errores! -</p> -<p>Se puede introducir el depurador cuando se llama a la función -llamando <code>debug-on-entry</code>. -</p> -<p>Tipo: -</p> -<div class="smallexample"> -<pre class="smallexample">M-x debug-on-entry RET triangle-bugged RET -</pre></div> - -<p>Ahora, evalúa lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle-bugged 5) -</pre></div> - -<p>Todas las versiones de Emacs crearán un búffer ‘<tt>*Backtrace*</tt>’ -y cuenta tu que eso es el principio para evaluar la función -<code>triangle-bugged</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--entering a function: -* triangle-bugged(5) - eval((triangle-bugged 5)) -</pre><pre class="smallexample"> eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>En el búffer ‘<tt>*Backtrace*</tt>’, escribe <kbd>d</kbd>. Emacs evaluará -la primera expresión en <code>triangle-bugged</code>; el búffer se -parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--beginning evaluation of function call form: -* (let ((total 0)) (while (> number 0) (setq total ...) - (setq number ...)) total) -* triangle-bugged(5) - eval((triangle-bugged 5)) -</pre><pre class="smallexample"> eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>Ahora, escribe <kbd>d</kbd> de nuevo, ocho veces, lentamente. Cada vez que -se escribe <kbd>d</kbd> Emacs evaluará otra expresión en la -definición de función. -</p> -<p>Eventualmente, el búffer se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--beginning evaluation of function call form: -* (setq number (1= number)) -* (while (> number 0) (setq total (+ total number)) - (setq number (1= number))) -</pre><pre class="smallexample">* (let ((total 0)) (while (> number 0) (setq total ...) - (setq number ...)) total) -* triangle-bugged(5) - eval((triangle-bugged 5)) -</pre><pre class="smallexample"> eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>Finalmente, después se escribe <kbd>d</kbd> dos veces más, Emacs logrará -el error y las dos líneas superiores del buffer -‘<tt>*Backtrace*</tt>’ se ve así: -</p> -<div class="smallexample"> -<pre class="smallexample">---------- Buffer: *Backtrace* ---------- -Debugger entered--Lisp error: (void-function 1=) -* (1= number) -… ----------- Buffer: *Backtrace* ---------- -</pre></div> - -<p>Escribiendo <kbd>d</kbd>, sería capaz de pasear a través de -la función. -</p> -<p>Se puede salir de un buffer ‘<tt>*Backtrace*</tt>’ escribiendo <kbd>q</kbd>; -esto se sale de la traza, pero no cancela <code>debug-on-entry</code>. -</p> -<a name="index-cancel_002ddebug_002don_002dentry"></a> -<p>Para cancelar el efecto de <code>debug-on-entry</code>, llama a -<code>cancel-debug-on-entry</code> y el nombre de la función, como esto: -</p> -<div class="smallexample"> -<pre class="smallexample">M-x cancel-debug-on-entry RET triangle-bugged RET -</pre></div> - -<p>(Si está leyendo esto en Info, cancela <code>debug-on-entry</code> ahora.) -</p> -<hr> -<a name="debug_002don_002dquit"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Depurando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#debug_002don_002dentry" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#edebug" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="debug_002don_002dquit-y-_0028debug_0029"></a> -<h2 class="section">17.3 <code>debug-on-quit</code> y <code>(debug)</code></h2> - -<p>Adición a la configuración <code>debug-on-error</code> o llamando -<code>debug-on-entry</code>, hay otros dos caminos para empezar <code>debug</code>. -</p> -<a name="index-debug_002don_002dquit"></a> -<p>Se puede empezar <code>debug</code> siempre y cuando se escribe <kbd>C-g</kbd> -(<code>keyboard-quit</code>) se configura la variable <code>debug-on-quit</code> -para <code>t</code>. Esto es útil para depurar bucles infinitos. -</p> -<a name="index-_0028debug_0029-en-codigo"></a> -<p>O, se puede insertar un línea que dice <code>(debug)</code> -dentro de tu código donde se quiere que el depurador empiece, -así: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-bugged (number) - "Devuelve suma de números 1 a través de NUMERO inclusive." - (let ((total 0)) - (while (> number 0) - (setq total (+ total number)) - (debug) ; <span class="roman">Empieza el depurador.</span> - (setq number (1= number))) ; <span class="roman">Error aquí.</span> - total)) -</pre></div> - -<p>La función <code>debug</code> se describe en detalle en <a href="elisp.html#Depurador">El Depurador Lisp</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>. -</p> -<hr> -<a name="edebug"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Depurando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#debug_002don_002dquit" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-de-depuraci_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-depurador-de-nivel-de-fuentes-edebug"></a> -<h2 class="section">17.4 El depurador de nivel de fuentes <code>edebug</code></h2> -<a name="index-Depurador-de-nivel-de-codigo"></a> -<a name="index-edebug"></a> - -<p>Edebug es un depurador a nivel de fuentes Edebug que normalmente -muestra las fuentes del código que se está depurando, con una -flecha a la izquierda que muestra que línea se está -actualmente ejecutando. -</p> -<p>Se puede pasear a través de la ejecución de una función, -línea a línea, o ejecutarse rápidamente -hasta lograr un <em>punto de ruptura</em> donde la ejecución pare. -</p> -<p>Edebug se describe en <a href="elisp.html#edebug">Edebug</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>. -</p> -<p>Aquí hay una función con errores para -<code>triangle-recursively</code>. Véase la sección <a href="#Funci_00f3n-recursiva-tri_00e1ngulo">Recursión en lugar de un contador</a>, para una revisión de eso. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun triangle-recursively-bugged (number) - "Devuelve la suma of números 1 a través de NUMBER inclusive. -Usa recursión." - (if (= number 1) - 1 - (+ number - (triangle-recursively-bugged - (1= number))))) ; <span class="roman">Error aquí.</span> -</pre></div> - -<p>Normalmente, se instalaría esta definición -posicionando su cursor después de la función cerrando paréntesis -y escribiendo <kbd>C-x C-e</kbd> (<code>eval-last-sexp</code>) o lo demás -posicionando tu cursor con la definición y escribiendo <kbd>C-M-x</kbd> -(<code>eval-defun</code>). (Por defecto, el comando <code>eval-defun</code> -funciona solo en modo Emacs Lisp o en el modo de interacción de -Lisp.) -</p> -<p>Sin embargo, para preparar esta definición de función para Edebug, -se debe primero <em>instrumentar</em> el código usando un comando -diferente. Se puede hacer esto posicionando el cursor dentro o -después de la definición y escribiendo -</p> -<div class="smallexample"> -<pre class="smallexample">M-x edebug-defun RET -</pre></div> - -<p>Esto causará que Emacs cargue Edebug automáticamente si eso no -está ya cargado y, apropiadamente prepara la función. -</p> -<p>Después de preparar la función, emplaza tu cursor después -de la siguiente expresión y escribe <kbd>C-x C-e</kbd> (<code>eval-last-sexp</code>): -</p> -<div class="smallexample"> -<pre class="smallexample">(triangle-recursively-bugged 3) -</pre></div> - -<p>Se vuelve a las fuentes de <code>triangle-recursively-bugged</code> y el -cursor se posiciona al principio del <code>if</code> de la -línea de la función. También, se verá una flecha -en la mano izquierda al lado de esta línea donde la -función se está ejecutando. (En los siguientes ejemplos, se -muestra la flecha con ‘<samp>=></samp>’; en un sistema de ventanas, se puede -ver la flecha como un triángulo sólido en el ‘borde’ de la -ventana.) -</p> -<div class="smallexample"> -<pre class="smallexample">=>∗(if (= number 1) -</pre></div> - -<p>En el ejemplo, la localización del punto es mostrado como -‘<samp>∗</samp>’ (en un libro impreso, eso es mostrado con una estrella -apuntada). -</p> -<p>Si ahora se presiona <SPC>, el punto se moverá a la siguiente -expresión para ejecutarse; la línea se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">=>(if ∗(= number 1) -</pre></div> - -<p>Como se continua presionando <SPC>, el puntero se moverá desde -la expresión a la expresión. Al mismo tiempo, siempre y cuando una -expresión devuelva un valor, este valor será mostrado en el área -echo. Por ejemplo, después de mover el punto pasado <code>number</code>, -se verá lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">Resultado: 3 (#o3, #x3, ?\C-c) -</pre></div> - -<p>Esto significa el valor de <code>number</code> es 3, que son tres octales, -tres hexadecimales, y <small>ASCII</small> ‘control-c’ (la tercera letra del -alfabeto, en caso de que se necesite conocer esta información). -</p> -<p>Uno puede continuar moviéndose a través del código hasta que -logre la línea con el error. Antes de la evaluación, -esta línea se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">=> ∗(1= number))))) ; <span class="roman">Error aquí.</span> -</pre></div> - -<p>Cuando se presiona <SPC> una vez de nuevo, se producirá un -mensaje de error que dice: -</p> -<div class="smallexample"> -<pre class="smallexample">La definición de la función está vacío: 1= -</pre></div> - -<p>Este es el error. -</p> -<p>Presiona <kbd>q</kbd> para salir de Edebug. -</p> -<p>Para eliminar la instrumentación desde una definición de -función, simplemente se reevalúa con un comando que no lo -instrumente. Por ejemplo, se podría posicionar su cursor -después de la definición cerrando paréntesis y escribiendo -<kbd>C-x C-e</kbd>. -</p> -<p>Edebug hace un gran trato antes de entrar en una función. Se puede -dirigir así mismo, parando solo en un error o en puntos -específicos, se puede causar para mostrar los valores -cambiantes de varias expresiones; se puede encontrar cuantas veces una -función se llama, y más. -</p> -<p>Edebug se describe en <a href="elisp.html#edebug">Edebug</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>. -</p> -<hr> -<a name="Ejercicios-de-depuraci_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Depurando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#edebug" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Depurando" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Ejercicios-de-depuracion"></a> -<h2 class="section">17.5 Ejercicios de depuración</h2> - -<ul> -<li> -Instale la función <code>count-words-example</code> y provoque que se -introduzca el depurador construido cuando se llame. Ejecute el comando -en una región conteniendo dos palabras. Se necesitará presionar -<kbd>d</kbd> un número remarcable de veces. En el sistema, es un ‘hook’ -llamado después que el comando se finaliza. (Para información sobre -hooks, mira <a href="elisp.html#Resumen-de-Comandos">Resumen del Comando Bucle</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>.) - -</li><li> -Copie <code>count-words-example</code> dentro del búffer ‘<tt>*scratch*</tt>’, -instrumente la función para Edebug, y navegue a través de su -ejecución. La función no necesita tener un error, aunque se puede -introducir uno si se desea. Si a la función le falta un error, el -paseo se completa sin problemas. - -</li><li> -Mientras se ejecuta Edebug, escriba <kbd>?</kbd> para ver una lista de todos -los comandos Edebug. (El <code>global-edebug-prefix</code> normalmente es -<kbd>C-x X</kbd>, por ej <kbd><CTRL>-x</kbd> seguido por una tecla -mayúscula <kbd>X</kbd>; use este prefijo para comandos hechos fuera del -búffer de depuración Edebug.) - -</li><li> -En el búffer de depuración Edebug, usa el comando <kbd>p</kbd> -(<code>edebug-bounce-point</code>) para ver si <code>count-words-example</code> -está funcionando. - -</li><li> -Mueve el punto a algún sitio debajo de la función y entonces -escribe el comando <kbd>h</kbd> (<code>edebug-goto-here</code>) para saltar a -esta localización. - -</li><li> -Usa el comando <kbd>t</kbd> (<code>edebug-trace-mode</code>) para causar que -Edebug pasee a través de la función en sí; usa una -letra mayúscula <kbd>T</kbd> para <code>edebug-Trace-fast-mode</code>. - -</li><li> -Asigna un punto de ruptura, entonces ejecuta Edebug en modo Traza -hasta que se logre el punto de parada. -</li></ul> - -<hr> -<a name="Conclusi_00f3n"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Depurando" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejercicios-de-depuraci_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#the_002dthe" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#the_002dthe" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Conclusion"></a> -<h1 class="chapter">18 Conclusión</h1> - -<p>Ahora se ha llegado al fin de esta Introducción. Se ha aprendido lo -suficiente acerca de programación en Emacs Lisp para asignar -valores, para escribir ficheros ‘<tt>.emacs</tt>’ para tí -mismo y tus amigos, y escribir personalizaciones simples y extensiones -a Emacs. -</p> -<p>Este es un lugar para parar. O, si se desea, se puede ir adelante, y -aprender más por uno mismo. -</p> -<p>Se han aprendido algunas bases de programación. Pero solo -algunas. Todavía hay muchas cosas que son fáciles de -usar que no se han tocado. -</p> -<p>Otra idea para seguir es leer las fuentes de Emacs o -<cite>El Manual de Referencia de GNU Emacs</cite>. -</p> -<p>Las fuentes de Emacs Lisp son una aventura. Cuando se leen las fuentes -vienen a través de una función o expresión que nos es familiar, -se necesita imaginar o encontrar qué se hace. -</p> -<p>Ir al Manual de Referencia. Eso está a través del completo, limpio -y fácil de leer descripción de Emacs Lisp. Está escrito no solo -para expertos, pero sí para gente que conoce lo que -usted conoce. (El <cite>Manual de Referencia</cite> viene con la -distribución de GNU Emacs. Como esta introducción, viene como un -fichero fuente Texinfo, así se puede leer on-line como -un libro impreso.) -</p> -<p>Ir a otra ayuda on-line que sea parte de GNU Emacs: la documentación -on-line para todas las funciones y variables, y <code>find-tag</code>, el -programa que va a las fuentes. -</p> -<p>Aquí hay un ejemplo de cómo explorar las -fuentes. Porque su nombre, ‘<tt>simple.el</tt>’ es el fichero que se vió -primero, hace tiempo. Como eso ocurre alguna de las funciones en -‘<tt>simple.el</tt>’ son complicadas, o al menos parece complicado a -primera vista. La función <code>open-line</code>, por ejemplo, parece -complicada. -</p> -<p>Se puede querer pasear a través de esta función lentamente, como -nosotros hicimos la función -<code>forward-sentence</code>. (Véase la sección <a href="#forward_002dsentence">La función <code>forward-sentence</code></a>.) O se puede querer salir de esta función -y mirar en otra, tal como <code>split-line</code>. No se necesita leer todas -las funciones. De acuerdo a <code>count-words-in-defun</code>, la función -<code>split-line</code> contiene 102 palabras y símbolos. -</p> -<p>Incluso aunque sean pocas, <code>split-line</code> contiene expresiones que -no se han estudiado: <code>skip-chars-forward</code>, <code>indent-to</code>, -<code>current-column</code> y <code>insert-and-inherit</code>. -</p> -<p>Considera la función <code>skip-chars-forward</code>. (Eso es parte de la -definición de función para <code>back-to-indentation</code>, que -muestra la <a href="#Revisar">Revisar</a>.) -</p> -<p>En GNU Emacs, se puede encontrar más acerca de -<code>skip-chars-forward</code> escribiendo <kbd>C-h f</kbd> -(<code>describe-function</code>) y el nombre de la función. Esto te da la -documentación de función. -</p> -<p>Se puede ser capaz de adivinar que se hace por una función bien -llamada tal como <code>indent-to</code>; o se puede buscar, -también. Incidentalmente, la función <code>describe-function</code> en -sí está en ‘<tt>help.el</tt>’; esta es una de estas largas, -pero descifrables funciones. ¡Se puede buscar -<code>describe-function</code> usando el comando <kbd>C-h f</kbd>! -</p> -<p>En esta instancia, desde el código es Lisp, el búffer -‘<tt>*Help*</tt>’ contiene el nombre de la librería -conteniendo las fuentes de la función. Se puede poner el punto a -través del nombre de la librería y presiona la tecla -RET, que está en esta situación está asociado a -<code>help-follow</code>, y se toma directamente de las fuentes, en el mismo -camino que <kbd>M-.</kbd> (<code>find-tag</code>). -</p> -<p>La definición para <code>describe-function</code> ilustra como -personalizar las expresiones <code>interactive</code> sin usar los códigos -de caracter estándar y eso muestra como crear un búffer temporal. -</p> -<p>(La función <code>indent-to</code> es escrita en C en vez de Emacs Lisp; -eso es una función ‘construida’. <code>help-follow</code> toma su fuente -como <code>find-tag</code>, cuando se configura apropiadamente.) -</p> -<p>Se puede mirar en las fuentes de la función usando <code>find-tag</code>, -que está asociado a <kbd>M-.</kbd>. Finalmente, se puede encontrar que el -Manual de Referencia tiene que decir visitando el manual en Info, y -escribiendo <kbd>i</kbd> (<code>Info-index</code>) y el nombre de la función, o -buscando la función en el índice a una copia impresa -del manual. -</p> -<p>Similarmente, se puede encontrar que significa por -<code>insert-and-inherit</code>. -</p> -<p>Otros ficheros fuente interesantes incluyen ‘<tt>paragraphs.el</tt>’, -‘<tt>loaddefs.el</tt>’ y ‘<tt>loadup.el</tt>’. El fichero ‘<tt>paragraphs.el</tt>’ -incluye ordenar, funciones fácilmente comprendidas tan bien como las -largas. El fichero ‘<tt>loaddefs.el</tt>’ contiene muchos autoloads -estándar y muchos mapas de teclado. Nunca se ha buscado en todo; -solo en las partes. ‘<tt>loadup.el</tt>’ es el fichero que carga las -partes estándar de Emacs; eso cuenta un gran trato acerca de cómo -Emacs está construido. (See <a href="elisp.html#Construyendo-Emacs">Construyendo Emacs</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>, para más -acerca de construcción.) -</p> -<p>Como dije, se han aprendido algunas cosas; sin embargo, y de manera -muy importante, se han tocado fuertes aspectos de la programación; -no se ha dicho nada acerca de como ordenar la información, excepto -para usar la función predefinida <code>sort</code>; no se ha dicho nada -acerca de cómo almacenar la información, excepto para usar -variables y listas; no se ha dicho nada acerca de como escribir -programas que escriben programas. Esto son asuntos para otro tipo -diferente de libro, un diferente tipo de aprendizaje. -</p> -<p>Lo que se ha hecho es aprender lo suficiente para hacer mucho trabajo -práctico con GNU Emacs. Lo que se ha hecho es comenzar. Este es el -fin del principio de una gran amistad. -</p> - -<hr> -<a name="the_002dthe"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Conclusi_00f3n" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-the_002dthe"></a> -<h1 class="appendix">Appendix A La función <code>the-the</code></h1> -<a name="index-the_002dthe"></a> -<a name="index-Funcion-de-palabras-duplicadas"></a> -<a name="index-Palabras_002c-duplicadas"></a> - -<p>Algunas veces cuando se se escribe texto, se duplican palabras — como -con “se se” cerca del principio de esta frase. Se encuentra que lo -más frecuente, es duplicar “el”; aquí, se llama a la -función para detectar las palabras duplicadas, <code>the-the</code>. -</p> -<p>Como primer paso, se podrían usar las siguientes -expresiones regulares para buscar duplicados: -</p> -<div class="smallexample"> -<pre class="smallexample">\\(\\w+[ \t\n]+\\)\\1 -</pre></div> - -<p>Este regexp asocia uno o más caracteres que constituyen palabras -seguidas por uno o más espacios, tabuladores, o nuevas -líneas. Sin embargo, eso no detecta palabras duplicadas -en diferentes líneas, desde la finalización de la -primera palabra, el fin de la línea, es diferente desde -el fin de la segunda palabra, un espacio. (Para más información -acerca de expresiones regulares, mira el <a href="#Buscar-regexp">Búsquedas de Expresiones Regulares</a>, tan bien como la <a href="emacs.html#Regexps">Sintaxis de Expresiones Regulares</a> in <cite>El Manual de GNU Emacs</cite>, y la -<a href="elisp.html#Expresiones-Regulares">Expresiones Regulares</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>.) -</p> -<p>Se podrían intentar buscar caracteres duplicados pero no -si el patrón detecta dobles tales como las dos ocurrencias de ‘th’ -en ‘with the’. -</p> -<p>Otro posible regexp busca caracteres constituyentes de palabras -seguidos por caracteres de no palabras constituyentes, -reduplicadas. Aquí, ‘<samp>\\w+</samp>’ asocia a una o más -caracteres de palabras constituyente y ‘<samp>\\W*</samp>’ asocia cero o -más caracteres que no constituyen palabras. -</p> -<div class="smallexample"> -<pre class="smallexample">\\(\\(\\w+\\)\\W*\\)\\1 -</pre></div> - -<p>De nuevo, no útil. -</p> -<p>Aquí está el patrón que uso. No es perfecto, pero -suficientemente bueno. ‘<samp>\\b</samp>’ asocia la cadena -vacía provista al principio o fin de una palabra; -‘<samp>[^@ \n\t]+</samp>’ asocia una o más ocurrencias de qué -caracteres que <em>no</em> son un @-signo, espacio, nueva -línea, o tabulador. -</p> -<div class="smallexample"> -<pre class="smallexample">\\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b -</pre></div> - -<p>Uno puede escribir expresiones más complicadas, pero esta -expresión es suficientemente buena así. -</p> -<p>Aquí está la función <code>the-the</code>, como se incluye -en mi fichero ‘<tt>.emacs</tt>’, a lo largo de un atajo global manejable: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun the-the () - "Busca hacia adelante para una palabra duplicada." - (interactive) - (message "Buscando palabras duplicadas ...") - (push-mark) -</pre><pre class="smallexample"> ;; Este regexp no es perfecto - ;; pero es limpiamente bueno a pesar de todo: - (if (re-search-forward - "\\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b" nil 'move) - (message "Palabra encontrada duplicada.") - (message "Fin de búffer"))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; Asocia `the-the' a C-c \ -(global-set-key "\C-c\\" 'the-the) -</pre></div> - -<br> -<p>Aquí está el test del texto: -</p> -<div class="smallexample"> -<pre class="smallexample">uno dos tres cuatro cinco -cinco seis siete -</pre></div> - -<p>Se pueden sustituir las otras expresiones regulares mostradas debajo en -la definición de función y se prueba cada una de ellas en esta lista. -</p> -<hr> -<a name="Kill-Ring"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#the_002dthe" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#the_002dthe" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Qu_00e9-hace-el-anillo-de-la-muerte" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Manejando-el-anillo-de-la-muerte"></a> -<h1 class="appendix">Appendix B Manejando el anillo de la muerte</h1> -<a name="index-Manejando-el-anillo-de-la-muerte"></a> -<a name="index-Manejando-el-anillo-de-la-muerte-1"></a> -<a name="index-Anillo_002c-creando-un-lista-como-un"></a> - -<p>El anillo de la muerte es una lista que es transformada dentro de un -anillo que trabaja con la función <code>current-kill</code>. Los comandos -<code>yank</code> y <code>yank-pop</code> usan la función <code>current-kill</code>. -</p> -<p>Este apéndice describe la función <code>current-kill</code> y los -comandos <code>yank</code> y <code>yank-pop</code>, pero primero, considere los -trabajo del kill ring. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Qu_00e9-hace-el-anillo-de-la-muerte">Qué hace el anillo de la muerte</a></td><td> </td><td align="left" valign="top"></td></tr> -<tr><td align="left" valign="top"><a href="#current_002dkill">B.1 La función <code>current-kill</code></a></td><td> </td><td align="left" valign="top"> current-kill -</td></tr> -<tr><td align="left" valign="top"><a href="#pegar">B.2 <code>pegar</code></a></td><td> </td><td align="left" valign="top"> Pegar una copia de un elemento ya cortado. -</td></tr> -<tr><td align="left" valign="top"><a href="#yank_002dpop">B.3 <code>yank-pop</code></a></td><td> </td><td align="left" valign="top"> Insertar elemento apuntado. -</td></tr> -<tr><td align="left" valign="top"><a href="#fichero-anillo">B.4 El fichero ‘<tt>ring.el</tt>’</a></td><td> </td><td align="left" valign="top"> fichero anillo -</td></tr> -</table> - -<hr> -<a name="Qu_00e9-hace-el-anillo-de-la-muerte"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#current_002dkill" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Que-hace-el-anillo-de-la-muerte"></a> -<h2 class="unnumberedsec">Qué hace el anillo de la muerte</h2> - -<p>El anillo de la muerte <em>kill ring</em> tiene el tamaño máximo de -sesenta elementos; hacer una explicación con este número máximo -quedaría demasiado larga. En vez de eso, pensemos qué -ocurre si se asígna a cuatro. Por favor, evalúe lo -siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq old-kill-ring-max kill-ring-max) -(setq kill-ring-max 4) -</pre></div> - -<p>Entonces, por favor, copie cada línea del siguiente -ejemplo indentado dentro del anillo de la muerte <em>kill ring</em>. Se -puede cortar cada línea con <kbd>C-k</kbd> o marcarla y -copiarla con <kbd>M-w</kbd>. -</p> -<p>(En un búffer de solo lectura, tal como el búffer ‘<tt>*info*</tt>’, el -comando kill, <kbd>C-k</kbd> (<code>kill-line</code>), no eliminará el texto, -solamente lo mueve al anillo de la muerte <em>kill ring</em>. Sin -embargo, el ordenador puede avisar con un beep. Alternativamente, para -silenciar, se puede copiar la región de cada línea con -el comando <kbd>M-w</kbd> (<code>kill-ring-save</code>). Se debe marcar cada -línea de este comando para tener éxito, pero no -importa si al final se posiciona en el punto o la marca). -</p> -<p>Por favor, invoque las llamadas en orden, de modo que los cinco -elementos rellenen el anillo de la muerte <em>kill ring</em>. -</p> -<div class="smallexample"> -<pre class="smallexample">primero algo de texto -segunda pieza de texto -tercera línea -cuarta línea de texto -quinto bit de texto -</pre></div> - -<p>Entonces encuentra el valor de <code>kill-ring</code> evaluando -</p> -<div class="smallexample"> -<pre class="smallexample">kill-ring -</pre></div> - -<p>Eso es: -</p> -<div class="smallexample"> -<pre class="smallexample">("quinto bit de texto" "cuarta línea de texto" -"tercera línea" "segunda pieza de texto") -</pre></div> - -<p>El primer elemento, ‘<samp>primero algo de texto</samp>’, fué borrado. -</p> -<p>Para devolver el viejo valor para el tamaño del kill ring, evalúe: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq kill-ring-max old-kill-ring-max) -</pre></div> - -<hr> -<a name="current_002dkill"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Qu_00e9-hace-el-anillo-de-la-muerte" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#C_00f3digo-para-current_002dkill" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-current_002dkill"></a> -<h2 class="appendixsec">B.1 La función <code>current-kill</code></h2> -<a name="index-current_002dkill"></a> - -<p>La función <code>current-kill</code> cambia el elemento en el anillo de la -muerte <em>kill ring</em> para el que el <code>kill-ring-yank-pointer</code> -apunta. (También, la función <code>kill-new</code> asigna -<code>kill-ring-yank-pointer</code> para apuntar al último elemento del -anillo de la muerte <em>kill ring</em>. La función <code>kill-new</code> se -usa directamente o indirectamente por <code>kill-append</code>, -<code>copy-region-as-kill</code>, <code>kill-ring-save</code>, <code>kill-line</code>, y -<code>kill-region</code>.) -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#C_00f3digo-para-current_002dkill">El código <code>current-kill</code></a></td><td> </td><td align="left" valign="top"> Código para current-kill -</td></tr> -<tr><td align="left" valign="top"><a href="#Comprendiendo-current_002dkill"><code>current-kill</code> en outline</a></td><td> </td><td align="left" valign="top"> Comprendiendo current-kill -</td></tr> -</table> - -<hr> -<a name="C_00f3digo-para-current_002dkill"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#current_002dkill" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#current_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Comprendiendo-current_002dkill" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-codigo-current_002dkill"></a> -<h3 class="unnumberedsubsec">El código <code>current-kill</code></h3> - - -<p>La función <code>current-kill</code> es usada por <code>yank</code> y por -<code>yank-pop</code>. Aquí está el código para -<code>current-kill</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun current-kill (n &optional do-not-move) -"Rota el punto de pegue por N lugares, y entonces devuelve lo cortado. -Si N es cero, `interprogram-paste-function' se asigna, y si se llama -devuelve una cadena, entonces esta cadena se añade al frente del -anillo de la muerte <em>kill ring</em> y devuelve el último corte. -</pre><pre class="smallexample">Si el argumento opcional DO-NOT-MOVE es no nulo, entonces no muevas el -punto de pegue; solo devuelve el Nth corte hacia adelante. - (let ((interprogram-paste (and (= n 0) - interprogram-paste-function - (funcall interprogram-paste-function))))) -</pre><pre class="smallexample"> (if interprogram-paste - (progn - ;; Deshabilita el programa de la función de corte cuando se - ;; añade el nuevo texto al anillo de la muerte <em>kill ring</em>, - ;; así Emacs no intenta poseer la selección - ;; con idéntico texto. - (let ((interprogram-cut-function nil)) - (kill-new interprogram-paste)) - interprogram-paste) -</pre><pre class="smallexample"> (or kill-ring (error "Kill ring is empty")) - (let ((ARGth-kill-element - (nthcdr (mod (- n (length kill-ring-yank-pointer)) - (length kill-ring)) - kill-ring))) - (or do-not-move - (setq kill-ring-yank-pointer ARGth-kill-element)) - (car ARGth-kill-element))))) -</pre></div> - -<p>Recuerde también que la función <code>kill-new</code> asigna -<code>kill-ring-yank-pointer</code> al último elemento del anillo de la -muerte <em>kill ring</em>, que significa que todas las funciones lo -llaman y asigna el valor de manera indirecta: <code>kill-append</code>, -<code>copy-region-as-kill</code>, <code>kill-ring-save</code>, <code>kill-line</code> y -<code>kill-region</code>. -</p> -<p>Aquí está la línea en <code>kill-new</code>, -que se explica en la <a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a>. -</p> -<div class="smallexample"> -<pre class="smallexample">(setq kill-ring-yank-pointer kill-ring) -</pre></div> - -<hr> -<a name="Comprendiendo-current_002dkill"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#C_00f3digo-para-current_002dkill" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#current_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Cuerpo-de-current_002dkill" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="current_002dkill-en-outline"></a> -<h3 class="unnumberedsubsec"><code>current-kill</code> en outline</h3> - -<p>La función <code>current-kill</code> parece compleja, pero usual, eso -puede ser comprendido tomándolo aparte pieza por pieza. Primero -míralo en la forma esquelética: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun current-kill (n &optional do-not-move) - "Rota el punto a pegar por N lugares, y entonces devuelve el texto cortado." - (let <var>varlist</var> - <var>body</var>…) -</pre></div> - -<p>Esta función tiene dos argumentos, uno es opcional. Hay una cadena -de documentación. <em>No</em> es una función interactiva. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Cuerpo-de-current_002dkill">El cuerpo de <code>current-kill</code></a></td><td> </td><td align="left" valign="top"> Cuerpo de current-kill -</td></tr> -<tr><td align="left" valign="top"><a href="#Disgresi_00f3n-concerniente-de-error">Disgresión acerca de la palabra ‘error’</a></td><td> </td><td align="left" valign="top"> Cómo confundir humanos, pero no - ordenadores. -</td></tr> -<tr><td align="left" valign="top"><a href="#Determinando-el-elemento">Determinando el elemento</a></td><td> </td><td align="left" valign="top"></td></tr> -</table> - -<hr> -<a name="Cuerpo-de-current_002dkill"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Comprendiendo-current_002dkill" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Comprendiendo-current_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Disgresi_00f3n-concerniente-de-error" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-cuerpo-de-current_002dkill"></a> -<h4 class="unnumberedsubsubsec">El cuerpo de <code>current-kill</code></h4> - -<p>El cuerpo de la definición de función es una expresión -<code>let</code>, que por sí misma tiene tanto un cuerpo como -una <var>varlist</var>. -</p> -<p>La expresión <code>let</code> declara una variable que será solo usable -con las asociaciones de esta función. Esta variable se llama -<code>interprogram-paste</code> y se copia a otro programa. No se copia con -esta instancia de GNU Emacs. La mayoría de los sistemas -de ventanas proveen una facilidad para pegar el -interprograma. Tristemente, esta facilidad normalmente provee solo el -último elemento. La mayoría de los sistemas de -ventanas no han adoptado un anillo de muchas posibilidades, incluso -aunque Emacs haya provisto esto durante décadas. -</p> -<p>La expresión <code>if</code> tiene dos partes, una si existe -<code>interprogram-paste</code> y otra si no. -</p> -<p>Permítenos considerar el ‘si no’ o la parte else de la -función <code>current-kill</code>. (La parte then usa la función -<code>kill-new</code>, que ya hemos descrito. Véase la sección <a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code>.</a>) -</p> -<div class="smallexample"> -<pre class="smallexample">(or kill-ring (error "El Kill ring está vacío")) -(let ((ARGth-kill-element - (nthcdr (mod (- n (length kill-ring-yank-pointer)) - (length kill-ring)) - kill-ring))) - (or do-not-move - (setq kill-ring-yank-pointer ARGth-kill-element)) - (car ARGth-kill-element)) -</pre></div> - -<p>El código primero chequea si el kill ring <em>anillo de la muerte</em> -tiene contenido; de otro modo señala un error. -</p> -<p>Note que la expresión <code>or</code> es muy similar para testear el -tamaño con un <code>if</code>: -</p> -<a name="index-zerop"></a> -<a name="index-error"></a> -<div class="smallexample"> -<pre class="smallexample">(if (zerop (length kill-ring)) ; <span class="roman">parte-si</span> - (error "Anillo de la muerte vacío")) ; <span class="roman">parte-entonces</span> - ;; No hay parte-resto -</pre></div> - -<p>Si no hay nada en el kill ring <em>anillo de la muerte</em>, su tamaño -debe ser cero y un mensaje de error se envía al usuario: -‘<samp>El kill ring está vacío</samp>’. La función -<code>current-kill</code> usa una expresión <code>or</code> que es simple. Pero -una expresión <code>if</code> recuerda lo que lleva. -</p> -<p>Esta expresión <code>if</code> usa la función <code>zerop</code> que devuelve -cierto si el valor que se chequea es cero. Cuando <code>zerop</code> chequea -cierto, la parte then del <code>if</code> se evalúa. La parte then es una -lista empezando con la función <code>error</code>, que es una función -que es similar a la función <code>message</code> (véase la sección <a href="#message">La Función <code>message</code></a>) que imprime un mensaje de una -línea en el área echo. Sin embargo, además de -imprimir un mensaje, <code>error</code> también evalúa la función que -está embebida. Esto significa que el resto de la función no será -evaluada si el tamaño del anillo de la muerte <em>kill ring</em> es -cero. -</p> -<p>Entonces la función <code>current-kill</code> selecciona el elemento a -devolver. La selección depende del número de lugares que -<code>current-kill</code> rota y donde <code>kill-ring-yank-pointer</code> apunta. -</p> -<p>Lo siguiente, si el argumento <code>do-not-move</code> opcional es verdadero -o el actual valor de <code>kill-ring-yank-pointer</code> se establece al -punto de la lista. Finalmente, otra expresión devuelve el primer -elemento de la lista incluso si el argumento <code>do-not-move</code> es -verdadero. -</p> -<hr> -<a name="Disgresi_00f3n-concerniente-de-error"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Cuerpo-de-current_002dkill" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Comprendiendo-current_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Determinando-el-elemento" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Disgresion-acerca-de-la-palabra-_0060error_0027"></a> -<h4 class="unnumberedsubsubsec">Disgresión acerca de la palabra ‘error’</h4> - -<p>En mi opinión, es ligeramente erróneo, al menos para humanos, usar -el término ‘error’ como el nombre de la función <code>error</code>. Un -término mejor sería ‘cancelar’. Estrictamente -hablando, de acuerdo, no se puede apuntar, mucho menos rotar un -puntero a una lista que no tiene tamaño, así desde el -punto de vista del ordenador, la palabra ‘error’ es correcta. Pero un -humano espera intentar algo, si solo si se encuentra el anillo de la -muerte <em>kill ring</em> esté lleno o vacío. Esto es un -acto de exploración. -</p> -<p>Desde el punto de vista humano, el acto de exploración y -descubrimiento no es necesariamente un error, y por esta razón no -sería etiquetado como tal, incluso las vocales de un -ordenador. Como tal, el código en Emacs implica que un humano que -está actuando virtuosamente, explorando su entorno, está teniendo -un error. Esto está mal. Incluso aunque el ordenador tome los mismos -pasos como cuando hay ‘error’, un término tal como ‘cancelar’ -tendría una clara connotación. -</p> -<hr> -<a name="Determinando-el-elemento"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Disgresi_00f3n-concerniente-de-error" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Comprendiendo-current_002dkill" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#pegar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Determinando-el-elemento-1"></a> -<h4 class="unnumberedsubsubsec">Determinando el elemento</h4> - -<p>Entre otras acciones, la else-part de la expresión <code>if</code> asigna -el valor de <code>kill-ring-yank-pointer</code> a <code>ARGth-kill-element</code> -cuando el kill ring <em>anillo de la muerte</em> tiene alguna cosa -dentro y el valor de <code>do-not-move</code> es <code>nil</code>. -</p> -<p>El código se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(nthcdr (mod (- n (length kill-ring-yank-pointer)) - (length kill-ring)) - kill-ring))) -</pre></div> - -<p>Esto necesita algún examen. A menos que no se suponga mover el -puntero, la función <code>current-kill</code> cambia donde -<code>kill-ring-yank-pointer</code> apunta. Esto es lo que la expresión -<code>(setq <span class="nolinebreak">kill-ring-yank-pointer</span> <span class="nolinebreak">ARGth-kill-element)</span></code> -hace. También, claramente, <code>ARGth-kill-element</code> está siendo -asignado para ser igual a algún <small>CDR</small> del anillo de la muerte -<em>kill ring</em>, usando la función <code>nthcdr</code> que está -descrita en una sección temprana. (Véase la sección <a href="#copy_002dregion_002das_002dkill"><code>copy-region-as-kill</code></a>.) -¿Cómo se hace? -</p> -<p>Como se ha visto antes (véase la sección <a href="#nthcdr"><code>nthcdr</code></a>), la función <code>nthcdr</code> -funciona repetidamente tomando el <small>CDR</small> de una lista — eso toma -el <small>CDR</small>, del <small>CDR</small>, del <small>CDR</small>, … -</p> -<p>Las siguientes dos expresiones producen el mismo resultado: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq kill-ring-yank-pointer (cdr kill-ring)) - -(setq kill-ring-yank-pointer (nthcdr 1 kill-ring)) -</pre></div> - -<p>Sin embargo, la expresión <code>nthcdr</code> es más complicada. Usa la -función <code>mod</code> para determinar que <small>CDR</small> para seleccionar. -</p> -<p>(Se recordará buscar funciones propias primero, en vez de esto, -tendremos que ir dentro del <code>mod</code>.) -</p> -<p>La función <code>mod</code> devuelve el valor de su primer argumento -módulo el segundo; que es decir, eso devuelve el resto después de -dividir el primer argumento por el segundo. El valor devuelto tiene el -mismo signo que el segundo argumento. -</p> -<p>De este modo, -</p> -<div class="smallexample"> -<pre class="smallexample">(mod 12 4) - ⇒ 0 ;; <span class="roman">porque no hay resto</span> -(mod 13 4) - ⇒ 1 -</pre></div> - -<p>En este caso, el primer argumento es con frecuencia pequeño que el -segundo. Que está bien. -</p> -<div class="smallexample"> -<pre class="smallexample">(mod 0 4) - ⇒ 0 -(mod 1 4) - ⇒ 1 -</pre></div> - -<p>Se puede adivinar lo que la función <code>-</code> hace. Eso es como -<code>+</code> pero sustrae en vez de añadir; la función <code>-</code> -sustrae su segundo argumento desde el primero. También, ya se sabe -que la función <code>length</code> hace (véase la sección <a href="#length">Encuentra el tamaño de una lista: <code>length</code></a>). Eso devuelve el -tamaño de una lista. -</p> -<p>Y <code>n</code> es el nombre del argumento requerido a la función -<code>current-kill</code>. -</p> -<p>Así cuando el primer argumento a <code>nthcdr</code> es cero, -la expresión <code>nthcdr</code> devuelve la lista entera, como se puede -ver evaluando lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">;; kill-ring-yank-pointer <span class="roman">and</span> kill-ring <span class="roman">tener un tamaño de cuatro</span> -;; <span class="roman">and</span> (mod (- 0 4) 4) ⇒ 0 -(nthcdr (mod (- 0 4) 4) - '("cuarta línea de texto" - "tercera línea" - "segunda pieza de texto" - "primero algo de texto")) -</pre></div> - -<p>Cuando el primer argumento a la función <code>current-kill</code> es uno, -la expresión <code>nthcdr</code> devuelve la lista sin su primer elemento. -</p> -<div class="smallexample"> -<pre class="smallexample">(nthcdr (mod (- 1 4) 4) - '("cuarta línea de texto" - "tercera línea" - "segunda pieza de texto" - "primero algo de texto")) -</pre></div> - -<a name="index-variable-global-definida"></a> -<a name="index-variable_002c-global_002c-definida"></a> -<p>Incidentalmente, tanto <code>kill-ring</code> y -<code>kill-ring-yank-pointer</code> son <em>variables globales</em>. Esto -significa que cualquier expresión en Emacs Lisp puede acceder a -ellas. Ellas no son como las variables locales asignadas por -<code>let</code> o como los símbolos en una lista de -argumentos. Las variables locales pueden solo ser accedidas con el -<code>let</code> que los define o la función que los especifica en una -lista de argumentos (y con expresiones llamadas por ellos). -</p> - -<hr> -<a name="pegar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Determinando-el-elemento" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#yank_002dpop" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="pegar-1"></a> -<h2 class="appendixsec">B.2 <code>pegar</code></h2> -<a name="index-pegar-1"></a> - -<p>Después de aprender acerca de <code>current-kill</code>, el código para -la función <code>yank</code> es casi fácil. -</p> -<p>La función <code>yank</code> no usa la variable <code>kill-ring-yank-pointer</code> -directamente. Eso llama a <code>insert-for-yank</code> que llama a -<code>current-kill</code> que asigna la variable <code>kill-ring-yank-pointer</code>. -</p> -<p>El código se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun yank (&optional arg) - "Reinserta (\"pega\") el último logro del texto cortado. -Más precisamente, reinserta el texto cortado más recientemente. -Pon el punto al final, y asigna la marca al principio. -Solo con \\[universal-argument] como argumento, lo mismo pero pon el -punto al principio (y la marca al final). Con el argumento N, reinserta -el N más recientemente cortado. -Cuando este comando inserta texto cortado dentro del búffer, eso -honra a `yank-excluded-properties' y `yank-handler' como se describe -la cadena de documentación para `insert-for-yank-1', que se ve. - -Ver también el comando \\[yank-pop]." -</pre><pre class="smallexample"> (interactive "*P") - (setq yank-window-start (window-start)) - ;; Si no tenemos todo el camino a través, crea last-command que - ;; indique esto para el siguiente comando. - (setq this-command t) - (push-mark (point)) -</pre><pre class="smallexample"> (insert-for-yank (current-kill (cond - ((listp arg) 0) - ((eq arg '-) -2) - (t (1- arg))))) - (if (consp arg) - ;; Esto es como like exchange-point-and-mark, - ;; pero no activa la marca. - ;; Es limpio evitar la activación, incluso aunque el comando - ;; loop would desactivaría la marca porque se - ;; insertara el texto. - (goto-char (prog1 (mark t) - (set-marker (mark-marker) (point) (current-buffer))))) -</pre><pre class="smallexample"> ;; Si tenemos todo el camino, haz que this-command lo indique. - (if (eq this-command t) - (setq this-command 'yank)) - nil) -</pre></div> - -<p>La expresión clave es <code>insert-for-yank</code>, que inserta la cadena -devuelta por <code>current-kill</code>, pero elimina algo de propiedades de -texto desde eso. -</p> -<p>Sin embargo, antes de tener esta expresión, la función asigna el -valor de <code>yank-window-start</code> a la posición devuelta por la -expresión <code>(window-start)</code>, la posición que muestra lo -que actualmente empieza. La función <code>yank</code> también asigna -<code>this-command</code> y empuja la marca. -</p> -<p>Después de pegar el elemento apropiado, si el argumento opcional es -un <small>CONS</small> en vez de un número o nada, se pone el punto al principio -del texto pegado y se marca al final. -</p> -<p>(La función <code>prog1</code> es como <code>progn</code> pero devuelve el valor -de su primer argumento en vez del valor de su último argumento. Su -primer argumento fuerza devolver la marca del búffer como un -entero. Se puede ver la documentación para estas funciones -emplazando el punto a través de ellas en este búffer y entonces -escribiendo <kbd>C-h f</kbd> (<code>describe-function</code>) seguido por un -<kbd>RET</kbd>; por defecto es la función.) -</p> -<p>La última parte de la función cuenta que hacer cuando eso sucede. -</p> -<hr> -<a name="yank_002dpop"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#pegar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#fichero-anillo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="yank_002dpop-1"></a> -<h2 class="appendixsec">B.3 <code>yank-pop</code></h2> -<a name="index-yank_002dpop"></a> - -<p>Después de comprender <code>yank</code> y <code>current-kill</code>, se conoce -como enfocar la función <code>yank-pop</code>. Dejando fuera la -documentación para guardar el espacio, se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun yank-pop (&optional arg) - "…" - (interactive "*p") - (if (not (eq last-command 'yank)) - (error "El comando previo no fué un corte")) -</pre><pre class="smallexample"> (setq this-command 'yank) - (unless arg (setq arg 1)) - (let ((inhibit-read-only t) - (before (< (point) (mark t)))) -</pre><pre class="smallexample"> (if before - (funcall (or yank-undo-function 'delete-region) (point) (mark t)) - (funcall (or yank-undo-function 'delete-region) (mark t) (point))) - (setq yank-undo-function nil) -</pre><pre class="smallexample"> (set-marker (mark-marker) (point) (current-buffer)) - (insert-for-yank (current-kill arg)) - ;; Asigna la ventana a volver donde estaba el comando yank, - ;; si es posible - (set-window-start (selected-window) yank-window-start t) -</pre><pre class="smallexample"> (if before - ;; Esto es como exchange-point-and-mark, - ;; pero no activa la marca. - ;; Es limpio evitar la activación, incluso aunque el comando - ;; desactivase la marca porque se insertara el texto. - (goto-char (prog1 (mark t) - (set-marker (mark-marker) - (point) - (current-buffer)))))) - nil) -</pre></div> - -<p>La función es interactive con una pequeña ‘<samp>p</samp>’ -así el argumento prefijo es procesado y pasado a la -función. El comando puede solo ser usado después del yank previo; -de otro modo un mensaje de error se envía. Este chequeo -usa la variable <code>last-command</code> que se asigna por <code>yank</code> y -discutida de algún modo. (Véase la sección <a href="#copy_002dregion_002das_002dkill"><code>copy-region-as-kill</code></a>.) -</p> -<p>La cláusula <code>let</code> asigna la variable <code>before</code> a cierto o -falso dependiendo de si el punto está antes o después de la marca -y entonce la región entre punto y marca se borra. Esta es la -región que fué insertada por el yank previo y eso es este texto -que será reemplazado. -</p> -<p><code>funcall</code> llama a su primer argumento como una función, pasando -los argumentos que permanecen. El primer argumento es el que la -expresión <code>or</code> devuelve. Los dos argumentos que permanecen son -las posiciones de punto y marca asignadas por el comando <code>yank</code> -precedente. -</p> -<p>Hay más, pero esta es la parte más dura. -</p> -<hr> -<a name="fichero-anillo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#yank_002dpop" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Kill-Ring" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-fichero-ring_002eel"></a> -<h2 class="appendixsec">B.4 El fichero ‘<tt>ring.el</tt>’</h2> -<a name="index-fichero-ring_002eel"></a> - -<p>De manera interesante, GNU Emacs posee un fichero llamado -‘<tt>ring.el</tt>’ que provee muchas de las funcionalidades que ahora se -discuten. Pero las funciones tales como <code>kill-ring-yank-pointer</code> -no usan esta librería, posiblemente porque fueron -escritas pronto. -</p> -<hr> -<a name="Grafo-completo"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Kill-Ring" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#fichero-anillo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-etiquetado" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Un-grafo-con-ejes-etiquetados"></a> -<h1 class="appendix">Appendix C Un grafo con ejes etiquetados</h1> - -<p>Los ejes impresos ayudan a comprender un grafo. Para crear escalas. En -un capítulo anterior (véase la sección <a href="#Leyendo-un-grafo">Leyendo un grafo</a>), se escribió el código para imprimir el cuerpo de un -grafo. Aquí se escribe el código para imprimir y -etiquetar ejes horizontales y verticales, a lo largo del cuerpo en -sí. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Ejemplo-etiquetado">Grafo de ejemplo etiquetado</a></td><td> </td><td align="left" valign="top"> Ejemplo etiquetado -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002dgraph-Varlist">C.1 La varlist <code>print-graph</code></a></td><td> </td><td align="left" valign="top"> Expresión <code>let</code> en <code>print-graph</code>. -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002dY_002daxis">C.2 La función <code>print-Y-axis</code></a></td><td> </td><td align="left" valign="top"> Imprimir una etiqueta para los ejes verticales. -</td></tr> -<tr><td align="left" valign="top"><a href="#print_002dX_002daxis">C.3 La función <code>print-X-axis</code></a></td><td> </td><td align="left" valign="top"> Imprimir una etiqueta horizontal. -</td></tr> -<tr><td align="left" valign="top"><a href="#Imprimir-Grafo-Entero">C.4 Imprimiendo el grafo completo</a></td><td> </td><td align="left" valign="top"> La función para imprimir un grafo completo. -</td></tr> -</table> - -<hr> -<a name="Ejemplo-etiquetado"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dgraph-Varlist" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Grafo-de-ejemplo-etiquetado"></a> -<h2 class="unnumberedsec">Grafo de ejemplo etiquetado</h2> - -<p>Puesto que las inserciones rellenan un búffer a la derecha y debajo -del punto, el nuevo grafo imprime la función que primero -imprimiría el eje vertical Y, después el cuerpo del -grafo, y finalmente el eje horizontal X. Esta secuencia nos da los -contenidos de la función: -</p> -<ol> -<li> -Configura código. - -</li><li> -Imprime el eje Y. - -</li><li> -Imprime el cuerpo del grafo. - -</li><li> -Imprime el eje X. -</li></ol> - -<p>Aquí hay un ejemplo de como se ve un grafo finalizado: -</p> -<div class="smallexample"> -<pre class="smallexample"> 10 - - * - * * - * ** - * *** - 5 - * ******* - * *** ******* - ************* - *************** - 1 - **************** - | | | | - 1 5 10 15 -</pre></div> - -<p>En este grafo, en ambos ejes vertical y horizontal se etiquetan con -números. Sin embargo, en algunos grafos, el eje horizontal es tiempo -y estaría mejor etiquetarlo con meses, -así: -</p> -<div class="smallexample"> -<pre class="smallexample"> 5 - * - * ** * - ******* - ********** ** - 1 - ************** - | ^ | - Enero Junio Enero -</pre></div> - -<p>Dentro, con un pequeño pensamiento, se puede fácilmente venir con -una variedad de esquemas de etiquetado verticales y -horizontales. Nuestra tarea podría llegar a ser -complicada. Pero las complicaciones generan confusión. En vez de -permitir esto, es mejor elegir un simple esquema de etiquetado para -nuestro primer esfuerzo, y modificarlo o reemplazarlo después. -</p> -<p>Estas consideraciones sugieren el siguiente outline para la función -<code>print-graph</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun print-graph (numbers-list) - "<var>documentation</var>…" - (let ((height … - …)) -</pre><pre class="smallexample"> (print-Y-axis height … ) - (graph-body-print numbers-list) - (print-X-axis … ))) -</pre></div> - -<p>Nosotros podemos trabajar en cada parte de la definición de función -<code>print-graph</code>. -</p> -<hr> -<a name="print_002dgraph-Varlist"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Ejemplo-etiquetado" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-varlist-print_002dgraph"></a> -<h2 class="appendixsec">C.1 La varlist <code>print-graph</code></h2> -<a name="index-print_002dgraph-varlist"></a> - -<p>Para escribir la función <code>print-graph</code>, la primera tarea es -escribir la varlist en la expresión <code>let</code>. (Nosotros dejaremos -por ahora cualquier pensamiento acerca de hacer la función -interactive o acerca de los contenidos de su cadena de documentación.) -</p> -<p>La varlist asignaría varios valores. Claramente, la -etiqueta superior del eje vertical debe ser al menos la altura del -grafo, que significa que debe obtener esta información -aquí. Note que la función <code>print-graph-body</code> -también requiere esta información. No hay razón para calcular la -altura del grafo en dos lugares diferentes, así -cambiaría <code>print-graph-body</code> desde el camino que -definimos pronto para tomar ventaja del cálculo. -</p> -<p>De manera similar, tanto la función para imprimir la etiqueta del -eje X y la función <code>print-graph-body</code> se necesita aprender el -valor del ancho de cada símbolo. Se puede desarrollar el -cálculo aquí y cambiar la definición para -<code>print-graph-body</code> desde el camino que se definió en el -capítulo previo. -</p> -<p>El tamaño de la etiqueta para el eje horizontal debe ser al menos -tan largo como el grafo. Sin embargo, esta información es usada solo -en la función que imprime el eje horizontal, así no -necesita calcularse aquí. -</p> -<p>Estos pensamientos nos llevan directamente a la siguiente forma para -la varlist en el <code>let</code> para <code>print-graph</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(let ((height (apply 'max numbers-list)) ; <span class="roman">Primera versión.</span> - (symbol-width (length graph-blank))) -</pre></div> - -<p>Como se verá, esta expresión no es bastante correcta. -</p> -<hr> -<a name="print_002dY_002daxis"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dgraph-Varlist" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis-en-Detalle" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-print_002dY_002daxis"></a> -<h2 class="appendixsec">C.2 La función <code>print-Y-axis</code></h2> -<a name="index-Ejes_002c-imprimir-vertical"></a> -<a name="index-imprimiendo-eje-Y"></a> -<a name="index-Imprimiendo-Ejes-Verticales"></a> -<a name="index-Imprimir-eje-vertical"></a> - -<p>El trabajo de la función <code>print-Y-axis</code> es imprimir una etiqueta -para el eje vertical que se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample"> 10 - - - - - - 5 - - - - - 1 - -</pre></div> - -<p>La función se pasaría a lo alto del grafo, y -así -construyen e insertan los números y marcas apropiados. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#print_002dY_002daxis-en-Detalle">La función <code>print-Y-axis</code> en detalle</a></td><td> </td><td align="left" valign="top"> print-Y-axis en Detalle -</td></tr> -<tr><td align="left" valign="top"><a href="#Altura-de-etiqueta">¿A qué altura se debería etiquetar?</a></td><td> </td><td align="left" valign="top"> ¿Qué altura para el eje Y? -</td></tr> -<tr><td align="left" valign="top"><a href="#Calcular-un-resto">C.2.1 Viaje lateral: Calcula un resto</a></td><td> </td><td align="left" valign="top"> Cómo calcular el resto de una división. -</td></tr> -<tr><td align="left" valign="top"><a href="#Elemento-del-Eje-Y">C.2.2 Construye un elemento del eje Y</a></td><td> </td><td align="left" valign="top"> Construir una línea para el eje - Y. -</td></tr> -<tr><td align="left" valign="top"><a href="#Y_002daxis_002dcolumn">C.2.3 Crea un eje de la columna Y</a></td><td> </td><td align="left" valign="top"> Generar una lista de etiquetas del eje Y. -</td></tr> -<tr><td align="left" valign="top"><a href="#Pen_00faltimo-print_002dY_002daxis">C.2.4 La versión no demasiado final de <code>print-Y-axis</code></a></td><td> </td><td align="left" valign="top"> Una versión no muy final. -</td></tr> -</table> - -<hr> -<a name="print_002dY_002daxis-en-Detalle"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Altura-de-etiqueta" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-print_002dY_002daxis-en-detalle"></a> -<h3 class="unnumberedsubsec">La función <code>print-Y-axis</code> en detalle</h3> - -<p>Es suficientemente fácil ver en la figura que la etiqueta del eje Y -pero se puede decir en palabras, y entonces escribir una definición -de función para hacer el trabajo es otra materia. No es bastante -verdad decir que se quiere un número y un tic cada cinco -líneas: solo hay tres líneas entre el -‘<samp>1</samp>’ y el ‘<samp>5</samp>’ (líneas 2, 3 y 4), pero cuatro -líneas entre el ‘<samp>5</samp>’ y el ‘<samp>10</samp>’ -(líneas 6, 7, 8 y 9). Es mejor decir que se quiere un -número y un tic en la quinta línea desde abajo a cada -línea que es un múltiplo de cinco. -</p> -<hr> -<a name="Altura-de-etiqueta"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis-en-Detalle" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Calcular-un-resto" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="g_t_00bfA-que-altura-se-deberia-etiquetar_003f"></a> -<h3 class="unnumberedsubsec">¿A qué altura se debería etiquetar?</h3> - -<p>La siguiente cuestión es a que altura se -etiquetaría. Supón que la máxima altura de la columna -mayor del grafo es siete. La etiqueta superior en el eje Y -sería ‘<samp>5 -</samp>’, ¿y el grafo se pegaría -debajo de la etiqueta?, ¿o la etiqueta superior sería -‘<samp>7 -</samp>’, y marcar la vertical del grafo? ¿o sería la -etiqueta superior <code>10 -</code>, que es múltiplo de cinco, y es -superior al valor más alto del grafo? -</p> -<p>La última forma es preferida. La mayoría de los grafos -son rectángulos cuyos lados son un número integral de pasos a lo -largo — 5, 10, 15, y así para un paso a distancia de -cinco. Pero tan pronto se decide usar un paso alto para el eje -vertical, se descubre que la expresión simple en la varlist para la -altura de la computación es errónea. La expresión es -<code>(apply 'max numbers-list)</code>. Esto devuelve la altura precisa, no -la altura máxima más de lo que es necesario para redondear el -múltiplo de cinco. Una expresión más compleja es requerida. -</p> -<p>Como es normal en casos como este, un problema complejo llega a ser -simple si está dividido en varios problemas pequeños. -</p> -<p>Primero, considere el caso cuando el valor superior del grafo es un -múltiplo integral de cinco — cuando eso es 5, 10, 15, o algún -múltiplo de cinco. Se puede usar este valor como la altura del eje Y. -</p> -<p>Un camino simple y limpio para determinar si un número es múltiplo -de cinco se divide por cinco y mira si la división devuelve -resto. Si no hay resto, el número es un múltiplo de cinco. De este -modo, siete dividido tiene un resto de dos, y siete no es un entero -múltiplo de cinco. Dicho de otra manera, recordando la escuela, -cinco entre siete es uno y me llevo dos. Sin embargo, diez entre dos, -no tiene resto: diez es un múltiplo entero de cinco. -</p> -<hr> -<a name="Calcular-un-resto"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Altura-de-etiqueta" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Elemento-del-Eje-Y" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Viaje-lateral_003a-Calcula-un-resto"></a> -<h3 class="appendixsubsec">C.2.1 Viaje lateral: Calcula un resto</h3> - -<a name="index-_0025-_0028funcion-resto_0029"></a> -<a name="index-Funcion-resto_002c-_0025"></a> -<p>En Lisp, la función para calcular un resto es <code>%</code>. La función -devuelve el resto de su primer argumento dividido por su segundo -argumento. Como ocurre, <code>%</code> es una función en Emacs Lisp que no -se puede implementar usando <code>apropos</code>: no se puede encontrar nada si -se escribe <kbd>M-x apropos <RET> resto <RET></kbd>. El único -camino para aprender la existencia de <code>%</code> es leer acerca de eso -en un libro tal como este o en las fuentes de Emacs Lisp. -</p> -<p>Se puede probar la función <code>%</code> evaluando las siguientes dos -expresiones: -</p> -<div class="smallexample"> -<pre class="smallexample">(% 7 5) - -(% 10 5) -</pre></div> - -<p>La primera expresión devuelve 2 y la segunda expresión devuelve 0. -</p> -<p>Para chequear si el valor devuelto es cero o algún otro número, se -puede usar la función <code>zerop</code>. Esta función devuelve <code>t</code> -si su argumento debe ser un número, es cero. -</p> -<div class="smallexample"> -<pre class="smallexample">(zerop (% 7 5)) - ⇒ nil - -(zerop (% 10 5)) - ⇒ t -</pre></div> - -<p>De este modo, la siguiente expresión devolverá <code>t</code> si la -altura del grafo es divisible por cinco: -</p> -<div class="smallexample"> -<pre class="smallexample">(zerop (% height 5)) -</pre></div> - -<p>(El valor de <code>height</code>, de acuerdo, puede ser encontrado desde -<code>(apply 'max numbers-list)</code>.) -</p> -<p>Por otro lado, si el valor de <code>height</code> no es un múltiplo de -cinco, nosotros queremos resetear el valor al siguiente múltiplo de -cinco. Esta es la aritmética sencilla usando funciones con las que -ya se está familiarizado. Primero, se divide el valor de -<code>height</code> por cinco para determinar cuantas veces cinco va dentro -del número. De este modo, cinco va dentro doce veces. Si se añade -uno a este cociente y se multiplica por cinco, obtendremos el valor -del siguiente múltiplo de cinco que es más largo que el -mayor. Cinco va dentro de doce dos veces. Añade uno a dos, y -multiplica por cinco; el resultado es quince, que es el siguiente -múltiplo de cinco que es mayor de doce. La expresión Lisp para -esto es: -</p> -<div class="smallexample"> -<pre class="smallexample">(* (1+ (/ height 5)) 5) -</pre></div> - -<p>Por ejemplo, si se evalúa lo siguiente, el resultado es 15: -</p> -<div class="smallexample"> -<pre class="smallexample">(* (1+ (/ 12 5)) 5) -</pre></div> - -<p>Todo a través de esta discusión, se ha estado usando ‘cinco’ como -el valor para las etiquetas espaciadas en el eje Y; pero se puede -querer usar algún otro valor. Generalmente, -reemplazaría ‘cinco’ con una variable a la que poder -asignar un valor. El mejor nombre que puedo pensar para esta variable -es <code>Y-axis-label-spacing</code>. -</p> -<p>Usando este término, y una expresión <code>if</code>, se produce lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(if (zerop (% height Y-axis-label-spacing)) - height - ;; <span class="roman">else</span> - (* (1+ (/ height Y-axis-label-spacing)) - Y-axis-label-spacing)) -</pre></div> - -<p>Esta expresión devuelve el valor de <code>height</code> en -sí si la altura es incluso un múltiplo del valor del -<code>Y-axis-label-spacing</code> o lo demás computa y devuelve un valor -de <code>height</code> que es igual al siguiente múltiplo mayor del valor -del <code>Y-axis-label-spacing</code>. -</p> -<p>Se puede ahora incluir esta expresión en la expresión <code>let</code> -de la función <code>print-graph</code> (después de la primera -configuración del valor de <code>Y-axis-label-spacing</code>): -<a name="index-Y_002daxis_002dlabel_002dspacing"></a> -</p> -<div class="smallexample"> -<pre class="smallexample">(defvar Y-axis-label-spacing 5 - "Número de líneas desde una etiqueta del eje Y al siguiente.") -</pre><pre class="smallexample"> -</pre><pre class="smallexample">… -(let* ((height (apply 'max numbers-list)) - (height-of-top-line - (if (zerop (% height Y-axis-label-spacing)) - height -</pre><pre class="smallexample"> ;; <span class="roman">else</span> - (* (1+ (/ height Y-axis-label-spacing)) - Y-axis-label-spacing))) - (symbol-width (length graph-blank)))) -… -</pre></div> - -<p>(Note que el uso de la función <code>let*</code>: el valor inicial de la -altura es calculada una vez por la expresión <code>(apply 'max -numbers-list)</code> y entonces el valor resultado de <code>height</code> es -usado para computar su valor final. Véase la sección <a href="#fwd_002dpara-let">La expresión <code>let*</code></a>, para más acerca de <code>let*</code>.) -</p> -<hr> -<a name="Elemento-del-Eje-Y"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Calcular-un-resto" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Y_002daxis_002dcolumn" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Construye-un-elemento-del-eje-Y"></a> -<h3 class="appendixsubsec">C.2.2 Construye un elemento del eje Y</h3> - -<p>Cuando se imprime el eje vertical, se quieren insertar cadenas tales -como ‘<samp>5 <span class="nolinebreak">-</span></samp>’ y ‘<samp>10 <span class="nolinebreak">-</span> </samp>’ cada cinco -líneas. Más allá, se quieren los números agitados -para alinear, así pocos números deben ser acuñados -con espacios de guía. Si alguna de las cadenas usan dos -dígitos, las cadenas con un simple dígito -deben incluir una guía en blanco antes del número. -</p> -<a name="index-number_002dto_002dstring"></a> -<p>Para figurarse el tamaño del número, se usa la función -<code>length</code>. Pero la función <code>length</code> funciona solo con una -cadena, no con un número. Así el número tiene que -ser convertido desde un número a una cadena. Esto se hace con la -función <code>number-to-string</code>. Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(length (number-to-string 35)) - ⇒ 2 - -(length (number-to-string 100)) - ⇒ 3 -</pre></div> - -<p>(<code>number-to-string</code> se llama <code>int-to-string</code>; se verá este -nombre alternativo en varias fuentes.) -</p> -<p>Además, en cada etiqueta, cada número es seguido por una cadena -tal como ‘<samp> <span class="nolinebreak">-</span> </samp>’, que llamará al marcador -<code>Y-axis-tic</code>. Esta variable está definida con <code>defvar</code>: -</p> -<a name="index-Y_002daxis_002dtic"></a> -<div class="smallexample"> -<pre class="smallexample">(defvar Y-axis-tic " - " - "La Cadena que sigue el número en una etiqueta del eje Y.") -</pre></div> - -<p>El tamaño de la etiqueta Y es la suma del tamaño del eje Y y el -tamaño del número del alto del grafo. -</p> -<div class="smallexample"> -<pre class="smallexample">(length (concat (number-to-string height) Y-axis-tic))) -</pre></div> - -<p>Este valor será calculado por la función <code>print-graph</code> en su -varlist como <code>full-Y-label-width</code> y se pasa dentro. (Note que no -se pensaba en incluir esto en el varlist cuando se propuso.) -</p> -<p>Para crear un eje vertical completo, una marca de tic es concatenada -con un número; y los dos juntos pueden ser precedidos por uno o -más espacios dependiendo de cómo de largo es el número. La -etiqueta consiste de tres partes: los espacios que se lideran -(opcional), el número, y la marca tic. La función se pasa al -valor del número para la fila específica, y el valor -del ancho de la línea de arriba, que es calculada (solo -una vez) por <code>print-graph</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun Y-axis-element (number full-Y-label-width) - "Construye una etiqueta NUMERADA -Un elemento numerado se parece a esto ` 5 - ', -y está tan acuñado como se necesita así todo se -alinea con el elemento para el número mayor." -</pre><pre class="smallexample"> (let* ((leading-spaces - (- full-Y-label-width - (length - (concat (number-to-string number) - Y-axis-tic))))) -</pre><pre class="smallexample"> (concat - (make-string leading-spaces ? ) - (number-to-string number) - Y-axis-tic))) -</pre></div> - -<p>La función <code>Y-axis-element</code> concatena junto los espacios que se -lideran si cualquiera; el número, como una cadena; y la marca tic. -</p> -<p>Para imaginarnos cuantos espacios guía la etiqueta -necesita, la función sustrae el tamaño de la etiqueta — el -tamaño del número más el tamaño de la marca tic — desde el -ancho de la etiqueta deseada. -</p> -<a name="index-make_002dstring"></a> -<p>Los espacios en blanco se insertan usando la función -<code>make-string</code>. Esta función tiene dos argumentos: lo primero -cuenta como de larga será a cadena y el segundo es un -símbolo para el caracter a insertar, en un formato -espcial. El formato es una marca de pregunta seguida por un espacio en -blanco, como este, ‘<samp>?</samp>’. See <a href="elisp.html#Tipo-de-Caracter">Tipo de Caracter</a> in <cite>El Manual de Referencia Emacs Lisp</cite>, para una -descripción de la sintaxis para caracteres. (De acuerdo, se -podría querer reemplazar el espacio en blanco por -algún otro caracter …. Tu sabes qué hacer.) -</p> -<p>La función <code>number-to-string</code> es usada en la expresión de -concatenación, para convertir el número a una cadena que es -concatenada con los espacios que se lideran y la marca de tic. -</p> -<hr> -<a name="Y_002daxis_002dcolumn"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Elemento-del-Eje-Y" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Pen_00faltimo-print_002dY_002daxis" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Crea-un-eje-de-la-columna-Y"></a> -<h3 class="appendixsubsec">C.2.3 Crea un eje de la columna Y</h3> - -<p>Las funciones precedentes proporcionan todas las herramientas -necesarias para construir una función que genera una lista de -cadenas enumeradas y en blanco para inserta como la etiqueta para el -eje vertical: -</p> -<a name="index-Y_002daxis_002dcolumn"></a> -<div class="smallexample"> -<pre class="smallexample">(defun Y-axis-column (height width-of-label) - "Construye la lista de ejes Y etiquetadas y cadenas en blanco. -Para height <em>la altura</em> de la línea de debajo y width-of-label." - (let (Y-axis) -</pre><pre class="smallexample"> (while (> height 1) - (if (zerop (% height Y-axis-label-spacing)) - ;; <span class="roman">Insertar etiqueta.</span> - (setq Y-axis - (cons - (Y-axis-element height width-of-label) - Y-axis)) -</pre><pre class="smallexample"> ;; <span class="roman">Else, insertar blancos.</span> - (setq Y-axis - (cons - (make-string width-of-label ? ) - Y-axis))) - (setq height (1- height))) - ;; <span class="roman">Insertar la línea base.</span> - (setq Y-axis - (cons (Y-axis-element 1 width-of-label) Y-axis)) - (nreverse Y-axis))) -</pre></div> - -<p>En esta función, nosotros empezamos con el valor de <code>height</code> y -repetitivamente sustrae uno desde su valor. Después de cada -sustración, se chequea para ver si el valor es una integral -múltiple del <code>Y-axis-label-spacing</code>. Si eso es, se construye -una etiqueta numerada usando la función <code>Y-axis-element</code>; si -no, se construye una etiqueta blanca usando la función -<code>make-string</code>. La línea base consiste del número -uno seguido por una marca tic. -</p> -<hr> -<a name="Pen_00faltimo-print_002dY_002daxis"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Y_002daxis_002dcolumn" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dY_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dX_002daxis" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-version-no-demasiado-final-de-print_002dY_002daxis"></a> -<h3 class="appendixsubsec">C.2.4 La versión no demasiado final de <code>print-Y-axis</code></h3> - -<p>La lista construida por la función <code>Y-axis-column</code> está pasada -a la función <code>print-Y-axis</code>, que inserta la lista como una columna. -</p> -<a name="index-print_002dY_002daxis"></a> -<div class="smallexample"> -<pre class="smallexample">(defun print-Y-axis (height full-Y-label-width) - "Inserta el eje Y usando HEIGHT y FULL-Y-LABEL-WIDTH. -La altura debe ser la máxima altura del grafo. -El ancho completo es el ancho del mayor elemento de la -etiqueta" -;; El valor del alto y full-Y-label-width -;; son pasadas por `print-graph'. -</pre><pre class="smallexample"> (let ((start (point))) - (insert-rectangle - (Y-axis-column height full-Y-label-width)) - ;; <span class="roman">Posiciona el punto listo para inserta el grafo.</span> - (goto-char start) - ;; <span class="roman">Mueve el punto hacia adelante por valor de</span> full-Y-label-width - (forward-char full-Y-label-width))) -</pre></div> - -<p>El <code>print-Y-axis</code> usa la función <code>insert-rectangle</code> para -inserta el eje Y creado por la función -<code>Y-axis-column</code>. Además, eso emplaza el punto en la posición -correcta para imprimir el cuerpo del grafo. -</p> -<p>Se puede chequear <code>print-Y-axis</code>: -</p> -<ol> -<li> -Instalar - -<div class="smallexample"> -<pre class="smallexample">Y-axis-label-spacing -Y-axis-tic -Y-axis-element -Y-axis-column -print-Y-axis -</pre></div> - -</li><li> -Copia la siguiente expresión: - -<div class="smallexample"> -<pre class="smallexample">(print-Y-axis 12 5) -</pre></div> - -</li><li> -Cambia al búffer ‘<tt>*scratch*</tt>’ y emplaza el cursor donde se -quiere el eje etiquetado para empezar. - -</li><li> -Escribe <kbd>M-:</kbd> (<code>eval-expression</code>). - -</li><li> -Pega la expresión <code>graph-body-print</code> dentro del minibúffer con -<kbd>C-y</kbd> (<code>yank</code>). - -</li><li> -Presiona <RET> para evaluar la expresión -</li></ol> - -<p>Emacs imprimirá etiquetas verticalmente, el primero siendo -‘<samp>10 <span class="nolinebreak">-</span> </samp>’. (La función <code>print-graph</code> pasará el -valor de <code>height-of-top-line</code>, que en este caso finalizará en -15, por esto lo que se obtiene podría aparecer como un error.) -</p> -<hr> -<a name="print_002dX_002daxis"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Pen_00faltimo-print_002dY_002daxis" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Diferencias-similares" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-print_002dX_002daxis"></a> -<h2 class="appendixsec">C.3 La función <code>print-X-axis</code></h2> -<a name="index-Ejes_002c-imprime-horizontal"></a> -<a name="index-imprimiendo-eje-X"></a> -<a name="index-Imprime-eje-horizontal"></a> -<a name="index-Imprimiendo-eje-horizontal"></a> - -<p>Las etiquetas del eje X son como las etiquetas del eje Y, excepto que -los ticks son un línea debajo de los números. Las -etiquetas se parece como esto: -</p> -<div class="smallexample"> -<pre class="smallexample"> | | | | - 1 5 10 15 -</pre></div> - -<p>El primer tic está bajo la primera columna del grafo y está -precedido por varios espacios en blanco. Estos espacios proporcionan -la habitación en filas de debajo para las etiquetas del eje Y. El -segundo, tercer, cuarto, y subsiguientes ticks son todos espaciados -igualmente, de acuerdo al valor de <code>X-axis-label-spacing</code>. -</p> -<p>La segunda fila del eje X consiste de números, precedidos por varios -espacios en blanco y también separado de acuerdo al valor de la -variable <code>X-axis-label-spacing</code>. -</p> -<p>El valor de la variable <code>X-axis-label-spacing</code> -sería medido en unidades de <code>symbol-width</code>, puesto -que se puede querer cambiar el ancho de los símbolos que -estás usando para imprimir el cuerpo del grafo sin cambiar los -caminos del grafo que está etiquetado. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#Diferencias-similares">Similaridades y diferencias</a></td><td> </td><td align="left" valign="top"> Mucho como <code>print-Y-axis</code>, pero no - exactamente. -</td></tr> -<tr><td align="left" valign="top"><a href="#Eje-X-marca-tic">C.3.1 Eje X marca tic</a></td><td> </td><td align="left" valign="top"> Crear marcas de tic para los ejes horizontales. -</td></tr> -</table> - -<hr> -<a name="Diferencias-similares"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dX_002daxis" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dX_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Eje-X-marca-tic" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Similaridades-y-diferencias"></a> -<h3 class="unnumberedsubsec">Similaridades y diferencias</h3> - -<p>La función <code>print-X-axis</code> está construida más o menos del -mismo modo como que la función <code>print-Y-axis</code> excepto que tiene -dos líneas: la línea de marcas tic y los -números. Nosotros escribiremos una función separado a imprimir -cada línea y entonces combinarlo con la función -<code>print-X-axis</code>. -</p> -<p>Esto es un proceso de tres pasos: -</p> -<ol> -<li> -Escribe una función para imprimir el eje X marca tic, -<code>print-X-axis-tic-line</code>. - -</li><li> -Escribe una función imprime los números X, -<code>print-X-axis-numbered-line</code>. - -</li><li> -Escribe una función para imprimir ambas líneas, la -función <code>print-X-axis</code>, usando <code>print-X-axis-tic-line</code> y -<code>print-X-axis-numbered-line</code>. -</li></ol> - -<hr> -<a name="Eje-X-marca-tic"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Diferencias-similares" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#print_002dX_002daxis" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Eje-X-marca-tic-1"></a> -<h3 class="appendixsubsec">C.3.1 Eje X marca tic</h3> - -<p>La primera función imprimiría las marcas de tic del eje -X. Se deben especificar las marcas en sí y su espacio: -</p> -<div class="smallexample"> -<pre class="smallexample">(defvar X-axis-label-spacing - (if (boundp 'graph-blank) - (* 5 (length graph-blank)) 5) - "Números de unidades desde un eje X al siguiente.") -</pre></div> - -<p>(Note que el valor de <code>graph-blank</code> est’a asignado por otro -<code>defvar</code>. El predicado <code>boundp</code> chequea si ya ha sido -asignado; <code>boundp</code> devuelve <code>nil</code> si no lo tiene. Si -<code>graph-blank</code> fuera disociado y no usara esta construcción -condicional, en un GNU Emacs reciente, se introduciría -el depurador y mirará un mensaje de error diciendo ‘<samp>Debugger <span class="nolinebreak">entered--Lisp</span> error: <span class="nolinebreak">(void-variable</span> <span class="nolinebreak">graph-blank)</span></samp>’ -</p> -<p>Aquí está el <code>defvar</code> para <code>X-axis-tic-symbol</code>: -</p> -<div class="smallexample"> -<pre class="smallexample">(defvar X-axis-tic-symbol "|" - "Cadena para insertar para apuntar a una columna en el eje X.") -</pre></div> - -<p>El objetivo es crear una línea que se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample"> | | | | -</pre></div> - -<p>El primer tic es indentado así que está bajo la -primera columna, que es indentado para proveer espacio para las -etiquetas del eje Y. -</p> -<p>Un elemento tic consiste en espacios en blanco que se extienden desde -un tic al siguiente más un símbolo tic. El número de -espacios en blanco se determinan por el ancho del -símbolo tic y el <code>X-axis-label-spacing</code>. -</p> -<p>El código se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">;;; X-axis-tic-element -… -(concat - (make-string - ;; <span class="roman">Crea una cadena de blancos.</span> - (- (* symbol-width X-axis-label-spacing) - (length X-axis-tic-symbol)) - ? ) - ;; <span class="roman">Concatena blancos con símbolos.</span> - X-axis-tic-symbol) -… -</pre></div> - -<p>Lo siguiente, determina cuantos espacios en blanco son necesarios para -indentar la primera marca tic a la primera del grafo. Esto usa el -valor de <code>full-Y-label-width</code> pasaba por la función -<code>print-graph</code>. -</p> -<p>El código para crear <code>X-axis-leading-spaces</code> se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">;; X-axis-leading-spaces -… -(make-string full-Y-label-width ? ) -… -</pre></div> - -<p>También necesita determinar el tamaño del eje horizontal, que es -el tamaño de la lista de números, y el número de ticks en el eje -horizontal: -</p> -<div class="smallexample"> -<pre class="smallexample">;; X-length -… -(length numbers-list) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; tic-width -… -(* symbol-width X-axis-label-spacing) -</pre><pre class="smallexample"> -</pre><pre class="smallexample">;; number-of-X-ticks -(if (zerop (% (X-length tic-width))) - (/ (X-length tic-width)) - (1+ (/ (X-length tic-width)))) -</pre></div> - -<p>Todo esto lidera directamente a la función para imprimir el eje X: -</p> -<a name="index-print_002dX_002daxis_002dtic_002dline"></a> -<div class="smallexample"> -<pre class="smallexample">(defun print-X-axis-tic-line - (number-of-X-tics X-axis-leading-spaces X-axis-tic-element) - "Imprime ticks para el eje X." - (insert X-axis-leading-spaces) - (insert X-axis-tic-symbol) ; <span class="roman">En la primera columna.</span> -</pre><pre class="smallexample"> ;; <span class="roman">Inserta el segundo tic en el lugar adecuado.</span> - (insert (concat - (make-string - (- (* symbol-width X-axis-label-spacing) - ;; <span class="roman">Inserta el espacio en blanco al segundo símbolo tic.</span> - (* 2 (length X-axis-tic-symbol))) - ? ) - X-axis-tic-symbol)) -</pre><pre class="smallexample"> ;; <span class="roman">Inserta los ticks que permanecen.</span> - (while (> number-of-X-tics 1) - (insert X-axis-tic-element) - (setq number-of-X-tics (1- number-of-X-tics)))) -</pre></div> - -<p>La línea de números es igualmente simple: -</p> -<p>Primero, creamos un elemento numerado con espacios en blanco antes de -cada número: -</p> -<a name="index-X_002daxis_002delement"></a> -<div class="smallexample"> -<pre class="smallexample">(defun X-axis-element (number) - "Construye un elemento del eje X numerado." - (let ((leading-spaces - (- (* symbol-width X-axis-label-spacing) - (length (number-to-string number))))) - (concat (make-string leading-spaces ? ) - (number-to-string number)))) -</pre></div> - -<p>Lo siguiente, se crea la función para imprimir la -línea numerada, empezando con el número “1” para la -primera columna: -</p> -<a name="index-print_002dX_002daxis_002dnumbered_002dline"></a> -<div class="smallexample"> -<pre class="smallexample">(defun print-X-axis-numbered-line - (number-of-X-tics X-axis-leading-spaces) - "Imprime la líneas de números del eje X" - (let ((number X-axis-label-spacing)) - (insert X-axis-leading-spaces) - (insert "1") -</pre><pre class="smallexample"> (insert (concat - (make-string - ;; <span class="roman">Inserta espacios en blanco al siguiente número.</span> - (- (* symbol-width X-axis-label-spacing) 2) - ? ) - (number-to-string number))) -</pre><pre class="smallexample"> ;; <span class="roman">Insertar números.</span> - (setq number (+ number X-axis-label-spacing)) - (while (> number-of-X-tics 1) - (insert (X-axis-element number)) - (setq number (+ number X-axis-label-spacing)) - (setq number-of-X-tics (1- number-of-X-tics))))) -</pre></div> - -<p>Finalmente, se necesita escribir lo que <code>print-X-axis</code> que usa -<code>print-X-axis-tic-line</code> y <code>print-X-axis-numbered-line</code>. -</p> -<p>La función debe determinar los valores locales de las variables -usadas por <code>print-X-axis-tic-line</code> y -<code>print-X-axis-numbered-line</code>, y entonces eso debe -llamarlas. También, debe imprimir el retorno de carro que separe las -dos líneas. -</p> -<p>La función consiste de una varlist que especifica cinco variables -locales, y llama cada una de las dos líneas imprimiendo -funciones: -</p> -<a name="index-print_002dX_002daxis"></a> -<div class="smallexample"> -<pre class="smallexample">(defun print-X-axis (numbers-list) - "Imprime el eje X etique al tamaño de NUMBERS-LIST." - (let* ((leading-spaces - (make-string full-Y-label-width ? )) -</pre><pre class="smallexample"> ;; symbol-width <span class="roman">se provee por</span> graph-body-print - (tic-width (* symbol-width X-axis-label-spacing)) - (X-length (length numbers-list)) -</pre><pre class="smallexample"> (X-tic - (concat - (make-string -</pre><pre class="smallexample"> ;; <span class="roman">Crea una cadena de espacios en blanco.</span> - (- (* symbol-width X-axis-label-spacing) - (length X-axis-tic-symbol)) - ? ) -</pre><pre class="smallexample"> ;; <span class="roman">Concatena espacio en blanco con símbolos - tic.</span> - X-axis-tic-symbol)) -</pre><pre class="smallexample"> (tic-number - (if (zerop (% X-length tic-width)) - (/ X-length tic-width) - (1+ (/ X-length tic-width))))) -</pre><pre class="smallexample"> (print-X-axis-tic-line tic-number leading-spaces X-tic) - (insert "\n") - (print-X-axis-numbered-line tic-number leading-spaces))) -</pre></div> - -<p>Se puede testear <code>print-X-axis</code>: -</p> -<ol> -<li> -Instale <code>X-axis-tic-symbol</code>, <code>X-axis-label-spacing</code>, -<code>print-X-axis-tic-line</code>, tanto como <code>X-axis-element</code>, -<code>print-X-axis-numbered-line</code>, y <code>print-X-axis</code>. - -</li><li> -Copia la siguiente expresión: - -<div class="smallexample"> -<pre class="smallexample">(progn - (let ((full-Y-label-width 5) - (symbol-width 1)) - (print-X-axis - '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)))) -</pre></div> - -</li><li> -Cambia al búffer ‘<tt>*scratch*</tt>’ y emplaza el cursor donde se -quiere el eje etiquetado para empezar. - -</li><li> -Escribe <kbd>M-:</kbd> (<code>eval-expression</code>). - -</li><li> -Pegue la expresión de test dentro del minibuffer con <kbd>C-y</kbd> -(<code>yank</code>). - -</li><li> -Presiona <RET> para evaluar la expresión -</li></ol> - -<p>Emacs imprimirá el eje horizontal así -</p><br> - -<div class="smallexample"> -<pre class="smallexample"> | | | | | - 1 5 10 15 20 -</pre></div> - -<hr> -<a name="Imprimir-Grafo-Entero"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Eje-X-marca-tic" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-completo" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#La-versi_00f3n-final" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Imprimiendo-el-grafo-completo"></a> -<h2 class="appendixsec">C.4 Imprimiendo el grafo completo</h2> -<a name="index-Imprimiendo-el-grafo-entero"></a> -<a name="index-Imprimiendo-el-grafo-entero-1"></a> -<a name="index-Grafo_002c-imprimiendo-todo"></a> - -<p>Ahora estamos listos para imprimir el grafo completo. -</p> -<p>La función para imprimir el grafo con las etiquetas apropiadas sigue -el esquema que creamos antes (véase la sección <a href="#Grafo-completo">Un Grafo con Ejes Etiquetados</a>), pero con adiciones. -</p> -<p>Aquí está el esquema: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun print-graph (numbers-list) - "<var>documentation</var>…" - (let ((height … - …)) -</pre><pre class="smallexample"> (print-Y-axis height … ) - (graph-body-print numbers-list) - (print-X-axis … ))) -</pre></div> - -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#La-versi_00f3n-final">Cambios para la versión final</a></td><td> </td><td align="left" valign="top"> Unos pocos cambios -</td></tr> -<tr><td align="left" valign="top"><a href="#Testear-print_002dgraph">C.4.1 Testeando <code>print-graph</code></a></td><td> </td><td align="left" valign="top"> Ejecutar un rápido test. -</td></tr> -<tr><td align="left" valign="top"><a href="#Graficar-palabras-en-funciones">C.4.2 Creando gráficas de números de palabras y símbolos</a></td><td> </td><td align="left" valign="top"> Ejecutando el código final. -</td></tr> -<tr><td align="left" valign="top"><a href="#lambda">C.4.3 Una expresión <code>lambda</code>: Anonimicidad útil</a></td><td> </td><td align="left" valign="top"> Cómo escribir una función anónima. -</td></tr> -<tr><td align="left" valign="top"><a href="#mapcar">C.4.4 La función <code>mapcar</code></a></td><td> </td><td align="left" valign="top"> Aplicar una función a elementos de una lista. -</td></tr> -<tr><td align="left" valign="top"><a href="#Otro-Error">C.4.5 Otro error … más insidioso</a></td><td> </td><td align="left" valign="top"> Todavía otro error … más - insidioso. -</td></tr> -<tr><td align="left" valign="top"><a href="#Grafo-impreso-final">C.4.6 El gráfico impreso</a></td><td> </td><td align="left" valign="top"> ¡El grafo en sí! -</td></tr> -</table> - -<hr> -<a name="La-versi_00f3n-final"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Testear-print_002dgraph" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Cambios-para-la-version-final"></a> -<h3 class="unnumberedsubsec">Cambios para la versión final</h3> - -<p>La versión final es diferente desde que se planea en dos caminos: -primero, contiene los valores adicionales calculadas una vez que en la -varlist; segundo, eso trae una opción para específicar -las etiquetas se incrementa la fila. Esta última funcionalidad -cambia a ser esencial; de otro modo, un grafo puede tener más filas -que ajustarse en una muestra o en una hoja de papel. -</p> -<p>Esta nueva funcionalidad requiere un cambio a la función -<code>Y-axis-column</code>, para añadir <code>vertical-step</code> para -eso. Esta función es parece a esto: -</p> -<a name="index-Y_002daxis_002dcolumn-Version-Final_002e"></a> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Versión Final.</span> -(defun Y-axis-column - (height width-of-label &optional vertical-step) - "Construye una lista de etiquetas para el eje Y. -HEIGHT es la máxima altura del grafo. -WIDTH-OF-LABEL es el máximo ancho de la etiqueta. -VERTICAL-STEP, una opción, es un entero positivo -que especifica cuanto una etiqueta de eje Y incrementa -cada línea. Por ejemplo, un paso de 5 -significa que cada línea es cinco unidades -del grafo." -</pre><pre class="smallexample"> (let (Y-axis - (number-per-line (or vertical-step 1))) - (while (> height 1) - (if (zerop (% height Y-axis-label-spacing)) -</pre><pre class="smallexample"> ;; <span class="roman">Inserta etiqueta.</span> - (setq Y-axis - (cons - (Y-axis-element - (* height number-per-line) - width-of-label) - Y-axis)) -</pre><pre class="smallexample"> ;; <span class="roman">Else, inserta espacios en blanco.</span> - (setq Y-axis - (cons - (make-string width-of-label ? ) - Y-axis))) - (setq height (1- height))) -</pre><pre class="smallexample"> ;; <span class="roman">Inserta línea base.</span> - (setq Y-axis (cons (Y-axis-element - (or vertical-step 1) - width-of-label) - Y-axis)) - (nreverse Y-axis))) -</pre></div> - -<p>Los valores para la máxima altura del grafo y el ancho de un -símbolo se computan por <code>print-graph</code> es su -expresión <code>let</code>; así <code>graph-body-print</code> debe -ser cambiado para aceptarlos. -</p> -<a name="index-graph_002dbody_002dprint-Version-Final_002e"></a> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Versión Final.</span> -(defun graph-body-print (numbers-list height symbol-width) - "Imprime una gráfica de barras del NUMBERS-LIST. -El numbers-list consiste en los valores del eje Y. -HEIGHT es la máxisma altura del grafo. -SYMBOL-WIDTH es el número de cada columna." -</pre><pre class="smallexample"> (let (from-position) - (while numbers-list - (setq from-position (point)) - (insert-rectangle - (column-of-graph height (car numbers-list))) - (goto-char from-position) - (forward-char symbol-width) -</pre><pre class="smallexample"> ;; <span class="roman">Dibuja el grafo columna por columna.</span> - (sit-for 0) - (setq numbers-list (cdr numbers-list))) - ;; <span class="roman">Posiciona el punto para las etiquetas del eje X.</span> - (forward-line height) - (insert "\n"))) -</pre></div> - -<p>Finalmente, el código para la función <code>print-graph</code>: -</p> -<a name="index-print_002dgraph-Version-Final_002e"></a> -<div class="smallexample"> -<pre class="smallexample">;;; <span class="roman">Versión Final.</span> -(defun print-graph - (numbers-list &optional vertical-step) - "El gráfico de barras etiquetadas del NUMBERS-LIST. -El numbers-list consiste en los valores de eje Y. -</pre><pre class="smallexample"> -</pre><pre class="smallexample">Opcionalmente, VERTICAL-STEP, un entero positivo, especifica cuanto el -eje Y incrementa cada línea. Por ejemplo, un paso de 5 -significa que cada fila es de cinco unidades. -</pre><pre class="smallexample"> (let* ((symbol-width (length graph-blank)) - ;; <code>height</code> <span class="roman">en ambos es el número más largo</span> - ;; <span class="roman">y el número con la mayoría de los digitos.</span> - (height (apply 'max numbers-list)) -</pre><pre class="smallexample"> (height-of-top-line - (if (zerop (% height Y-axis-label-spacing)) - height - ;; <span class="roman">else</span> - (* (1+ (/ height Y-axis-label-spacing)) - Y-axis-label-spacing))) -</pre><pre class="smallexample"> (vertical-step (or vertical-step 1)) - (full-Y-label-width - (length -</pre><pre class="smallexample"> (concat - (number-to-string - (* height-of-top-line vertical-step)) - Y-axis-tic)))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (print-Y-axis - height-of-top-line full-Y-label-width vertical-step) -</pre><pre class="smallexample"> (graph-body-print - numbers-list height-of-top-line symbol-width) - (print-X-axis numbers-list))) -</pre></div> - -<hr> -<a name="Testear-print_002dgraph"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#La-versi_00f3n-final" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Graficar-palabras-en-funciones" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Testeando-print_002dgraph"></a> -<h3 class="appendixsubsec">C.4.1 Testeando <code>print-graph</code></h3> - -<p>Se puede chequear la función <code>print-graph</code> con una lista -ordenada de números: -</p> -<ol> -<li> -Instala las versiones finales de <code>Y-axis-column</code>, -<code>graph-body-print</code>, y <code>print-graph</code> (además del resto del -código.) - -</li><li> -Copia la siguiente expresión: - -<div class="smallexample"> -<pre class="smallexample">(print-graph '(3 2 5 6 7 5 3 4 6 4 3 2 1)) -</pre></div> - -</li><li> -Cambia al búffer ‘<tt>*scratch*</tt>’ y emplaza el cursor donde se -quiere el eje etiquetado para empezar. - -</li><li> -Escribe <kbd>M-:</kbd> (<code>eval-expression</code>). - -</li><li> -Pegue la expresión de test dentro del minibuffer con <kbd>C-y</kbd> -(<code>yank</code>). - -</li><li> -Presiona <RET> para evaluar la expresión -</li></ol> - -<p>Emacs imprimirá un grafo que se parece a: -</p> -<div class="smallexample"> -<pre class="smallexample">10 - - - - * - ** * - 5 - **** * - **** *** - * ********* - ************ - 1 - ************* - - | | | | - 1 5 10 15 -</pre></div> - -<p>Por otro lado, si se pasa a <code>print-graph</code> un <code>vertical-step</code> -valor de 2, evaluando esta expresión: -</p> -<div class="smallexample"> -<pre class="smallexample">(print-graph '(3 2 5 6 7 5 3 4 6 4 3 2 1) 2) -</pre></div> - -<p>El grafo se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">20 - - - - * - ** * -10 - **** * - **** *** - * ********* - ************ - 2 - ************* - - | | | | - 1 5 10 15 -</pre></div> - -<p>(Una pregunta: ¿es el ‘2’ debajo del eje vertical un error o una -funcionalidad? Si se piensa que es un error, y sería un -‘1’, (o incluso un ‘0’), se pueden modificar las fuentes.) -</p> -<hr> -<a name="Graficar-palabras-en-funciones"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Testear-print_002dgraph" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#lambda" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Creando-graficas-de-numeros-de-palabras-y-simbolos"></a> -<h3 class="appendixsubsec">C.4.2 Creando gráficas de números de palabras y símbolos</h3> - -<p>Ahora para el gráfico para el que todo este código fué escrito: -un gráfico que muestra cuantas definiciones de función contienen -unas pocas 10 palabras y símbolos, cuantas contienen -entre 10 y 19 palabras y símbolos, cuantos contienen -entre 20 y 29 palabras y símbolos, y así. -</p> -<p>Esto es un proceso de múltiples pasos. Primero asegúrate que has -cargado todo el requisito del código. -</p> -<p>Eso es una buena idea para eliminar el valor de <code>top-of-ranges</code> -en caso de que has asignado a algún valor diferente. Se puede -evaluar lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq top-of-ranges - '(10 20 30 40 50 - 60 70 80 90 100 - 110 120 130 140 150 - 160 170 180 190 200 - 210 220 230 240 250 - 260 270 280 290 300) -</pre></div> - -<p>Lo siguiente crea una lista del número de palabras y -símbolos en cada rango. -</p> -<p>Evalúa lo siguiente: -</p> -<div class="smallexample"> -<pre class="smallexample">(setq list-for-graph - (defuns-per-range - (sort - (recursive-lengths-list-many-files - (directory-files "/usr/local/emacs/lisp" - t ".+el$")) - '<) - top-of-ranges)) -</pre></div> - -<p>En mi vieja máquina, esto lleva como una hora. Se parece a 303 -ficheros Lisp en mi copia de Emacs version 19.23. Después de toda -esta computación, el <code>list-for-graph</code> tenía este -valor: -</p> -<div class="smallexample"> -<pre class="smallexample">(537 1027 955 785 594 483 349 292 224 199 166 120 116 99 -90 80 67 48 52 45 41 33 28 26 25 20 12 28 11 13 220) -</pre></div> - -<p>Esto significa que mi copia de Emacs tiene 537 definiciones de -funciones con poco menos de 10 palabras o símbolos en -sí, 1027 definiciones de función con 10 a 19 palabras -o símbolos dentro, 955 definiciones de función con 20 -a 29 palabras o símbolos dentro, y así. -</p> -<p>Claramente, solo buscando esta lista se puede ver que la -mayoría de definiciones de función contienen de diez a -treinta palabras y símbolos. -</p> -<p>Ahora para imprimir. Nosotros <em>no</em> queremos imprimir un grafo que -es de 1030 líneas de alto …. En vez de eso, -imprimiría un grafo que es mejor que venticinco -líneas de alto. Un grafo cuya altura puede ser mostrada -en casi cualquier monitor, y fácilmente impreso en una hoja de papel. -</p> -<p>Esto significa que cada valor en <code>list-for-graph</code> debe ser -reducido a un quinceavo de su valor presente. -</p> -<p>Aquí hay una corta función para hacer esto, usando dos -funciones que no se han visto todavía, <code>mapcar</code> y -<code>lambda</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(defun one-fiftieth (full-range) - "Devuelve la lista, con el cincuenteavo de cada elemento." - (mapcar '(lambda (arg) (/ arg 50)) full-range)) -</pre></div> - -<hr> -<a name="lambda"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Graficar-palabras-en-funciones" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#mapcar" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Una-expresion-lambda_003a-Anonimicidad-util"></a> -<h3 class="appendixsubsec">C.4.3 Una expresión <code>lambda</code>: Anonimicidad útil</h3> -<a name="index-Funcion-Anonima"></a> -<a name="index-lambda"></a> - -<p><code>lambda</code> es el símbolo para una función -anónima, una función sin un nombre. Cada vez que se use una -función anónima, se necesita incluir su cuerpo completo. -</p> -<p>De este modo, -</p> -<div class="smallexample"> -<pre class="smallexample">(lambda (arg) (/ arg 50)) -</pre></div> - -<p>es una definición de función que dice ‘devuelve el valor -resultante de dividir cualquier cosa que es pasada como <code>arg</code> por -50’. -</p> -<p>Pronto, por ejemplo, se tenía una función -<code>multiply-by-seven</code>; se multiplica su argumento por 7. Esta -función es similar, excepto que divide su argumento por 50; y, no -tiene nombre. El equivalente anónimo de <code>multiply-by-seven</code> es: -</p> -<div class="smallexample"> -<pre class="smallexample">(lambda (number) (* 7 number)) -</pre></div> - -<p>(Véase la sección <a href="#defun">La forma especial <code>defun</code></a>.) -</p> -<p>Si queremos multiplicar 3 por 7, podemos escribir: -</p> -<div class="smallexample"> -<pre class="smallexample">(multiply-by-seven 3) - \_______________/ ^ - | | - función argumento -</pre></div> -<br> -<br> - -<p>Esta expresión devuelve 21. -</p> -<p>De manera similar, se puede escribir: -</p> -<div class="smallexample"> -<pre class="smallexample">((lambda (number) (* 7 number)) 3) - \____________________________/ ^ - | | - función anónima argumento -</pre></div> -<br> -<br> - -<p>Si queremos dividir 100 por 50, se puede escribir: -</p> -<div class="smallexample"> -<pre class="smallexample">((lambda (arg) (/ arg 50)) 100) - \______________________/ \_/ - | | - función anónima argumento -</pre></div> -<br> -<br> - -<p>Esta expresión devuelve 2. El 100 es pasado para la función, que -divide este número por 50. -</p> -<p>See <a href="elisp.html#Expresiones-Lambda">Expresiones Lambda</a> in <cite>El Manual de Referencia GNU Emacs Lisp</cite>, para más acerca de <code>lambda</code>. Lisp y -expresiones Lambda se derivan del Cálculo Lambda. -</p> -<hr> -<a name="mapcar"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#lambda" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Otro-Error" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="La-funcion-mapcar"></a> -<h3 class="appendixsubsec">C.4.4 La función <code>mapcar</code></h3> -<a name="index-mapcar"></a> - -<p><code>mapcar</code> es una función que llama a su primer argumento con -cada elemento de su segundo argumento. El segundo argumento debe ser -una secuencia. -</p> -<p>La parte ‘<samp>map</samp>’ del nombre viene de la frase matemática, -‘mapeando a través de un dominio’, significa hace apply a una -función a cada uno de los elementos en un dominio. La frase -matemática está basada en la metáfora de un superviviente -paseando, un paso en un momento, a través de un área él está -mapeando. Y ‘<samp>car</samp>’, de acuerdo, viene desde la noción Lisp del -primero de una lista. -</p> -<p>Por ejemplo, -</p> -<div class="smallexample"> -<pre class="smallexample">(mapcar '1+ '(2 4 6)) - ⇒ (3 5 7) -</pre></div> - -<p>La función <code>1+</code> añade uno a su argumento, es ejecutada en -<em>each</em> de la lista, y una nueva lista es devuelta. -</p> -<p>En contraste con esto <code>apply</code>, se aplica su primer argumento a todo -lo que permanece. (Véase la sección <a href="#Leyendo-un-grafo">Leyendo un grafo</a>, para -una explicación de <code>apply</code>.) -</p> -<p>En la definición de <code>one-fiftieth</code>, el primer argumento es la -función anónima: -</p> -<div class="smallexample"> -<pre class="smallexample">(lambda (arg) (/ arg 50)) -</pre></div> - -<p>y el segundo argumento es <code>full-range</code>, que será asociado para -<code>list-for-graph</code>. -</p> -<p>La expresión completa se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(mapcar (lambda (arg) (/ arg 50)) full-range)) -</pre></div> - -<p>See <a href="elisp.html#Funciones-de-Mapeo">Mapeando Funciones</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>, para más acerca de <code>mapcar</code>. -</p> -<p>Usando la función <code>one-fiftieth</code>, se puede generar una lista en -el que cada elemento es un cincuenteavo del tamaño del -correspondiente elemento en <code>list-for-graph</code>. -</p> -<div class="smallexample"> -<pre class="smallexample">(setq fiftieth-list-for-graph - (one-fiftieth list-for-graph)) -</pre></div> - -<p>La lista resultante se parece a esto: -</p> -<div class="smallexample"> -<pre class="smallexample">(10 20 19 15 11 9 6 5 4 3 3 2 2 -1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 4) -</pre></div> - -<p>Así, ¡ya estamos casi listos para imprimir! -(También se notifica la pérdida de información: muchos de los -rangos superiores son 0, esto significa que menos de 50 funciones -tenían muchas palabras o símbolos — pero -no necesariamente significando que niguna tenía muchas -palabras o símbolos.) -</p> -<hr> -<a name="Otro-Error"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#mapcar" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-impreso-final" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Otro-error-_2026-mas-insidioso"></a> -<h3 class="appendixsubsec">C.4.5 Otro error … más insidioso</h3> -<a name="index-Error_002c-del-tipo-mas-insidioso"></a> -<a name="index-Insidioso-tipo-de-error"></a> - -<p>¡Se dijo ‘casi listo para imprimir’! De acuerdo, hay un -error en la función <code>print-graph</code> …. Esta tiene una -opción <code>vertical-step</code>, pero no una opción -<code>horizontal-step</code>. La escala <code>top-of-range</code> va desde 10 a -300 por decenas. Pero la función <code>print-graph</code> imprimirá solo - uno por uno. -</p> -<p>Esto es un ejemplo clásico de lo que algunos consideramos el tipo -más insidioso de error, el error de omisión. Este no es el tipo de -error que se puede encontrar estudiando el código, para eso no es el -código; es una funcionalidad omitida. Tus mejores acciones son -probar tu programa pronto y con frecuencia; e intentar poner en orden, -tanto como se pueda, escribir código que sea fácil de comprender y -fácil de cambiar. Intenta ser consciente, siempre y cuando se pueda, -esto es siempre que tengas que escribir, <em>será</em> reescrito, si -no pronto, eventualmente. Un máximo duro de seguir. -</p> -<p>Esta es la función <code>print-X-axis-numbered-line</code> que necesita el -trabajo; y entonces el <code>print-X-axis</code> y la función -<code>print-graph</code> necesita ser adaptada. No se necesita mucho para -ser hecho; hay uno simpático: los números podrían -alinearse con marcas de tic. Esto toma un pequeño pensamiento. -</p> -<p>Aquí está el <code>print-X-axis-numbered-line</code> corregido: -</p> -<div class="smallexample"> -<pre class="smallexample">(defun print-X-axis-numbered-line - (number-of-X-tics X-axis-leading-spaces - &optional horizontal-step) - "Imprime la líneas de números X-axis" - (let ((number X-axis-label-spacing) - (horizontal-step (or horizontal-step 1))) -</pre><pre class="smallexample"> (insert X-axis-leading-spaces) - ;; <span class="roman">Elimina espacios extra de guía.</span> - (delete-char - (- (1- - (length (number-to-string horizontal-step))))) - (insert (concat - (make-string -</pre><pre class="smallexample"> ;; <span class="roman">Inserta espacio en blanco.</span> - (- (* symbol-width - X-axis-label-spacing) - (1- - (length - (number-to-string horizontal-step))) - 2) - ? ) - (number-to-string - (* number horizontal-step)))) -</pre><pre class="smallexample"> ;; <span class="roman">Insertar los números que permanecen.</span> - (setq number (+ number X-axis-label-spacing)) - (while (> number-of-X-tics 1) - (insert (X-axis-element - (* number horizontal-step))) - (setq number (+ number X-axis-label-spacing)) - (setq number-of-X-tics (1- number-of-X-tics))))) -</pre></div> - -<p>Si se está leyendo esto en Info, se pueden ver las nuevas versiones -<code>print-X-axis</code> y <code>print-graph</code> y los evaluarlas. Si se -está leyendo esto en un libro impreso, se pueden ver las -líneas cambiadas aquí (el texto completo -es mucho para imprimir). -</p> - -<div class="smallexample"> -<pre class="smallexample">(defun print-X-axis (numbers-list horizontal-step) - "Imprime etiquetas del eje X a la longitud de NUMBERS-LIST. -Opcionalmente, HORIZONTAL-STEP, un entero positivo, -especifica cuanto una etiqueta del eje X incrementa -cada columna." -</pre><pre class="smallexample">;; Valor del símbolo symbol-width and full-Y-label-width -;; se pasan por `print-graph'. - (let* ((leading-spaces - (make-string full-Y-label-width ? )) - ;; symbol-width <span class="roman">is provided by</span> graph-body-print - (tic-width (* symbol-width X-axis-label-spacing)) - (X-length (length numbers-list)) -</pre><pre class="smallexample"> (X-tic - (concat - (make-string - ;; <span class="roman">Crea una cadena de espacios en blanco.</span> - (- (* symbol-width X-axis-label-spacing) - (length X-axis-tic-symbol)) - ? ) -</pre><pre class="smallexample"> ;; <span class="roman">Concatena espacios en blanco con el - símbolo tic.</span> - X-axis-tic-symbol)) - (tic-number - (if (zerop (% X-length tic-width)) - (/ X-length tic-width) - (1+ (/ X-length tic-width))))) -</pre><pre class="smallexample"> -</pre><pre class="smallexample"> (print-X-axis-tic-line - tic-number leading-spaces X-tic) - (insert "\n") - (print-X-axis-numbered-line - tic-number leading-spaces horizontal-step))) -</pre></div> - -<div class="smallexample"> -<pre class="smallexample">(defun print-graph - (numbers-list &optional vertical-step horizontal-step) - "Imprime el gráfico de barras etiquetada de los NUMBERS-LIST. -Los numbers-list consisten en los valores del eje Y." -</pre><pre class="smallexample"> -</pre><pre class="smallexample">Opcionalmente, VERTICAL-STEP, un entero positivo, especifica cuanto un -eje Y se incrementa por cada línea. Por ejemplo, un paso -de 5 significa que cada fila es de cinco unidades. -</pre><pre class="smallexample"> -</pre><pre class="smallexample">Opcionalmente, HORIZONTAL-STEP, un entero positivo, -especifica cuanto se incrementa en un eje X cada columna." - (let* ((symbol-width (length graph-blank)) - ;; <code>height</code> <span class="roman">es ambos el número más largo</span> - ;; <span class="roman">y el número con la mayoría de los dígitos.</span> - (height (apply 'max numbers-list)) -</pre><pre class="smallexample"> (height-of-top-line - (if (zerop (% height Y-axis-label-spacing)) - height - ;; <span class="roman">else</span> - (* (1+ (/ height Y-axis-label-spacing)) - Y-axis-label-spacing))) -</pre><pre class="smallexample"> (vertical-step (or vertical-step 1)) - (full-Y-label-width - (length - (concat - (number-to-string - (* height-of-top-line vertical-step)) - Y-axis-tic)))) -</pre><pre class="smallexample"> (print-Y-axis - height-of-top-line full-Y-label-width vertical-step) - (graph-body-print - numbers-list height-of-top-line symbol-width) - (print-X-axis numbers-list horizontal-step))) -</pre></div> - - - -<hr> -<a name="Grafo-impreso-final"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Otro-Error" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Imprimir-Grafo-Entero" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="El-grafico-impreso"></a> -<h3 class="appendixsubsec">C.4.6 El gráfico impreso</h3> - -<p>Cuando esté hecho e instalado, se puede llamar al comando -<code>print-graph</code> como esto: -</p><br> - -<div class="smallexample"> -<pre class="smallexample">(print-graph fiftieth-list-for-graph 50 10) -</pre></div> -<br> - -<p>Aquí está el gráfico: -</p><br> -<br> - -<div class="smallexample"> -<pre class="smallexample">1000 - * - ** - ** - ** - ** - 750 - *** - *** - *** - *** - **** - 500 - ***** - ****** - ****** - ****** - ******* - 250 - ******** - ********* * - *********** * - ************* * - 50 - ***************** * * - | | | | | | | | - 10 50 100 150 200 250 300 350 -</pre></div> - -<br> -<br> - -<p>El grupo largo de funciones contienen de 10 a 19 palabras y -símbolos. -</p> -<hr> -<a name="Software-Libre-y-Manuales-Libres"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Grafo-completo" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Grafo-impreso-final" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#GNU-Free-Documentation-License" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#GNU-Free-Documentation-License" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Software-Libre-y-Manuales-Libres-1"></a> -<h1 class="appendix">Appendix D Software Libre y Manuales Libres</h1> - -<p><strong>por Richard M. Stallman</strong> -</p><br> - -<p>La mayor deficiencia en sistemas operativos libres no está en el -software — es la falta de buenos manuales libres que se puedan -incluir en estos sistemas. Muchos de nuestros programas más -importantes no vienen con manuales completos. La documentación es -una parte esencial de cualquier paquete de software; cuando un paquete -de software libre no viene con un manual libre, es una brecha -mayor. Nosotros tenemos muchas brechas hoy. -</p> -<p>Érase una vez, hace muchos años, se piensa que -aprendería Perl. Se tiene una copia de un manual libre, -pero se encontró difícil de leer. Cuando pregunto a -los usuarios de Perl acerca de alternativas, me contaron que -serían mejor los manuales introductorios — pero estos -no eran libres. -</p> -<p>¿Por qué era esto? Los autores de los buenos manuales -los habían escrito para O’Reilly Associates, que los -publicaron con términos restrictivos — no copiando, no -modificando, los ficheros fuentes están disponibles — que los -excluyen desde la comunidad de software libre. -</p> -<p>No era la primera vez que esto ocurría, y (para -nuestra comunidad es una gran pérdida) eso está lejos desde el -último. Las editoriales de manuales privativos han logrado que -muchos autores restrinjan sus manuales desde entonces. Muchas veces se -ha oido que un usuario de GNU hábil me cuente que un manual que -está escribiendo, con el que él espera ayudar al proyecto GNU — -y entonces tenía mis esperanzas frustradas, como se ha -procedió a explicar que él tenía que haber firmado -un contrato con una editorial que restringiría eso, -así que no puede usarlo. -</p> -<p>Debido a que escribir buen inglés es una habilidad rara entre -programadores, se pueden perder manuales por este motivo. -</p> -<p>La documentación, como el software, es una cuestión de libertad, -no de precio. El problema con estos manuales no eran que O’Reilly -Associates impusiera un precio por las copias impresas — que en -sí estaban bien. La Free Software Foundation -<em>Fundación por el Software Libre</em> <a href="http://shop.fsf.org">vende copias impresas</a> de <a href="http://www.gnu.org/doc/doc.html">manuales libres de GNU</a>, también. Pero los manuales de GNU están -disponibles en forma de código fuente, mientras que estos manuales -están disponibles solo en papel. Los manuales de GNU vienen con -permiso para copiar y modificar; los manuales de Perl no. Estas -restricciones son un problema. -</p> -<p>El criterio para un manual libre es parecido al del software libre: es -una cuestión de dar a todos los usuarios ciertas libertades. La -redistribución (incluyendo redistribución comercial) debe ser -permitida, así el manual puede acompañar cada copia -del programa, en líne o en papel. El permiso para modificar -es crucial también. -</p> -<p>Como regla general, no se cree que sea esencial para la gente tener -permisos para modificar todas las partes de artículos y -libro. Las cuestiones para escritos no son necesariamente las mismas -como estas para el software. Por ejemplo, no se sabe si se está -obligado a dar permisos para modificar artículos como -este, que describen nuestras acciones y nuestras vistas. -</p> -<p>Pero hay una razón particular de por qué la libertad de modificar -es crucial para la documentación de software libre. Cuando las -personas ejercita su derecho a modificar el software, y añadir o -cambiar sus funcionalidades, si son consciente ellos cambiarán el -manual también — así se puede proveer -documentación usable y cuidada con el programa modificado. Un manual -que prohibe a los programadores ser consciente y finalizar el trabajo, -o más precisamente requiere escribir un nuevo manual desde cero si -ellos cambian el programa, no se ajusta a las necesidades de nuestra -comunidad. -</p> -<p>Mientras una serie de prohibiciones en la modificación es -inaceptable, algunos tipos de límites en el método de -modificar no tiene tanto problema. Por ejemplo, los requisitos para -preservar la noticia de autores del copyright, los términos de -distribución, o la lista de autores, estén ok. Eso es también no -da problemas para requerir versiones modificadas para incluir -notificar que fueron modificadas, incluso tienen secciones enteras que -puede no ser eliminadas o cambiadas, tan largo como estas secciones -tratan con asuntos no técnicos. (Algunos manuales de GNU los tienen). -</p> -<p>Estos tipos de restricciones no son un problema porque, como materia -práctica, no para al programador consciente desde la adaptación -del manual para ajustar el programa modificado. En otras palabras, no -se bloquea la comunidad del software libre haciendo el uso completo -del manual. -</p> -<p>Sin embargo, debe ser posible modificar todo el contenido técnico -del manual, y entonces se distribuye el resultado en todos los medios -usuales, a través de todos los canales usuales; de otro modo, las -restricciones bloquean la comunidad, el manual no es libre, y -así no se necesita otro manual. -</p> -<p>Desafortunadamente, con frecuencia es duro encontrar a alguien a -escribir otro manual cuando un manual privativo. El obstáculo es que -muchos usuario piensan que un manual privativo es suficientemente -bueno — así ellos no ven la necesidad de escribir un -manual libre. Ellos no ven que el sistema operativo tiene un gazapo -que necesita se rellenado. -</p> -<p>¿Por qué los usuarios piensan que los manuales -privativos son suficientemente buenos? Algunos no han considerado la -cuestión. Espero que este artículo hará alguna cosa -para cambiar esto. -</p> -<p>Otros usuarios considera manuales privativos aceptables para la misma -razón así muchas personas software privativo -aceptable: ellos judgan en términos puramente prácticos, no usando -la liberta como un criterio. Estas personas son tituladas a sus -opiniones, pero desde que estas opciones crezcan desde valores que no -incluyen libertad, ellas no están guiadas por esto quienes valoran -la libertad. -</p> -<p>Por favor, populariza esta cuestión. Se continúa a perder manuales -para publicación privativa. Si se populariza que los manuales -privativos no son suficientes, quizás la siguiente persona que -quiere ayudar a GNU escribiendo documentación realizará, antes de -que sea demasiado tarde, lo que él debe que todo sea libre. -</p> -<p>Se puede también animar editoriales comerciales a vender manuales -libres o con copyleft en vez de uno privativo. Un camino que se puede -ayudar esto chequea los términos de la distribución de un manual -antes de que se compre, y preferimos manuales copyleft a los no copyleft. -</p> -<br> -<br> -<p>Note: La Fundación para el Software Libre mantiene una página en -su sitio Web que liste libros libres disponibles desde otras -editoriales:<br> <a href="http://www.gnu.org/doc/other-free-books.html">http://www.gnu.org/doc/other-free-books.html</a> -</p> -<hr> -<a name="GNU-Free-Documentation-License"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#Software-Libre-y-Manuales-Libres" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="GNU-Free-Documentation-License-1"></a> -<h1 class="appendix">Appendix E GNU Free Documentation License</h1> - -<a name="index-FDL_002c-GNU-Free-Documentation-License"></a> -<p align="center">Version 1.3, 3 November 2008 -</p> - -<div class="display"> -<pre class="display">Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. -<a href="http://fsf.org/">http://fsf.org/</a> - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -</pre></div> - -<ol> -<li> -PREAMBLE - -<p>The purpose of this License is to make a manual, textbook, or other -functional and useful document <em>free</em> in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. -</p> -<p>This License is a kind of “copyleft”, which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. -</p> -<p>We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. -</p> -</li><li> -APPLICABILITY AND DEFINITIONS - -<p>This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The “Document”, below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as “you”. You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. -</p> -<p>A “Modified Version” of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. -</p> -<p>A “Secondary Section” is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document’s overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. -</p> -<p>The “Invariant Sections” are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. -</p> -<p>The “Cover Texts” are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. -</p> -<p>A “Transparent” copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not “Transparent” is called “Opaque”. -</p> -<p>Examples of suitable formats for Transparent copies include plain -<small>ASCII</small> without markup, Texinfo input format, LaTeX input -format, <acronym>SGML</acronym> or <acronym>XML</acronym> using a publicly available -<acronym>DTD</acronym>, and standard-conforming simple <acronym>HTML</acronym>, -PostScript or <acronym>PDF</acronym> designed for human modification. Examples -of transparent image formats include <acronym>PNG</acronym>, <acronym>XCF</acronym> and -<acronym>JPG</acronym>. Opaque formats include proprietary formats that can be -read and edited only by proprietary word processors, <acronym>SGML</acronym> or -<acronym>XML</acronym> for which the <acronym>DTD</acronym> and/or processing tools are -not generally available, and the machine-generated <acronym>HTML</acronym>, -PostScript or <acronym>PDF</acronym> produced by some word processors for -output purposes only. -</p> -<p>The “Title Page” means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, “Title Page” means -the text near the most prominent appearance of the work’s title, -preceding the beginning of the body of the text. -</p> -<p>The “publisher” means any person or entity that distributes copies -of the Document to the public. -</p> -<p>A section “Entitled XYZ” means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as “Acknowledgements”, -“Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” -of such a section when you modify the Document means that it remains a -section “Entitled XYZ” according to this definition. -</p> -<p>The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. -</p> -</li><li> -VERBATIM COPYING - -<p>You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. -</p> -<p>You may also lend copies, under the same conditions stated above, and -you may publicly display copies. -</p> -</li><li> -COPYING IN QUANTITY - -<p>If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document’s license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. -</p> -<p>If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. -</p> -<p>If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. -</p> -<p>It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. -</p> -</li><li> -MODIFICATIONS - -<p>You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: -</p> -<ol> -<li> -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -</li><li> -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has fewer than five), -unless they release you from this requirement. - -</li><li> -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -</li><li> -Preserve all the copyright notices of the Document. - -</li><li> -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -</li><li> -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -</li><li> -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document’s license notice. - -</li><li> -Include an unaltered copy of this License. - -</li><li> -Preserve the section Entitled “History”, Preserve its Title, and add -to it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section Entitled “History” in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -</li><li> -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the “History” section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -</li><li> -For any section Entitled “Acknowledgements” or “Dedications”, Preserve -the Title of the section, and preserve in the section all the -substance and tone of each of the contributor acknowledgements and/or -dedications given therein. - -</li><li> -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -</li><li> -Delete any section Entitled “Endorsements”. Such a section -may not be included in the Modified Version. - -</li><li> -Do not retitle any existing section to be Entitled “Endorsements” or -to conflict in title with any Invariant Section. - -</li><li> -Preserve any Warranty Disclaimers. -</li></ol> - -<p>If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version’s license notice. -These titles must be distinct from any other section titles. -</p> -<p>You may add a section Entitled “Endorsements”, provided it contains -nothing but endorsements of your Modified Version by various -parties—for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. -</p> -<p>You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. -</p> -<p>The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. -</p> -</li><li> -COMBINING DOCUMENTS - -<p>You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. -</p> -<p>The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. -</p> -<p>In the combination, you must combine any sections Entitled “History” -in the various original documents, forming one section Entitled -“History”; likewise combine any sections Entitled “Acknowledgements”, -and any sections Entitled “Dedications”. You must delete all -sections Entitled “Endorsements.” -</p> -</li><li> -COLLECTIONS OF DOCUMENTS - -<p>You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. -</p> -<p>You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. -</p> -</li><li> -AGGREGATION WITH INDEPENDENT WORKS - -<p>A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an “aggregate” if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation’s users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. -</p> -<p>If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document’s Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. -</p> -</li><li> -TRANSLATION - -<p>Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. -</p> -<p>If a section in the Document is Entitled “Acknowledgements”, -“Dedications”, or “History”, the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. -</p> -</li><li> -TERMINATION - -<p>You may not copy, modify, sublicense, or distribute the Document -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, or distribute it is void, and -will automatically terminate your rights under this License. -</p> -<p>However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. -</p> -<p>Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. -</p> -<p>Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, receipt of a copy of some or all of the same material does -not give you any rights to use it. -</p> -</li><li> -FUTURE REVISIONS OF THIS LICENSE - -<p>The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -<a href="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</a>. -</p> -<p>Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License “or any later version” applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. If the Document -specifies that a proxy can decide which future versions of this -License can be used, that proxy’s public statement of acceptance of a -version permanently authorizes you to choose that version for the -Document. -</p> -</li><li> -RELICENSING - -<p>“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any -World Wide Web server that publishes copyrightable works and also -provides prominent facilities for anybody to edit those works. A -public wiki that anybody can edit is an example of such a server. A -“Massive Multiauthor Collaboration” (or “MMC”) contained in the -site means any set of copyrightable works thus published on the MMC -site. -</p> -<p>“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 -license published by Creative Commons Corporation, a not-for-profit -corporation with a principal place of business in San Francisco, -California, as well as future copyleft versions of that license -published by that same organization. -</p> -<p>“Incorporate” means to publish or republish a Document, in whole or -in part, as part of another Document. -</p> -<p>An MMC is “eligible for relicensing” if it is licensed under this -License, and if all works that were first published under this License -somewhere other than this MMC, and subsequently incorporated in whole -or in part into the MMC, (1) had no cover texts or invariant sections, -and (2) were thus incorporated prior to November 1, 2008. -</p> -<p>The operator of an MMC Site may republish an MMC contained in the site -under CC-BY-SA on the same site at any time before August 1, 2009, -provided the MMC is eligible for relicensing. -</p> -</li></ol> - - -<a name="ADDENDUM_003a-How-to-use-this-License-for-your-documents"></a> -<h2 class="heading">ADDENDUM: How to use this License for your documents</h2> - -<p>To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: -</p> -<div class="smallexample"> -<pre class="smallexample"> Copyright (C) <var>year</var> <var>your name</var>. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.3 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -</pre></div> - -<p>If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the “with…Texts.” line with this: -</p> -<div class="smallexample"> -<pre class="smallexample"> with the Invariant Sections being <var>list their titles</var>, with - the Front-Cover Texts being <var>list</var>, and with the Back-Cover Texts - being <var>list</var>. -</pre></div> - -<p>If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. -</p> -<p>If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. -</p> - - - - -<hr> -<a name="g_t_00cdndice"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#GNU-Free-Documentation-License" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#GNU-Free-Documentation-License" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[<a href="#Acerca-del-Autor" title="Sección siguiente en orden de lectura"> > </a>]</td> -<td valign="middle" align="left">[<a href="#Acerca-del-Autor" title="Capítulo siguiente"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Indice"></a> -<h1 class="unnumbered">Índice</h1> - - -<table><tr><th valign="top">Saltar a: </th><td><a class="summary-letter" href="#Indice_cp_symbol-1"><b>%</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-2"><b>(</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-3"><b>*</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-4"><b>/</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-5"><b><</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-6"><b>></b></a> - -<br> -<a class="summary-letter" href="#Indice_cp_letter-A"><b>A</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-B"><b>B</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-C"><b>C</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-D"><b>D</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-E"><b>E</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-F"><b>F</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-G"><b>G</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-H"><b>H</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-I"><b>I</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-K"><b>K</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-L"><b>L</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-M"><b>M</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-N"><b>N</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-O"><b>O</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-P"><b>P</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-R"><b>R</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-S"><b>S</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-T"><b>T</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-V"><b>V</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-W"><b>W</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-X"><b>X</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-Y"><b>Y</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-Z"><b>Z</b></a> - -</td></tr></table> -<table class="index-cp" border="0"> -<tr><td></td><th align="left">Entrada de índice</th><td> </td><th align="left"> Sección</th></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_symbol-1">%</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-_0025-_0028funcion-resto_0029"><code>% <span class="roman">(función resto)</span></code></a></td><td> </td><td valign="top"><a href="#Calcular-un-resto">C.2.1 Viaje lateral: Calcula un resto</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_symbol-2">(</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-_0028debug_0029-en-codigo"><code>(debug)</code> en código</a></td><td> </td><td valign="top"><a href="#debug_002don_002dquit">17.3 <code>debug-on-quit</code> y <code>(debug)</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_symbol-3">*</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-_002a-_0028multiplicacion_0029"><code>* <span class="roman">(multiplicación)</span></code></a></td><td> </td><td valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-_002a-para-buffer-solo-lectura"><code>* <span class="roman">para buffer solo lectura</span></code></a></td><td> </td><td valign="top"><a href="#B_00faffer-solo-lectura">Un búffer de solo lectura</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-_002ascratch_002a-buffer">‘<tt>*scratch*</tt>’ buffer</a></td><td> </td><td valign="top"><a href="#print_002delements_002dof_002dlist">11.1.2 Un ejemplo: <code>imprimir-elementos-de-la-lista</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_symbol-4">/</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-_002f-_0028division_0029"><code>/ <span class="roman">(division)</span></code></a></td><td> </td><td valign="top"><a href="#El-caso-del-buffer-largo">Qué ocurre en un búffer largo</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_symbol-5"><</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-_003c_003d-_0028menos-que-igual_0029"><code><= <span class="roman">(menos que igual)</span></code></a></td><td> </td><td valign="top"><a href="#Partes-Inc-de-Ejemplo">Las partes de la definición de función</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_symbol-6">></a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-_003e-_0028mayor-que_0029"><code>> (mayor que)</code></a></td><td> </td><td valign="top"><a href="#if-en-m_00e1s-detalle"><code>if</code> en más detalle</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-A">A</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Atomos-Lisp">Átomos Lisp</a></td><td> </td><td valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Acumular_002c-tipo-de-patron-recursivo">Acumular, tipo de patrón recursivo</a></td><td> </td><td valign="top"><a href="#Acumular">Patrón recursivo: <em>accumulate</em></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-add_002dhook"><code>add-hook</code></a></td><td> </td><td valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Alias-de-correo">Alias de correo</a></td><td> </td><td valign="top"><a href="#Alias-de-correo">16.5 Alias de correo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Almacenando-y-cortando-texto">Almacenando y cortando texto</a></td><td> </td><td valign="top"><a href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Ampliando">Ampliando</a></td><td> </td><td valign="top"><a href="#Encogiendo-y-extendiendo">6 Encogiendo y extendiendo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-and"><code>and</code></a></td><td> </td><td valign="top"><a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-and-1"><code>and</code></a></td><td> </td><td valign="top"><a href="#fwd_002dpara-let">La expresión <code>let*</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Anillo_002c-creando-un-lista-como-un">Anillo, creando un lista como un</a></td><td> </td><td valign="top"><a href="#Kill-Ring">Appendix B Manejando el anillo de la muerte</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-append_002dto_002dbuffer"><code>append-to-buffer</code></a></td><td> </td><td valign="top"><a href="#append_002dto_002dbuffer">4.4 La definición de <code>append-to-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-apply"><code>apply</code></a></td><td> </td><td valign="top"><a href="#Columnas-de-un-grafo">Imprimiendo las columnas de un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-apropos"><code>apropos</code></a></td><td> </td><td valign="top"><a href="#Columnas-de-un-grafo">Imprimiendo las columnas de un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Argumento-como-variable-local">Argumento como variable local</a></td><td> </td><td valign="top"><a href="#Ejemplo-Dec-junto">Poniendo la definición de la función junta</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-argumento-definido">‘<samp>argumento</samp>’ definido</a></td><td> </td><td valign="top"><a href="#Argumentos">1.8 Argumentos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Argumento_002c-tipo-incorrecto-de">Argumento, tipo incorrecto de</a></td><td> </td><td valign="top"><a href="#Tipo-incorrecto-de-argumento">1.8.4 Usando el tipo incorrecto de objeto como un argumento</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Argumentos">Argumentos</a></td><td> </td><td valign="top"><a href="#Argumentos">1.8 Argumentos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Argumentos-Opcionales">Argumentos Opcionales</a></td><td> </td><td valign="top"><a href="#Argumentos-opcionales">5.3.1 Argumentos opcionales</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Argumentos_002c-numero-variable-de">Argumentos, número variable de</a></td><td> </td><td valign="top"><a href="#N_00famero-de-variables-de-argumentos">1.8.3 Número de variables de argumentos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Asignando-tecla-globalmente">Asignando tecla globalmente</a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Asignando-valor-de-variable">Asignando valor de variable</a></td><td> </td><td valign="top"><a href="#set-y-setq">1.9 Configurando el valor de una variable</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Asignar-tecla-global">Asignar tecla global</a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Asociaciones_002c-teclas_002c-arreglando">Asociaciones, teclas, arreglando</a></td><td> </td><td valign="top"><a href="#Arreglando-Atajos-de-Teclados">Arreglando Atajos de Teclados</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Asterisco-para-buffer-de-solo-lectura">Asterisco para búffer de solo lectura</a></td><td> </td><td valign="top"><a href="#B_00faffer-solo-lectura">Un búffer de solo lectura</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Atajos-de-Teclado_002c-arreglando">Atajos de Teclado, arreglando</a></td><td> </td><td valign="top"><a href="#Arreglando-Atajos-de-Teclados">Arreglando Atajos de Teclados</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-autoload"><code>autoload</code></a></td><td> </td><td valign="top"><a href="#Autocarga">16.10 Autoloading</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Ayuda-escribiendo-listas">Ayuda escribiendo listas</a></td><td> </td><td valign="top"><a href="#Escribiendo-listas">1.1.3 GNU Emacs te ayuda a escribir listas</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-B">B</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-beginning_002dof_002dbuffer"><code>beginning-of-buffer</code></a></td><td> </td><td valign="top"><a href="#beginning_002dof_002dbuffer">5.3 Definición completa de <code>beginning-of-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-bind-se-definio">‘<samp>bind</samp>’ se definió</a></td><td> </td><td valign="top"><a href="#set-y-setq">1.9 Configurando el valor de una variable</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Borrando-texto">Borrando texto</a></td><td> </td><td valign="top"><a href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Borrando-texto-1">Borrando texto</a></td><td> </td><td valign="top"><a href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Buffer-solo-lectura">Búffer solo lectura</a></td><td> </td><td valign="top"><a href="#B_00faffer-solo-lectura">Un búffer de solo lectura</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Busquedas-de-expresiones-regulares">Búsquedas de expresiones regulares</a></td><td> </td><td valign="top"><a href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Busquedas_002c-ilustrando">Búsquedas, ilustrando</a></td><td> </td><td valign="top"><a href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Bucles">Bucles</a></td><td> </td><td valign="top"><a href="#while">11.1 <code>while</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Bucles-y-recursion">Bucles y recursión</a></td><td> </td><td valign="top"><a href="#Bucles-y-recursi_00f3n">11 Bucles y recursión</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Buffer_002c-historia-de-palabra">Buffer, historia de palabra</a></td><td> </td><td valign="top"><a href="#Nombres-de-b_00faffer">2.1 Nombres de búffer</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-buffer_002dfile_002dname"><code>buffer-file-name</code></a></td><td> </td><td valign="top"><a href="#Nombres-de-b_00faffer">2.1 Nombres de búffer</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-buffer_002dmenu_002c-asociado-a-tecla"><code>buffer-menu, <span class="roman">asociado a tecla</span></code></a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-buffer_002dname"><code>buffer-name</code></a></td><td> </td><td valign="top"><a href="#Nombres-de-b_00faffer">2.1 Nombres de búffer</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-C">C</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-C_002c-una-disgresion-dentro">C, una disgresión dentro</a></td><td> </td><td valign="top"><a href="#Disgresi_00f3n-dentro-de-C">8.4 Disgresión dentro de C</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-cadena-definida">‘<samp>cadena</samp>’ definida</a></td><td> </td><td valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-cadena-vacia-definida">‘<samp>cadena vacía</samp>’ definida</a></td><td> </td><td valign="top"><a href="#Revisar">3.11 Revisar</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Caja-con-cajones_002c-metafora-para-su-simbolo">Caja con cajones, metáfora para su símbolo</a></td><td> </td><td valign="top"><a href="#S_00edmbolos-como-cajas">9.1 Símbolos como una caja con cajones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cajones_002c-Caja-de_002c-metafora-para-un-simbolo">Cajones, Caja de, metáfora para un símbolo</a></td><td> </td><td valign="top"><a href="#S_00edmbolos-como-cajas">9.1 Símbolos como una caja con cajones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cambiando-a-un-buffer">Cambiando a un búffer</a></td><td> </td><td valign="top"><a href="#Cambiando-b_00faffers">2.3 Cambiando búffers</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cambiando-una-definicion-de-funcion">Cambiando una definición de función</a></td><td> </td><td valign="top"><a href="#Cambiar-un-defun">3.2.1 Cambiar una definición de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-cancel_002ddebug_002don_002dentry"><code>cancel-debug-on-entry</code></a></td><td> </td><td valign="top"><a href="#debug_002don_002dentry">17.2 <code>debug-on-entry</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-car_002c-introducido"><code>car, <span class="roman">introducido</span></code></a></td><td> </td><td valign="top"><a href="#Car-cdr-y-cons">7 <code>car</code>, <code>cdr</code>, <code>cons</code>: Funciones fundamentales</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cargando-ficheros">Cargando ficheros</a></td><td> </td><td valign="top"><a href="#Cargando-ficheros">16.9 Cargando ficheros</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Categorias-de-sintaxis-y-tablas">Categorías de sintaxis y tablas</a></td><td> </td><td valign="top"><a href="#Sintaxis">14.2 ¿Qué constituye una palabra o símbolo?</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-cdr_002c-introducido"><code>cdr, <span class="roman">introducido</span></code></a></td><td> </td><td valign="top"><a href="#Car-cdr-y-cons">7 <code>car</code>, <code>cdr</code>, <code>cons</code>: Funciones fundamentales</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Codigo-de-instalacion">Código de instalación</a></td><td> </td><td valign="top"><a href="#Instalaci_00f3n-Permanente">3.5 Instalar código permanentemente</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Codigo-Permanente-de-Instalacion">Código Permanente de Instalación</a></td><td> </td><td valign="top"><a href="#Instalaci_00f3n-Permanente">3.5 Instalar código permanentemente</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-comando-definido">‘<samp>comando</samp>’ definido</a></td><td> </td><td valign="top"><a href="#C_00f3mo-evaluar">Cómo evaluar</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Comentarios-en-Codigo-Lisp">Comentarios en Código Lisp</a></td><td> </td><td valign="top"><a href="#Cambiar-un-defun">3.2.1 Cambiar una definición de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Common-Lisp">Common Lisp</a></td><td> </td><td valign="top"><a href="#Historia-de-Lisp">Historia de Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-compare_002dwindows"><code>compare-windows</code></a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Compilando-Byte">Compilando Byte</a></td><td> </td><td valign="top"><a href="#Compilaci_00f3n-de-bytes">1.5.1 Compilación de bytes</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-concatenar"><code>concatenar</code></a></td><td> </td><td valign="top"><a href="#Tipos-de-datos">1.8.1 Tipos de argumentos de datos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-cond"><code>cond</code></a></td><td> </td><td valign="top"><a href="#Recursi_00f3n-con-cond">11.3.5 Ejemplo de recursión usando <code>cond</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Condicional-con-if">Condicional con <code>if</code></a></td><td> </td><td valign="top"><a href="#if">3.7 La forma especial <code>if</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Condicional-marcaran-estas-dos-versiones-de-Emacs">Condicional marcarán estas dos versiones de Emacs</a></td><td> </td><td valign="top"><a href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-condition_002dcase"><code>condition-case</code></a></td><td> </td><td valign="top"><a href="#condition_002dcase">8.2.1 <code>condition-case</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Configurando-una-tecla-globalmente">Configurando una tecla globalmente</a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-cons_002c-introducido"><code>cons, <span class="roman">introducido</span></code></a></td><td> </td><td valign="top"><a href="#cons">7.2 <code>cons</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Construyendo-Etiquetas-en-las-fuentes-Emacs">Construyendo Etiquetas en las fuentes Emacs</a></td><td> </td><td valign="top"><a href="#Construyendo-Etiquetas-en-las-fuentes-Emacs">Construyendo Etiquetas en las fuentes Emacs</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Construyendo-robots">Construyendo robots</a></td><td> </td><td valign="top"><a href="#Construyendo-robots">11.3.1 Construyendo robots: Extendiendo la metáfora</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Contando">Contando</a></td><td> </td><td valign="top"><a href="#Contando">1.9.3 Contando</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Contando-las-palabras-en-un-defun">Contando las palabras en un <code>defun</code></a></td><td> </td><td valign="top"><a href="#Palabras-en-una-funci_00f3n">14 Contando palabras en una <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Contando-palabras-en-un-defun">Contando palabras en un <code>defun</code></a></td><td> </td><td valign="top"><a href="#Palabras-en-una-funci_00f3n">14 Contando palabras en una <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Contando-palabras-en-un-defun-1">Contando palabras en un <code>defun</code></a></td><td> </td><td valign="top"><a href="#count_002dwords_002din_002ddefun">14.3 La función <code>count-words-in-defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Convencion-formateando">Convención formateando</a></td><td> </td><td valign="top"><a href="#append-save_002dexcursion">4.4.3 <code>save-excursion</code> en <code>append-to-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Copiando-texto">Copiando texto</a></td><td> </td><td valign="top"><a href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-copy_002dregion_002das_002dkill"><code>copy-region-as-kill</code></a></td><td> </td><td valign="top"><a href="#copy_002dregion_002das_002dkill">8.3 <code>copy-region-as-kill</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-copy_002dto_002dbuffer"><code>copy-to-buffer</code></a></td><td> </td><td valign="top"><a href="#copy_002dto_002dbuffer">5.1 La definición de <code>copy-to-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cortando-texto">Cortando texto</a></td><td> </td><td valign="top"><a href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cortando-y-almacenando-texto">Cortando y almacenando texto</a></td><td> </td><td valign="top"><a href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-count_002dwords_002dexample"><code>count-words-example</code></a></td><td> </td><td valign="top"><a href="#count_002dwords_002dexample">13.1 La función <code>count-words-example</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-count_002dwords_002din_002ddefun"><code>count-words-in-defun</code></a></td><td> </td><td valign="top"><a href="#count_002dwords_002din_002ddefun">14.3 La función <code>count-words-in-defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-crear-etiquetas"><code>crear etiquetas</code></a></td><td> </td><td valign="top"><a href="#Construyendo-Etiquetas-en-las-fuentes-Emacs">Construyendo Etiquetas en las fuentes Emacs</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cuenta-palabras-recursivamente">Cuenta palabras recursivamente</a></td><td> </td><td valign="top"><a href="#recursive_002dcount_002dwords">13.2 Cuenta palabras recursivamente</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Cuerpo-de-grafo">Cuerpo de grafo</a></td><td> </td><td valign="top"><a href="#Leyendo-un-grafo">15 Leyendo un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-cuerpo-definido">‘<samp>cuerpo</samp>’ definido</a></td><td> </td><td valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-current_002dbuffer"><code>current-buffer</code></a></td><td> </td><td valign="top"><a href="#Obteniendo-b_00faffers">2.2 Obteniendo búffers</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-current_002dkill"><code>current-kill</code></a></td><td> </td><td valign="top"><a href="#current_002dkill">B.1 La función <code>current-kill</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-D">D</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-debug_002don_002dentry"><code>debug-on-entry</code></a></td><td> </td><td valign="top"><a href="#debug_002don_002dentry">17.2 <code>debug-on-entry</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-debug_002don_002dquit"><code>debug-on-quit</code></a></td><td> </td><td valign="top"><a href="#debug_002don_002dquit">17.3 <code>debug-on-quit</code> y <code>(debug)</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-defconst"><code>defconst</code></a></td><td> </td><td valign="top"><a href="#defcustom">16.2 Especificar variables usando <code>defcustom</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-defcustom"><code>defcustom</code></a></td><td> </td><td valign="top"><a href="#defcustom">16.2 Especificar variables usando <code>defcustom</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Definicion-de-Funcion_002c-como-cambiar">Definición de Función, como cambiar</a></td><td> </td><td valign="top"><a href="#Cambiar-un-defun">3.2.1 Cambiar una definición de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Definicion-de-la-instalacion">Definición de la instalación</a></td><td> </td><td valign="top"><a href="#Instalar">3.2 Instalar una definición de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Definicion-de-la-Instalacion-de-Funcion">Definición de la Instalación de Función</a></td><td> </td><td valign="top"><a href="#Instalar">3.2 Instalar una definición de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-definicion-de-punto">definición de ‘<samp>punto</samp>’</a></td><td> </td><td valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-definicion-funcion-definida">‘<samp>definición función</samp>’ definida</a></td><td> </td><td valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Definicion_002c-como-cambiar">Definición, cómo cambiar</a></td><td> </td><td valign="top"><a href="#Cambiar-un-defun">3.2.1 Cambiar una definición de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-defsubst"><code>defsubst</code></a></td><td> </td><td valign="top"><a href="#defcustom">16.2 Especificar variables usando <code>defcustom</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-defun"><code>defun</code></a></td><td> </td><td valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-defvar"><code>defvar</code></a></td><td> </td><td valign="top"><a href="#defvar">8.5 Inicializando una variable con <code>defvar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-defvar-con-un-asterisco"><code>defvar <span class="roman">con un asterisco</span></code></a></td><td> </td><td valign="top"><a href="#defvar-y-asterisk">8.5.1 <code>defvar</code> y un asterisco</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-defvar-para-una-variable-personalizable"><code>defvar <span class="roman">para una variable personalizable</span></code></a></td><td> </td><td valign="top"><a href="#defvar-y-asterisk">8.5.1 <code>defvar</code> y un asterisco</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-delete_002dand_002dextract_002dregion"><code>delete-and-extract-region</code></a></td><td> </td><td valign="top"><a href="#Disgresi_00f3n-dentro-de-C">8.4 Disgresión dentro de C</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Depurador-de-nivel-de-codigo">Depurador de nivel de código</a></td><td> </td><td valign="top"><a href="#edebug">17.4 El depurador de nivel de fuentes <code>edebug</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-depurando">depurando</a></td><td> </td><td valign="top"><a href="#Depurando">17 Depurando</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-depurar"><code>depurar</code></a></td><td> </td><td valign="top"><a href="#depurar">17.1 <code>depurar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Desasociar-Tecla-a-Comando">Desasociar Tecla a Comando</a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-describe_002dfunction"><code>describe-function</code></a></td><td> </td><td valign="top"><a href="#simplified_002dbeginning_002dof_002dbuffer">4.2 Una definición simplificada de <code>beginning-of-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-describe_002dfunction_002c-introducido"><code>describe-function, <span class="roman">introducido</span></code></a></td><td> </td><td valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Diferir-en-recursion">Diferir en recursión</a></td><td> </td><td valign="top"><a href="#Sin-Aplazar">11.3.7 Recursión sin diferir</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-directory_002dfiles"><code>directory-files</code></a></td><td> </td><td valign="top"><a href="#Listar-ficheros">14.9.2 Creando una lista de ficheros</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Disgresion-dentro-de-C">Disgresión dentro de C</a></td><td> </td><td valign="top"><a href="#Disgresi_00f3n-dentro-de-C">8.4 Disgresión dentro de C</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Disociando-la-tecla">Disociando la tecla</a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Division">División</a></td><td> </td><td valign="top"><a href="#El-caso-del-buffer-largo">Qué ocurre en un búffer largo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-dolist"><code>dolist</code></a></td><td> </td><td valign="top"><a href="#dolist">La macro <code>dolist</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-dotimes"><code>dotimes</code></a></td><td> </td><td valign="top"><a href="#dotimes">La macro <code>dotimes</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-E">E</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-edebug"><code>edebug</code></a></td><td> </td><td valign="top"><a href="#edebug">17.4 El depurador de nivel de fuentes <code>edebug</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-efecto-lateral-definido">‘<samp>efecto lateral</samp>’ definido</a></td><td> </td><td valign="top"><a href="#C_00f3mo-el-int_00e9rprete-act_00faa">Cómo el intérprete actúa</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Ejecuta-un-programa">Ejecuta un programa</a></td><td> </td><td valign="top"><a href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Ejemplo-de-Expresion-let">Ejemplo de Expresión <code>let</code></a></td><td> </td><td valign="top"><a href="#Ejemplo-de-expresi_00f3n-let">3.6.2 Ejemplo de Expresión <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Ejes_002c-imprime-horizontal">Ejes, imprime horizontal</a></td><td> </td><td valign="top"><a href="#print_002dX_002daxis">C.3 La función <code>print-X-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Ejes_002c-imprimir-vertical">Ejes, imprimir vertical</a></td><td> </td><td valign="top"><a href="#print_002dY_002daxis">C.2 La función <code>print-Y-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Else">Else</a></td><td> </td><td valign="top"><a href="#else">3.8 Expresiones if–then–else</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Encogiendo">Encogiendo</a></td><td> </td><td valign="top"><a href="#Encogiendo-y-extendiendo">6 Encogiendo y extendiendo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Encontrar-documentacion-de-la-funcion">Encontrar documentación de la función</a></td><td> </td><td valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Encontrar-la-fuente-de-la-funcion">Encontrar la fuente de la función</a></td><td> </td><td valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Encontrar-un-fichero">Encontrar un fichero</a></td><td> </td><td valign="top"><a href="#Encontrar-un-fichero">14.5 Encontrar un fichero</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-eobp"><code>eobp</code></a></td><td> </td><td valign="top"><a href="#fwd_002dpara-while">El bucle <code>while</code> hacia adelante</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-eq"><code>eq</code></a></td><td> </td><td valign="top"><a href="#Revisar">3.11 Revisar</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-eq-_0028ejemplo-de-uso_0029"><code>eq <span class="roman">(ejemplo de uso)</span></code></a></td><td> </td><td valign="top"><a href="#last_002dcommand-_0026-this_002dcommand"><code>last-command</code> y <code>this-command</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-equal"><code>equal</code></a></td><td> </td><td valign="top"><a href="#Revisar">3.11 Revisar</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-error"><code>error</code></a></td><td> </td><td valign="top"><a href="#Cuerpo-de-current_002dkill">El cuerpo de <code>current-kill</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Error-para-simbolo-sin-funcion">Error para símbolo sin función</a></td><td> </td><td valign="top"><a href="#Funci_00f3n-vac_00eda">1.7.1 Mensaje de error de un símbolo sin una función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Error-para-simbolo-sin-valor">Error para símbolo sin valor</a></td><td> </td><td valign="top"><a href="#Variable-vac_00eda">1.7.2 Mensaje de error de un símbolo sin un valor</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Error_002c-del-tipo-mas-insidioso">Error, del tipo más insidioso</a></td><td> </td><td valign="top"><a href="#Otro-Error">C.4.5 Otro error … más insidioso</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Escribiendo-la-Definicion">Escribiendo la Definición</a></td><td> </td><td valign="top"><a href="#Escribiendo-funciones">3 Cómo escribir definiciones de funciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Escribiendo-la-Definicion-de-Funcion">Escribiendo la Definición de Función</a></td><td> </td><td valign="top"><a href="#Escribiendo-funciones">3 Cómo escribir definiciones de funciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Escribiendo-una-definicion-funcion">Escribiendo una definición función</a></td><td> </td><td valign="top"><a href="#Escribiendo-funciones">3 Cómo escribir definiciones de funciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Espacio-en-blanco-en-listas">Espacio en blanco en listas</a></td><td> </td><td valign="top"><a href="#Espacios-en-blanco-en-listas">1.1.2 Espacios en blanco en listas</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-etags"><code>etags</code></a></td><td> </td><td valign="top"><a href="#etags">12.5 Crea tu propio fichero ‘<tt>TAGS</tt>’</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Etiquetas-en-las-fuentes-Emacs">Etiquetas en las fuentes Emacs</a></td><td> </td><td valign="top"><a href="#Construyendo-Etiquetas-en-las-fuentes-Emacs">Construyendo Etiquetas en las fuentes Emacs</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Evaluacion">Evaluación</a></td><td> </td><td valign="top"><a href="#Evaluaci_00f3n">1.6 Evaluación</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Evaluacion-de-listas-internas">Evaluación de listas internas</a></td><td> </td><td valign="top"><a href="#Evaluando-listas-propias">1.6.1 Evaluando listas propias</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Evaluacion-practica">Evaluación práctica</a></td><td> </td><td valign="top"><a href="#Practicando-evaluaci_00f3n">2 Practicando evaluación</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Evaluando-listas-internas">Evaluando listas internas</a></td><td> </td><td valign="top"><a href="#Evaluando-listas-propias">1.6.1 Evaluando listas propias</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Every_002c-tipo-de-patron-recursivo">Every, tipo de patrón recursivo</a></td><td> </td><td valign="top"><a href="#Cada">Patrón recursivo: <em>every</em></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-expresion-definida">‘<samp>expresión</samp>’ definida</a></td><td> </td><td valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-expresion-let_002c-partes-de">expresión <code>let</code>, partes de</a></td><td> </td><td valign="top"><a href="#Partes-de-la-expresi_00f3n-let">3.6.1 Las partes de una expresión <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-expresion-simple-let">expresión simple <code>let</code></a></td><td> </td><td valign="top"><a href="#Ejemplo-de-expresi_00f3n-let">3.6.2 Ejemplo de Expresión <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Expresiones-regulares-para-contar-palabras">Expresiones regulares para contar palabras</a></td><td> </td><td valign="top"><a href="#Contando-palabras">13 Contando: repetición y regexps</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Expresiones-simbolicas_002c-introducidas">Expresiones simbólicas, introducidas</a></td><td> </td><td valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Extendiendo_002c-ejemplo-de">Extendiendo, ejemplo de</a></td><td> </td><td valign="top"><a href="#what_002dline">6.2 <code>what-line</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Extension-simple-en-fichero-_002eemacs">Extensión simple en fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td valign="top"><a href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-F">F</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Falsedad-y-verdad-en-Emacs-Lisp">Falsedad y verdad en Emacs Lisp</a></td><td> </td><td valign="top"><a href="#Verdad-y-falsedad">3.9 Verdad y falsedad en Emacs Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-FDL_002c-GNU-Free-Documentation-License">FDL, GNU Free Documentation License</a></td><td> </td><td valign="top"><a href="#GNU-Free-Documentation-License">Appendix E GNU Free Documentation License</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fichero-_002eemacs">fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td valign="top"><a href="#Inicializaci_00f3n-de-Emacs">16 Tu fichero ‘<tt>.emacs</tt>’</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fichero-_002eemacs_002c-empezando">fichero ‘<tt>.emacs</tt>’, empezando</a></td><td> </td><td valign="top"><a href="#Empezando-un-fichero-_002eemacs">16.3 Empieza por un fichero ‘<tt>.emacs</tt>’</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fichero-de-inicio-default_002eel">fichero de inicio ‘<tt>default.el</tt>’</a></td><td> </td><td valign="top"><a href="#Site_002dwide-Init">16.1 Fichero de inicialización site-wide</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fichero-de-TAGS_002c-crea-el-propio">fichero de ‘<tt>TAGS</tt>’, crea el propio</a></td><td> </td><td valign="top"><a href="#etags">12.5 Crea tu propio fichero ‘<tt>TAGS</tt>’</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Fichero-inicializacion">Fichero inicialización</a></td><td> </td><td valign="top"><a href="#Inicializaci_00f3n-de-Emacs">16 Tu fichero ‘<tt>.emacs</tt>’</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fichero-inicio-site_002dinit_002eel">fichero inicio ‘<tt>site-init.el</tt>’</a></td><td> </td><td valign="top"><a href="#Site_002dwide-Init">16.1 Fichero de inicialización site-wide</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fichero-ring_002eel">fichero ‘<tt>ring.el</tt>’</a></td><td> </td><td valign="top"><a href="#fichero-anillo">B.4 El fichero ‘<tt>ring.el</tt>’</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fichero-site_002dload_002eel">fichero ‘<tt>site-load.el</tt>’</a></td><td> </td><td valign="top"><a href="#Site_002dwide-Init">16.1 Fichero de inicialización site-wide</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-files_002din_002dbelow_002ddirectory"><code>files-in-below-directory</code></a></td><td> </td><td valign="top"><a href="#Listar-ficheros">14.9.2 Creando una lista de ficheros</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-fill_002dcolumn_002c-una-variable-de-ejemplo"><code>fill-column, <span class="roman">una variable de ejemplo</span></code></a></td><td> </td><td valign="top"><a href="#Ejemplo-de-rellenar-columna"><code>fill-column</code>, un ejemplo de variable</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-filter_002dbuffer_002dsubstring"><code>filter-buffer-substring</code></a></td><td> </td><td valign="top"><a href="#last_002dcommand-_0026-this_002dcommand"><code>last-command</code> y <code>this-command</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-find_002dtag"><code>find-tag</code></a></td><td> </td><td valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Flores-en-un-campo">Flores en un campo</a></td><td> </td><td valign="top"><a href="#Listas-Lisp">1.1 Listas Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Focalizando-atencion-_0028encogiendo_0029">Focalizando atención (encogiendo)</a></td><td> </td><td valign="top"><a href="#Encogiendo-y-extendiendo">6 Encogiendo y extendiendo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-forma-definida">‘<samp>forma</samp>’ definida</a></td><td> </td><td valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Forma-Especial">Forma Especial</a></td><td> </td><td valign="top"><a href="#Complicaciones">Complicaciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Forma-Especial-de-defun">Forma Especial de <code>defun</code></a></td><td> </td><td valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Formateando-ayuda">Formateando ayuda</a></td><td> </td><td valign="top"><a href="#Escribiendo-listas">1.1.3 GNU Emacs te ayuda a escribir listas</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Formato-de-Modo-Linea">Formato de Modo Línea</a></td><td> </td><td valign="top"><a href="#Mode-Line">16.14 Una línea modificada</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-forward_002dparagraph"><code>forward-paragraph</code></a></td><td> </td><td valign="top"><a href="#forward_002dparagraph">12.4 <code>forward-paragraph</code>: una mina de oro de funciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-forward_002dsentence"><code>forward-sentence</code></a></td><td> </td><td valign="top"><a href="#forward_002dsentence">12.3 <code>forward-sentence</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Frases_002c-movimiento-por">Frases, movimiento por</a></td><td> </td><td valign="top"><a href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Funcion-Anonima">Función Anónima</a></td><td> </td><td valign="top"><a href="#lambda">C.4.3 Una expresión <code>lambda</code>: Anonimicidad útil</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Funcion-de-palabras-duplicadas">Función de palabras duplicadas</a></td><td> </td><td valign="top"><a href="#the_002dthe">Appendix A La función <code>the-the</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-funcion-definida">‘<samp>función</samp>’ definida</a></td><td> </td><td valign="top"><a href="#Creando-errores">1.3 Generar un mensaje de error</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-funcion-definida-1">‘<samp>función</samp>’ definida</a></td><td> </td><td valign="top"><a href="#Creando-errores">1.3 Generar un mensaje de error</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-funcion-interactiva-definida">‘<samp>función interactiva</samp>’ definida</a></td><td> </td><td valign="top"><a href="#C_00f3mo-evaluar">Cómo evaluar</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Funcion-resto_002c-_0025">Función resto, <code>%</code></a></td><td> </td><td valign="top"><a href="#Calcular-un-resto">C.2.1 Viaje lateral: Calcula un resto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Funciones-Interactivas">Funciones Interactivas</a></td><td> </td><td valign="top"><a href="#Interactive">3.3 Crear una función interactive</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Funciones-primitivas">Funciones primitivas</a></td><td> </td><td valign="top"><a href="#Funciones-primitivas">Una vía acerca de funciones primitivas</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Funciones_002c-primitiva">Funciones, primitiva</a></td><td> </td><td valign="top"><a href="#Funciones-primitivas">Una vía acerca de funciones primitivas</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-G">G</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Genera-un-mensaje-de-error">Genera un mensaje de error</a></td><td> </td><td valign="top"><a href="#Creando-errores">1.3 Generar un mensaje de error</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Generacion-de-mensaje-de-Error">Generación de mensaje de Error</a></td><td> </td><td valign="top"><a href="#Creando-errores">1.3 Generar un mensaje de error</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-global_002dset_002dkey"><code>global-set-key</code></a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-global_002dunset_002dkey"><code>global-unset-key</code></a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Grafo-prototipo">Grafo prototipo</a></td><td> </td><td valign="top"><a href="#Leyendo-un-grafo">15 Leyendo un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Grafo_002c-imprimiendo-todo">Grafo, imprimiendo todo</a></td><td> </td><td valign="top"><a href="#Imprimir-Grafo-Entero">C.4 Imprimiendo el grafo completo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-graph_002dbody_002dprint"><code>graph-body-print</code></a></td><td> </td><td valign="top"><a href="#graph_002dbody_002dprint">15.1 La función <code>graph-body-print</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-graph_002dbody_002dprint-Version-Final_002e"><code>graph-body-print <span class="roman">Versión Final.</span></code></a></td><td> </td><td valign="top"><a href="#La-versi_00f3n-final">Cambios para la versión final</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-H">H</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Historia-de-Lisp">Historia de Lisp</a></td><td> </td><td valign="top"><a href="#Historia-de-Lisp">Historia de Lisp</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-I">I</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-if"><code>if</code></a></td><td> </td><td valign="top"><a href="#if">3.7 La forma especial <code>if</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Imprime-eje-horizontal">Imprime eje horizontal</a></td><td> </td><td valign="top"><a href="#print_002dX_002daxis">C.3 La función <code>print-X-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Imprimiendo-eje-horizontal">Imprimiendo eje horizontal</a></td><td> </td><td valign="top"><a href="#print_002dX_002daxis">C.3 La función <code>print-X-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-imprimiendo-eje-X">imprimiendo eje X</a></td><td> </td><td valign="top"><a href="#print_002dX_002daxis">C.3 La función <code>print-X-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-imprimiendo-eje-Y">imprimiendo eje Y</a></td><td> </td><td valign="top"><a href="#print_002dY_002daxis">C.2 La función <code>print-Y-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Imprimiendo-Ejes-Verticales">Imprimiendo Ejes Verticales</a></td><td> </td><td valign="top"><a href="#print_002dY_002daxis">C.2 La función <code>print-Y-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Imprimiendo-el-grafo-entero">Imprimiendo el grafo entero</a></td><td> </td><td valign="top"><a href="#Imprimir-Grafo-Entero">C.4 Imprimiendo el grafo completo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Imprimiendo-el-grafo-entero-1">Imprimiendo el grafo entero</a></td><td> </td><td valign="top"><a href="#Imprimir-Grafo-Entero">C.4 Imprimiendo el grafo completo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Imprimir-eje-vertical">Imprimir eje vertical</a></td><td> </td><td valign="top"><a href="#print_002dY_002daxis">C.2 La función <code>print-Y-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-indent_002dtabs_002dmode"><code>indent-tabs-mode</code></a></td><td> </td><td valign="top"><a href="#Indentar-modo-de-tabulaciones">16.6 Indentar modo de tabulaciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Indentacin-para-formatear">Indentaciń para formatear</a></td><td> </td><td valign="top"><a href="#append-save_002dexcursion">4.4.3 <code>save-excursion</code> en <code>append-to-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Inicializacion-de-Variable">Inicialización de Variable</a></td><td> </td><td valign="top"><a href="#defvar">8.5 Inicializando una variable con <code>defvar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Inicializando-una-variable">Inicializando una variable</a></td><td> </td><td valign="top"><a href="#defvar">8.5 Inicializando una variable con <code>defvar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-insert_002dbuffer"><code>insert-buffer</code></a></td><td> </td><td valign="top"><a href="#insert_002dbuffer">5.2 La definición de <code>insert-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-insert_002dbuffer_002c-nueva-version-del-cuerpo"><code>insert-buffer, nueva versión del cuerpo</code></a></td><td> </td><td valign="top"><a href="#Nuevo-insert_002dbuffer">5.2.6 Nuevo cuerpo para <code>insert-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-insert_002dbuffer_002dsubstring"><code>insert-buffer-substring</code></a></td><td> </td><td valign="top"><a href="#resumen-de-append_002dto_002dbuffer">Un resumen de <code>append-to-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Insidioso-tipo-de-error">Insidioso tipo de error</a></td><td> </td><td valign="top"><a href="#Otro-Error">C.4.5 Otro error … más insidioso</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Instalar-codigo-permanentemente">Instalar código permanentemente</a></td><td> </td><td valign="top"><a href="#Instalaci_00f3n-Permanente">3.5 Instalar código permanentemente</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Instalar-una-definicion-de-funcion">Instalar una definición de función</a></td><td> </td><td valign="top"><a href="#Instalar">3.2 Instalar una definición de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Interprete-Lisp_002c-explicada">Intérprete Lisp, explicada</a></td><td> </td><td valign="top"><a href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Interprete-Lisp_002c-que-hace">Intérprete Lisp, qué hace</a></td><td> </td><td valign="top"><a href="#Interpr_00e9te-Lisp">1.5 El intérprete Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Interprete_002c-Lisp_002c-explicado">Intérprete, Lisp, explicado</a></td><td> </td><td valign="top"><a href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Interprete_002c-que-hace">Intérprete, qué hace</a></td><td> </td><td valign="top"><a href="#Interpr_00e9te-Lisp">1.5 El intérprete Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-interactive"><code>interactive</code></a></td><td> </td><td valign="top"><a href="#Interactive">3.3 Crear una función interactive</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-interactive_002c-ejemplo-de-uso"><code>interactive, <span class="roman">ejemplo de uso</span></code></a></td><td> </td><td valign="top"><a href="#insert_002dbuffer-interactivo">5.2.1 La expresión interactiva en <code>insert-buffer</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-K">K</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Keep_002c-el-tipo-de-patron-recursivo">Keep, el tipo de patrón recursivo</a></td><td> </td><td valign="top"><a href="#Guardar">Patrón recursivo: <em>keep</em></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-kill_002dappend"><code>kill-append</code></a></td><td> </td><td valign="top"><a href="#Funci_00f3n-kill_002dappend">La función <code>kill-append</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-kill_002dnew"><code>kill-new</code></a></td><td> </td><td valign="top"><a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-kill_002dregion"><code>kill-region</code></a></td><td> </td><td valign="top"><a href="#kill_002dregion">8.2 <code>kill-region</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-L">L</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-lambda"><code>lambda</code></a></td><td> </td><td valign="top"><a href="#lambda">C.4.3 Una expresión <code>lambda</code>: Anonimicidad útil</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-length"><code>length</code></a></td><td> </td><td valign="top"><a href="#length">7.2.1 Encuentra el tamaño de una lista: <code>length</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-lengths_002dlist_002dfile"><code>lengths-list-file</code></a></td><td> </td><td valign="top"><a href="#lengths_002dlist_002dfile">14.6 <code>lengths-list-file</code> en detalle</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-lengths_002dlist_002dmany_002dfiles"><code>lengths-list-many-files</code></a></td><td> </td><td valign="top"><a href="#lengths_002dlist_002dmany_002dfiles">Determina las longitudes de <code>defuns</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-let"><code>let</code></a></td><td> </td><td valign="top"><a href="#let">3.6 <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Leyendo-un-grafo">Leyendo un grafo</a></td><td> </td><td valign="top"><a href="#Leyendo-un-grafo">15 Leyendo un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Libreria_002c-como-termino-para-_0060fichero_0027">Librería, como término para ‘fichero’</a></td><td> </td><td valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-line_002dto_002dtop_002dof_002dwindow"><code>line-to-top-of-window</code></a></td><td> </td><td valign="top"><a href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-list_002dbuffers_002c-reasociar"><code>list-buffers, <span class="roman">reasociar</span></code></a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-lista-de-argumentos-definida">‘<samp>lista de argumentos</samp>’ definida</a></td><td> </td><td valign="top"><a href="#defun">3.1 La forma especial <code>defun</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Lista-de-variables-locales_002c-por-buffer_002c">Lista de variables locales, por búffer,</a></td><td> </td><td valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-lista-vacia-definida">‘<samp>lista vacía</samp>’ definida</a></td><td> </td><td valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Listas-en-un-ordenador">Listas en un ordenador</a></td><td> </td><td valign="top"><a href="#Implementaci_00f3n-de-listas">9 Cómo las listas se implementan</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Listas-Lisp">Listas Lisp</a></td><td> </td><td valign="top"><a href="#Listas-Lisp">1.1 Listas Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-llamada-definida">‘<samp>llamada</samp>’ definida</a></td><td> </td><td valign="top"><a href="#Cambiando-b_00faffers">2.3 Cambiando búffers</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-load_002dlibrary"><code>load-library</code></a></td><td> </td><td valign="top"><a href="#Cargando-ficheros">16.9 Cargando ficheros</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-load_002dpath"><code>load-path</code></a></td><td> </td><td valign="top"><a href="#Cargando-ficheros">16.9 Cargando ficheros</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Localizacion-del-Punto">Localización del Punto</a></td><td> </td><td valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Localizacion-del-punto">Localización del punto</a></td><td> </td><td valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-looking_002dat"><code>looking-at</code></a></td><td> </td><td valign="top"><a href="#fwd_002dpara-while">El bucle <code>while</code> hacia adelante</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-M">M</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Maclisp">Maclisp</a></td><td> </td><td valign="top"><a href="#Historia-de-Lisp">Historia de Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Macro-Lisp">Macro Lisp</a></td><td> </td><td valign="top"><a href="#Macro-Lisp">8.2.2 Macro Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Macro_002c-lisp">Macro, lisp</a></td><td> </td><td valign="top"><a href="#Macro-Lisp">8.2.2 Macro Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-make_002dstring"><code>make-string</code></a></td><td> </td><td valign="top"><a href="#Elemento-del-Eje-Y">C.2.2 Construye un elemento del eje Y</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Manejando-el-anillo-de-la-muerte">Manejando el anillo de la muerte</a></td><td> </td><td valign="top"><a href="#Kill-Ring">Appendix B Manejando el anillo de la muerte</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Manejando-el-anillo-de-la-muerte-1">Manejando el anillo de la muerte</a></td><td> </td><td valign="top"><a href="#Kill-Ring">Appendix B Manejando el anillo de la muerte</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Mapas-de-teclado">Mapas de teclado</a></td><td> </td><td valign="top"><a href="#Mapas-de-teclado">16.8 Mapas de teclado</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-mapcar"><code>mapcar</code></a></td><td> </td><td valign="top"><a href="#mapcar">C.4.4 La función <code>mapcar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-marca"><code>marca</code></a></td><td> </td><td valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-mark_002dwhole_002dbuffer"><code>mark-whole-buffer</code></a></td><td> </td><td valign="top"><a href="#mark_002dwhole_002dbuffer">4.3 La definición de <code>mark-whole-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-match_002dbeginning"><code>match-beginning</code></a></td><td> </td><td valign="top"><a href="#fwd_002dpara-while">El bucle <code>while</code> hacia adelante</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-max"><code>max</code></a></td><td> </td><td valign="top"><a href="#Columnas-de-un-grafo">Imprimiendo las columnas de un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-message"><code>message</code></a></td><td> </td><td valign="top"><a href="#message">1.8.5 La función <code>message</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-min"><code>min</code></a></td><td> </td><td valign="top"><a href="#Columnas-de-un-grafo">Imprimiendo las columnas de un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-mode_002dline_002dformat"><code>mode-line-format</code></a></td><td> </td><td valign="top"><a href="#Mode-Line">16.14 Una línea modificada</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Modo-de-autoajuste-activado">Modo de autoajuste activado</a></td><td> </td><td valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Modo-de-seleccion_002c-automatico">Modo de selección, automático</a></td><td> </td><td valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Modo-Texto-activado">Modo Texto activado</a></td><td> </td><td valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Mover-frase-y-parrafo">Mover frase y párrafo</a></td><td> </td><td valign="top"><a href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-N">N</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-narrowing-definido">‘<samp>narrowing</samp>’ definido</a></td><td> </td><td valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nil"><code>nil</code></a></td><td> </td><td valign="top"><a href="#Verdad-y-falsedad">3.9 Verdad y falsedad en Emacs Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nil_002c-historia-de-palabra"><code>nil</code>, historia de palabra</a></td><td> </td><td valign="top"><a href="#Nombres-de-b_00faffer">2.1 Nombres de búffer</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-No-aplazar-la-solucion">No aplazar la solución</a></td><td> </td><td valign="top"><a href="#No-aplazar-la-soluci_00f3n">11.3.8 No hay solución pospuesta</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Nombres-de-Simbolos">Nombres de Símbolos</a></td><td> </td><td valign="top"><a href="#Nombres-y-definiciones">1.4 Nombres de símbolos y definiciones de funciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nreverse"><code>nreverse</code></a></td><td> </td><td valign="top"><a href="#Contando-definiciones-de-funci_00f3n">14.9.3 Contando definiciones de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nth"><code>nth</code></a></td><td> </td><td valign="top"><a href="#nth">7.4 <code>nth</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nthcdr"><code>nthcdr</code></a></td><td> </td><td valign="top"><a href="#nthcdr">7.3 <code>nthcdr</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nthcdr-1"><code>nthcdr</code></a></td><td> </td><td valign="top"><a href="#copy_002dregion_002das_002dkill">8.3 <code>copy-region-as-kill</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nthcdr_002c-ejemplo"><code>nthcdr, <span class="roman">ejemplo</span></code></a></td><td> </td><td valign="top"><a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Numero-variable-de-argumentos">Número variable de argumentos</a></td><td> </td><td valign="top"><a href="#N_00famero-de-variables-de-argumentos">1.8.3 Número de variables de argumentos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-nueva-version-cuerpo-para-insert_002dbuffer"><code>nueva versión cuerpo para insert-buffer</code></a></td><td> </td><td valign="top"><a href="#Nuevo-insert_002dbuffer">5.2.6 Nuevo cuerpo para <code>insert-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-number_002dto_002dstring"><code>number-to-string</code></a></td><td> </td><td valign="top"><a href="#Elemento-del-Eje-Y">C.2.2 Construye un elemento del eje Y</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-O">O</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-occur"><code>occur</code></a></td><td> </td><td valign="top"><a href="#Atajos-de-teclado">16.7 Algunos atajos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-opcional"><code>opcional</code></a></td><td> </td><td valign="top"><a href="#Argumentos-opcionales">5.3.1 Argumentos opcionales</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Opciones-Interactive">Opciones Interactive</a></td><td> </td><td valign="top"><a href="#Opciones-de-interactive_002e">3.4 Diferentes opciones para <code>interactive</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Opciones-para-interactive">Opciones para <code>interactive</code></a></td><td> </td><td valign="top"><a href="#Opciones-de-interactive_002e">3.4 Diferentes opciones para <code>interactive</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-or"><code>or</code></a></td><td> </td><td valign="top"><a href="#Insertar-o">5.2.4 El <code>or</code> en el cuerpo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-other_002dbuffer"><code>other-buffer</code></a></td><td> </td><td valign="top"><a href="#Obteniendo-b_00faffers">2.2 Obteniendo búffers</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-P">P</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Parrafos_002c-movimiento-por">Párrafos, movimiento por</a></td><td> </td><td valign="top"><a href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Palabra-Clave">Palabra Clave</a></td><td> </td><td valign="top"><a href="#Argumentos-opcionales">5.3.1 Argumentos opcionales</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Palabras-y-simbolos-en-defun">Palabras y símbolos en defun</a></td><td> </td><td valign="top"><a href="#Palabras-y-S_00edmbolos">14.1 ¿Qué contar?</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Palabras_002c-contadas-recursivamente">Palabras, contadas recursivamente</a></td><td> </td><td valign="top"><a href="#recursive_002dcount_002dwords">13.2 Cuenta palabras recursivamente</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Palabras_002c-duplicadas">Palabras, duplicadas</a></td><td> </td><td valign="top"><a href="#the_002dthe">Appendix A La función <code>the-the</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-parte_002dentonces-definida">‘<samp>parte-entonces</samp>’ definida</a></td><td> </td><td valign="top"><a href="#if-en-m_00e1s-detalle"><code>if</code> en más detalle</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-parte_002dsi-definida">‘<samp>parte-si</samp>’ definida</a></td><td> </td><td valign="top"><a href="#if-en-m_00e1s-detalle"><code>if</code> en más detalle</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Partes-de-definicion-recursiva">Partes de definición recursiva</a></td><td> </td><td valign="top"><a href="#Partes-de-definici_00f3n-recursiva">11.3.2 Las partes de una definición recursiva</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Partes-de-la-expresion-let">Partes de la expresión <code>let</code></a></td><td> </td><td valign="top"><a href="#Partes-de-la-expresi_00f3n-let">3.6.1 Las partes de una expresión <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Partes-de-una-Definicion-Recursiva">Partes de una Definición Recursiva</a></td><td> </td><td valign="top"><a href="#Partes-de-definici_00f3n-recursiva">11.3.2 Las partes de una definición recursiva</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Pasando-informacion-para-funciones">Pasando información para funciones</a></td><td> </td><td valign="top"><a href="#Argumentos">1.8 Argumentos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Patron-recursivo_003a-acumular">Patrón recursivo: acumular</a></td><td> </td><td valign="top"><a href="#Acumular">Patrón recursivo: <em>accumulate</em></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Patron-recursivo_003a-every">Patrón recursivo: every</a></td><td> </td><td valign="top"><a href="#Cada">Patrón recursivo: <em>every</em></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Patron-recursivo_003a-keep">Patrón recursivo: keep</a></td><td> </td><td valign="top"><a href="#Guardar">Patrón recursivo: <em>keep</em></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Patrones-recursivos">Patrones recursivos</a></td><td> </td><td valign="top"><a href="#Patrones-recursivos">11.3.6 Patrones recursivos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Patrones_002c-buscando-por">Patrones, buscando por</a></td><td> </td><td valign="top"><a href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Pegando-Texto">Pegando Texto</a></td><td> </td><td valign="top"><a href="#Pegando">10 Pegando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-pegar"><code>pegar</code></a></td><td> </td><td valign="top"><a href="#Pegando">10 Pegando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-pegar-1"><code>pegar</code></a></td><td> </td><td valign="top"><a href="#pegar">B.2 <code>pegar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Personalizando-tu-fichero-_002eemacs">Personalizando tu fichero ‘<tt>.emacs</tt>’</a></td><td> </td><td valign="top"><a href="#Inicializaci_00f3n-de-Emacs">16 Tu fichero ‘<tt>.emacs</tt>’</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Por-buffer_002c-lista-de-variables-locales">Por búffer, lista de variables locales</a></td><td> </td><td valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Practicando-evaluacion">Practicando evaluación</a></td><td> </td><td valign="top"><a href="#Practicando-evaluaci_00f3n">2 Practicando evaluación</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Preservando-punto_002c-marca_002c-y-buffer">Preservando punto, marca, y búffer</a></td><td> </td><td valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Primitivas-en-lenguaje-C">Primitivas en lenguaje C</a></td><td> </td><td valign="top"><a href="#Funciones-primitivas">Una vía acerca de funciones primitivas</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Primitivas-escritas-en-C">Primitivas escritas en C</a></td><td> </td><td valign="top"><a href="#Funciones-primitivas">Una vía acerca de funciones primitivas</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002delements_002dof_002dlist"><code>print-elements-of-list</code></a></td><td> </td><td valign="top"><a href="#print_002delements_002dof_002dlist">11.1.2 Un ejemplo: <code>imprimir-elementos-de-la-lista</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002delements_002drecursively"><code>print-elements-recursively</code></a></td><td> </td><td valign="top"><a href="#Recursi_00f3n-con-lista">11.3.3 Recursión con una lista</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002dgraph-varlist"><code>print-graph</code> varlist</a></td><td> </td><td valign="top"><a href="#print_002dgraph-Varlist">C.1 La varlist <code>print-graph</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002dgraph-Version-Final_002e"><code>print-graph <span class="roman">Versión Final.</span></code></a></td><td> </td><td valign="top"><a href="#La-versi_00f3n-final">Cambios para la versión final</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002dX_002daxis"><code>print-X-axis</code></a></td><td> </td><td valign="top"><a href="#Eje-X-marca-tic">C.3.1 Eje X marca tic</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002dX_002daxis_002dnumbered_002dline"><code>print-X-axis-numbered-line</code></a></td><td> </td><td valign="top"><a href="#Eje-X-marca-tic">C.3.1 Eje X marca tic</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002dX_002daxis_002dtic_002dline"><code>print-X-axis-tic-line</code></a></td><td> </td><td valign="top"><a href="#Eje-X-marca-tic">C.3.1 Eje X marca tic</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-print_002dY_002daxis"><code>print-Y-axis</code></a></td><td> </td><td valign="top"><a href="#Pen_00faltimo-print_002dY_002daxis">C.2.4 La versión no demasiado final de <code>print-Y-axis</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-progn"><code>progn</code></a></td><td> </td><td valign="top"><a href="#progn">8.1.4 La forma especial <code>progn</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Programa_002c-ejecutando-uno">Programa, ejecutando uno</a></td><td> </td><td valign="top"><a href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Propiedades_002c-en-el-ejemplo-del-modo-linea">Propiedades, en el ejemplo del modo línea</a></td><td> </td><td valign="top"><a href="#Mode-Line">16.14 Una línea modificada</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Propiedades_002c-mencion-de-buffer_002dsubstring_002dno_002dproperties">Propiedades, mención de <code>buffer-substring-no-properties</code></a></td><td> </td><td valign="top"><a href="#Ejercicio-narrow">6.3 Ejercicio de encoger</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Prototipo-de-grafo">Prototipo de grafo</a></td><td> </td><td valign="top"><a href="#Leyendo-un-grafo">15 Leyendo un grafo</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-punto"><code>punto</code></a></td><td> </td><td valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Punto_002c-marca_002c-preservacion-de-buffer">Punto, marca, preservación de búffer</a></td><td> </td><td valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-push_002c-ejemplo"><code>push, <span class="roman">ejemplo</span></code></a></td><td> </td><td valign="top"><a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-R">R</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-re_002dsearch_002dforward"><code>re-search-forward</code></a></td><td> </td><td valign="top"><a href="#re_002dsearch_002dforward">12.2 La función <code>re-search-forward</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Reasociando-teclas">Reasociando teclas</a></td><td> </td><td valign="top"><a href="#Mapas-de-teclado">16.8 Mapas de teclado</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Recuperando-Texto">Recuperando Texto</a></td><td> </td><td valign="top"><a href="#Pegando">10 Pegando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Recuperar-Texto">Recuperar Texto</a></td><td> </td><td valign="top"><a href="#Pegando">10 Pegando texto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Recursion">Recursión</a></td><td> </td><td valign="top"><a href="#Recursi_00f3n">11.3 Recursión</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Recursion-sin-diferir">Recursión sin diferir</a></td><td> </td><td valign="top"><a href="#Sin-Aplazar">11.3.7 Recursión sin diferir</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Recursion-y-bucles">Recursión y bucles</a></td><td> </td><td valign="top"><a href="#Bucles-y-recursi_00f3n">11 Bucles y recursión</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Recursivamente-contando-palabras">Recursivamente contando palabras</a></td><td> </td><td valign="top"><a href="#recursive_002dcount_002dwords">13.2 Cuenta palabras recursivamente</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-recursive_002dcount_002dwords"><code>recursive-count-words</code></a></td><td> </td><td valign="top"><a href="#recursive_002dcount_002dwords">13.2 Cuenta palabras recursivamente</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-recursive_002dgraph_002dbody_002dprint"><code>recursive-graph-body-print</code></a></td><td> </td><td valign="top"><a href="#recursive_002dgraph_002dbody_002dprint">15.2 La función <code>recursive-graph-body-print</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-recursive_002dlengths_002dlist_002dmany_002dfiles"><code>recursive-lengths-list-many-files</code></a></td><td> </td><td valign="top"><a href="#Varios-ficheros-recursivamente">14.8 Recursivamente cuenta palabras en diferentes ficheros</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-regexp_002dquote"><code>regexp-quote</code></a></td><td> </td><td valign="top"><a href="#fwd_002dpara-let">La expresión <code>let*</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Region_002c-que-es">Región, qué es</a></td><td> </td><td valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Repeticion-_0028bucles_0029">Repetición (bucles)</a></td><td> </td><td valign="top"><a href="#Bucles-y-recursi_00f3n">11 Bucles y recursión</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Repeticion-para-contar-palabras">Repetición para contar palabras</a></td><td> </td><td valign="top"><a href="#Contando-palabras">13 Contando: repetición y regexps</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Resumen-del-Anillo-de-la-Muerte-Kill-ring">Resumen del Anillo de la Muerte <em>Kill ring</em></a></td><td> </td><td valign="top"><a href="#Resumen-del-anillo-de-la-muerte">10.1 Resumen del anillo de la muerte</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-reverse"><code>reverse</code></a></td><td> </td><td valign="top"><a href="#Contando-definiciones-de-funci_00f3n">14.9.3 Contando definiciones de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Robots_002c-construyendo">Robots, construyendo</a></td><td> </td><td valign="top"><a href="#Construyendo-robots">11.3.1 Construyendo robots: Extendiendo la metáfora</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-S">S</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-save_002dexcursion"><code>save-excursion</code></a></td><td> </td><td valign="top"><a href="#save_002dexcursion">3.10 <code>save-excursion</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-save_002drestriction"><code>save-restriction</code></a></td><td> </td><td valign="top"><a href="#save_002drestriction">6.1 La forma especial <code>save-restriction</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-se-definio-evaluate">se definió ‘<samp>evaluate</samp>’</a></td><td> </td><td valign="top"><a href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-search_002dforward"><code>search-forward</code></a></td><td> </td><td valign="top"><a href="#search_002dforward">8.1.3 La función <code>search-forward</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Seleccion-de-modo-automatico">Selección de modo automático</a></td><td> </td><td valign="top"><a href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-sentence_002dend"><code>sentence-end</code></a></td><td> </td><td valign="top"><a href="#sentence_002dend">12.1 La expresión regular para <code>sentence-end</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-set"><code>set</code></a></td><td> </td><td valign="top"><a href="#Usando-set">1.9.1 Usando <code>set</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-set_002dbuffer"><code>set-buffer</code></a></td><td> </td><td valign="top"><a href="#Cambiando-b_00faffers">2.3 Cambiando búffers</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-set_002dvariable"><code>set-variable</code></a></td><td> </td><td valign="top"><a href="#defvar-y-asterisk">8.5.1 <code>defvar</code> y un asterisco</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-setcar"><code>setcar</code></a></td><td> </td><td valign="top"><a href="#setcar">7.5 <code>setcar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-setcdr"><code>setcdr</code></a></td><td> </td><td valign="top"><a href="#setcdr">7.6 <code>setcdr</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-setcdr_002c-ejemplo"><code>setcdr, <span class="roman">ejemplo</span></code></a></td><td> </td><td valign="top"><a href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-setq"><code>setq</code></a></td><td> </td><td valign="top"><a href="#Usando-setq">1.9.2 Usando <code>setq</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Simbolo-sin-funcion-de-error">Símbolo sin función de error</a></td><td> </td><td valign="top"><a href="#Funci_00f3n-vac_00eda">1.7.1 Mensaje de error de un símbolo sin una función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Simbolo-sin-valor-de-error">Símbolo sin valor de error</a></td><td> </td><td valign="top"><a href="#Variable-vac_00eda">1.7.2 Mensaje de error de un símbolo sin un valor</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Simbolos-como-una-caja-con-cajones">Símbolos como una caja con cajones</a></td><td> </td><td valign="top"><a href="#S_00edmbolos-como-cajas">9.1 Símbolos como una caja con cajones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-simplified_002dbeginning_002dof_002dbuffer"><code>simplified-beginning-of-buffer</code></a></td><td> </td><td valign="top"><a href="#simplified_002dbeginning_002dof_002dbuffer">4.2 Una definición simplificada de <code>beginning-of-buffer</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Sin-posponer-la-solucion">Sin posponer la solución</a></td><td> </td><td valign="top"><a href="#No-aplazar-la-soluci_00f3n">11.3.8 No hay solución pospuesta</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Solucion-no-pospuesta">Solución no pospuesta</a></td><td> </td><td valign="top"><a href="#No-aplazar-la-soluci_00f3n">11.3.8 No hay solución pospuesta</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-sort"><code>sort</code></a></td><td> </td><td valign="top"><a href="#Ordenando">14.9.1 Ordenando listas</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-switch_002dto_002dbuffer"><code>switch-to-buffer</code></a></td><td> </td><td valign="top"><a href="#Cambiando-b_00faffers">2.3 Cambiando búffers</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-T">T</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-tabla-TAGS_002c-especificando">tabla TAGS, especificando</a></td><td> </td><td valign="top"><a href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Tabuladores_002c-previniendo">Tabuladores, previniendo</a></td><td> </td><td valign="top"><a href="#Indentar-modo-de-tabulaciones">16.6 Indentar modo de tabulaciones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Tamano-del-buffer">Tamaño del búffer</a></td><td> </td><td valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Tamano-del-Buffer">Tamaño del Búffer</a></td><td> </td><td valign="top"><a href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Teniendo-un-buffer">Teniendo un búffer</a></td><td> </td><td valign="top"><a href="#Obteniendo-b_00faffers">2.2 Obteniendo búffers</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Texto-entre-comillas">Texto entre comillas</a></td><td> </td><td valign="top"><a href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-the_002dthe"><code>the-the</code></a></td><td> </td><td valign="top"><a href="#the_002dthe">Appendix A La función <code>the-the</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Tipo-incorrecto-de-argumento">Tipo incorrecto de argumento</a></td><td> </td><td valign="top"><a href="#Tipo-incorrecto-de-argumento">1.8.4 Usando el tipo incorrecto de objeto como un argumento</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Tipos-de-dato-de-los-argumentos">Tipos de dato de los argumentos</a></td><td> </td><td valign="top"><a href="#Tipos-de-datos">1.8.1 Tipos de argumentos de datos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Tipos-de-datos">Tipos de datos</a></td><td> </td><td valign="top"><a href="#Tipos-de-datos">1.8.1 Tipos de argumentos de datos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Tipos-de-datos-1">Tipos de datos</a></td><td> </td><td valign="top"><a href="#Tipos-de-datos">1.8.1 Tipos de argumentos de datos</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-top_002dof_002dranges"><code>top-of-ranges</code></a></td><td> </td><td valign="top"><a href="#Contando-definiciones-de-funci_00f3n">14.9.3 Contando definiciones de función</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-triangle_002dbugged"><code>triangle-bugged</code></a></td><td> </td><td valign="top"><a href="#depurar">17.1 <code>depurar</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-triangle_002drecursively"><code>triangle-recursively</code></a></td><td> </td><td valign="top"><a href="#Funci_00f3n-recursiva-tri_00e1ngulo">11.3.4 Recursión en lugar de un contador</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-V">V</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-valor-devuelto-explicado">‘<samp>valor devuelto</samp>’ explicado</a></td><td> </td><td valign="top"><a href="#C_00f3mo-el-int_00e9rprete-act_00faa">Cómo el intérprete actúa</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Variable-de-Ejemplo_002c-fill_002dcolumn">Variable de Ejemplo, <code>fill-column</code></a></td><td> </td><td valign="top"><a href="#Ejemplo-de-rellenar-columna"><code>fill-column</code>, un ejemplo de variable</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-variable-global-definida">‘<samp>variable global</samp>’ definida</a></td><td> </td><td valign="top"><a href="#Determinando-el-elemento">Determinando el elemento</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-variable-local-definida">‘<samp>variable local</samp>’ definida</a></td><td> </td><td valign="top"><a href="#Prevenir-confusi_00f3n"><code>let</code> evita confusiones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Variable_002c-asignando-valor">Variable, asignando valor</a></td><td> </td><td valign="top"><a href="#set-y-setq">1.9 Configurando el valor de una variable</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Variable_002c-ejemplo-de_002c-fill_002dcolumn">Variable, ejemplo de, <code>fill-column</code></a></td><td> </td><td valign="top"><a href="#Ejemplo-de-rellenar-columna"><code>fill-column</code>, un ejemplo de variable</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-variable_002c-global_002c-definida">‘<samp>variable, global</samp>’, definida</a></td><td> </td><td valign="top"><a href="#Determinando-el-elemento">Determinando el elemento</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-variable_002c-local_002c-definida">‘<samp>variable, local</samp>’, definida</a></td><td> </td><td valign="top"><a href="#Prevenir-confusi_00f3n"><code>let</code> evita confusiones</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Variables">Variables</a></td><td> </td><td valign="top"><a href="#Variables">1.7 Variables</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Variables-let-no-inicializadas">Variables <code>let</code> no inicializadas</a></td><td> </td><td valign="top"><a href="#Variables-let-inicializadas">3.6.3 Variables sin inicializar en un sentencia <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Variables-let-no-inicializadas-1">Variables <code>let</code> no inicializadas</a></td><td> </td><td valign="top"><a href="#Variables-let-inicializadas">3.6.3 Variables sin inicializar en un sentencia <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-varlist-definida">‘<samp>varlist</samp>’ definida</a></td><td> </td><td valign="top"><a href="#Partes-de-la-expresi_00f3n-let">3.6.1 Las partes de una expresión <code>let</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Verdad-y-mentira-en-Emacs-Lisp">Verdad y mentira en Emacs Lisp</a></td><td> </td><td valign="top"><a href="#Verdad-y-falsedad">3.9 Verdad y falsedad en Emacs Lisp</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Version-de-Emacs_002c-eligiendo">Versión de Emacs, eligiendo</a></td><td> </td><td valign="top"><a href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Version-de-Emacs_002c-eligiendo-1">Versión de Emacs, eligiendo</a></td><td> </td><td valign="top"><a href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-W">W</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-what_002dline"><code>what-line</code></a></td><td> </td><td valign="top"><a href="#what_002dline">6.2 <code>what-line</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-while"><code>while</code></a></td><td> </td><td valign="top"><a href="#while">11.1 <code>while</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-X">X</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-X_002daxis_002delement"><code>X-axis-element</code></a></td><td> </td><td valign="top"><a href="#Eje-X-marca-tic">C.3.1 Eje X marca tic</a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-Y">Y</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-Y_002daxis_002dcolumn"><code>Y-axis-column</code></a></td><td> </td><td valign="top"><a href="#Y_002daxis_002dcolumn">C.2.3 Crea un eje de la columna Y</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Y_002daxis_002dcolumn-Version-Final_002e"><code>Y-axis-column <span class="roman">Versión Final.</span></code></a></td><td> </td><td valign="top"><a href="#La-versi_00f3n-final">Cambios para la versión final</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Y_002daxis_002dlabel_002dspacing"><code>Y-axis-label-spacing</code></a></td><td> </td><td valign="top"><a href="#Calcular-un-resto">C.2.1 Viaje lateral: Calcula un resto</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-Y_002daxis_002dtic"><code>Y-axis-tic</code></a></td><td> </td><td valign="top"><a href="#Elemento-del-Eje-Y">C.2.2 Construye un elemento del eje Y</a></td></tr> -<tr><td></td><td valign="top"><a href="#index-yank_002dpop"><code>yank-pop</code></a></td><td> </td><td valign="top"><a href="#yank_002dpop">B.3 <code>yank-pop</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -<tr><th><a name="Indice_cp_letter-Z">Z</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#index-zap_002dto_002dchar"><code>zap-to-char</code></a></td><td> </td><td valign="top"><a href="#zap_002dto_002dchar">8.1 <code>zap-to-char</code></a></td></tr> -<tr><td></td><td valign="top"><a href="#index-zerop"><code>zerop</code></a></td><td> </td><td valign="top"><a href="#Cuerpo-de-current_002dkill">El cuerpo de <code>current-kill</code></a></td></tr> -<tr><td colspan="4"> <hr></td></tr> -</table> -<table><tr><th valign="top">Saltar a: </th><td><a class="summary-letter" href="#Indice_cp_symbol-1"><b>%</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-2"><b>(</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-3"><b>*</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-4"><b>/</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-5"><b><</b></a> - -<a class="summary-letter" href="#Indice_cp_symbol-6"><b>></b></a> - -<br> -<a class="summary-letter" href="#Indice_cp_letter-A"><b>A</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-B"><b>B</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-C"><b>C</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-D"><b>D</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-E"><b>E</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-F"><b>F</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-G"><b>G</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-H"><b>H</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-I"><b>I</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-K"><b>K</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-L"><b>L</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-M"><b>M</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-N"><b>N</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-O"><b>O</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-P"><b>P</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-R"><b>R</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-S"><b>S</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-T"><b>T</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-V"><b>V</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-W"><b>W</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-X"><b>X</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-Y"><b>Y</b></a> - -<a class="summary-letter" href="#Indice_cp_letter-Z"><b>Z</b></a> - -</td></tr></table> - - -<hr> -<a name="Acerca-del-Autor"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Inicio de este capítulo o capítulo anterior"> << </a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Sección anterior en orden de lectura"> < </a>]</td> -<td valign="middle" align="left">[<a href="#Top" title="Subir sección"> Subir </a>]</td> -<td valign="middle" align="left">[ > ]</td> -<td valign="middle" align="left">[ >> ]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<a name="Acerca-del-Autor-1"></a> -<h1 class="unnumbered">Acerca del Autor</h1> - -<blockquote> -<p>Robert J. Chassell ha trabajado con GNU Emacs desde 1985. Él -escribe, edita y enseña Emacs y Emacs Lisp, y habla alrededor del -mundo acerca de la libertad del software. Chassell es Director -fundador y Tesorero de la Fundación por el Software Libre (FSF). Él -se graduó la Universidad de Cambridge, en Inglaterra. Él tiene un -interés contínuo en historia económica y social y vuela su -propio aeroplano -</p></blockquote> - - - -<hr size="6"> -<a name="SEC_Foot"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<h1>Notas al pie</h1> - -<h3><a name="FOOT1" href="#DOCF1">(1)</a></h3> -<p>El apóstrofo o comilla -es una abreviación para la función <code>quote</code>; -no necesitas pensar acerca de funciones ahora; las funciones se -definen en <a href="#Creando-errores">Generar un mensaje de error</a>. -</p><h3><a name="FOOT2" href="#DOCF2">(2)</a></h3> -<p>Es curioso trazar la -ruta por la cual la palabra ‘argumento’ llego a tener dos -significados distintos, uno en matemáticas y el otro en el inglés -cotidiano. De acuerdo al <cite>Oxford English -Dictionary</cite>, la palabra deriva del Latín para -‘<samp>dejar claro, probar</samp>’, por lo tanto, paso a significar, por un hilo de -derivación, ‘la evidencia ofrecida como prueba’, es decir ‘la -información -que se ofrece’, que conduce a su significado en Lisp. -Pero en el otro hilo de derivación, paso a significar ‘afirmar de una -manera lo que otros pueden afirmar en contra’, lo que llevó a la disputa del -significado de la palabra. (Nótese aquí que la -palabra Inglésa tiene dos definiciones diferentes adjuntas al mismo -tiempo. En contraste, en Emacs Lisp, un símbolo no puede -tener dos definiciones de función diferentes al mismo tiempo.) -</p><h3><a name="FOOT3" href="#DOCF3">(3)</a></h3> -<p><code>(quote -hola)</code> es una expansión de la abreviatura <code>'hola</code>. -</p><h3><a name="FOOT4" href="#DOCF4">(4)</a></h3> -<p>Actualmente, -puede usar <code>%s</code> para imprimir un número. Es no -específico. <code>%d</code> imprime solo la parte de un -número a la izquierda del punto decimal, y no cualquier cosa que -no es un número. -</p><h3><a name="FOOT5" href="#DOCF5">(5)</a></h3> -<p>En realidad, por defecto, si el búffer desde -el que has cambiado es visible por tí en otra -ventana, <code>other-buffer</code> elegirá el búffer más reciente que -no puedes ver; esto es una sutileza que a menudo olvido. -</p><h3><a name="FOOT6" href="#DOCF6">(6)</a></h3> -<p>O -mejor, para evitar escribir, probablemente solo necesite pulsar <kbd>RET</kbd> -si ‘<tt>*scratch*</tt>’ es el buffer por defecto, de ser diferente, solo -escriba parte del nombre, por ejemplo <code>*sc</code>, luego -presione la tecla <kbd>TAB</kbd> para hacer que se expanda el nombre completo, y -finalmente pulsa <kbd>RET</kbd> -</p><h3><a name="FOOT7" href="#DOCF7">(7)</a></h3> -<p>Recuerda, esta expresión te desplaza al -búffer más reciente que no puedas ver. Si -realmente quieres ir al ultimo búffers seleccionado, incluso si -es visible, es necesario evaluar la siguiente expresión más -compleja: -</p><div class="smallexample"> -<pre class="smallexample">(switch-to-buffer (other-buffer (current-buffer) t)) -</pre></div> -<p>En este caso, el primer argumento de <code>other-buffer</code> le dice a que -búffer saltar —el actual— y el segundo argumento le indica a -<code>other-buffer</code> que esta BIEN cambiar a un búffer visible. La utilidad -de <code>switch-to-buffer</code> es llevarte a una ventana invisible ya que -probablemente -usarías <kbd>C-x o</kbd> (<code>other-window</code>) para ir a otro -búffer visible -</p><h3><a name="FOOT8" href="#DOCF8">(8)</a></h3> -<p>De -acuerdo con Jared Diamond en <cite>Guns, Germs, and Steel</cite>, “… las -cebras se vuelven increiblemente peligrosas a medida que envejecen” pero la -demanda aquí es que no llegan a ser fieras como un -tigre. (1997, W. W. Norton and Co., ISBN 0-393-03894-2, pagina 171) -</p><h3><a name="FOOT9" href="#DOCF9">(9)</a></h3> -<p>Actualmente, -se puede <code>cons</code> un elemento para un átomo para producir a para -punteado. Los pares punteados no se discuten aquí; ver -<a href="elisp.html#Notaci_00f3n-de-Pares-Punteados">Notación de Para Punteado</a> in <cite>El Manual de Referencia de GNU Emacs Lisp</cite>. -</p><h3><a name="FOOT10" href="#DOCF10">(10)</a></h3> -<p>Más precisamente, y requiriendo conocimiento -más experto para comprender, los dos enteros son del tipo -‘Lisp_Object’, que puede también ser una unión C en vez de un tipo -de entero. -</p><h3><a name="FOOT11" href="#DOCF11">(11)</a></h3> -<p>Se pueden -escribir funciones recursivas para ser frugal o basura mental o -recursos de ordenador; como eso ocurre, los métodos que la gente -encuentra fáciles — son frugales de ‘recursos mentales’ — -algunas veces usan recursos de ordenador considerables. Emacs fué -diseñado para ejecutarse en máquinas que ahora se consideran -limitadas y sus configuraciones por defecto son conservadoras. Se puede -querer incrementar los valores de <code>max-specdl-size</code> y -<code>max-lisp-eval-depth</code>. En mi fichero ‘<tt>.emacs</tt>’, yo los asigno -a 15 o 30 veces su valor por defecto. -</p><h3><a name="FOOT12" href="#DOCF12">(12)</a></h3> -<p>La frase <em>cola -recursiva</em> es usado para describir tal proceso, uno que usa ‘espacio -constante’. -</p><h3><a name="FOOT13" href="#DOCF13">(13)</a></h3> -<p>La jerga es medianamente confusa: -<code>triangle-recursive-helper</code> usa un proceso que es iterativo en un -procedimiento que es recursivo. El proceso se llama iterativo porque -el ordenador necesita solo grabar los tres valores, <code>suma</code>, -<code>contador</code>, y <code>número</code>: el procedimiento es recursivo -porque la función ‘llama a sí mismo’. Por otro lado, -ambos el proceso y el procedimiento usado por -<code>triangle-recursively</code> son llamados recursivos. La palabra -‘recursivo’ tiene diferentes significados en los dos contextos. -</p><h3><a name="FOOT14" href="#DOCF14">(14)</a></h3> -<p>Tu puedes también añadir ‘<tt>.el</tt>’ para -‘<tt>~/.emacs</tt>’ y llama a un fichero ‘<tt>~/.emacs</tt>’. En el pasado, -fué prohibido escribir los atajos de teclado extra que el nombre -‘<tt>~/.emacs.el</tt>’ requiere, pero ahora puedes. El nuevo formato es -consistente con las conveniciones de nombre del fichero Emacs Lisp; el -viejo formato guarda la escritura. -</p><h3><a name="FOOT15" href="#DOCF15">(15)</a></h3> -<p>Cuando se empiezan las instancias de -Emacs que no cargan mi fichero ‘<tt>.emacs</tt>’ o cualquier fichero, -también se puede deshabilitar la ocultación: -</p><div class="smallexample"> -<pre class="smallexample">emacs -q --no-site-file -eval '(blink-cursor-mode nil)' -O ahora, -usando un conjunto más sofisticado de opciones, emacs -Q - D -</pre></div> - -<h3><a name="FOOT16" href="#DOCF16">(16)</a></h3> -<p>también se ejecutan gestores de ventanas más -modernos, tales como Enlightenment, Gnome, o KDE; en estos casos, con -frecuencia se especifica una imagen en vez de un color plano. -</p><hr> -<a name="SEC_Contents"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<h1>Índice General</h1> - -<div class="contents"> - -<ul class="no-bullet"> - <li><a name="toc-Prefacio-1" href="#Prefacio">Prefacio</a> - <ul class="no-bullet"> - <li><a name="toc-_00bfPor-que-estudiar-Emacs-Lisp_003f" href="#Por-qu_00e9">¿Por qué estudiar Emacs Lisp?</a></li> - <li><a name="toc-Leyendo-este-texto-1" href="#Leyendo-este-texto">Leyendo este texto</a></li> - <li><a name="toc-Para-quien-esta-esto-escrito" href="#Quien-eres">Para quien está esto escrito</a></li> - <li><a name="toc-Historia-de-Lisp-1" href="#Historia-de-Lisp">Historia de Lisp</a></li> - <li><a name="toc-Una-nota-para-principiantes" href="#Nota-para-principiantes">Una nota para principiantes</a></li> - <li><a name="toc-Se-agradece-1" href="#Se-agradece">Se agradece</a></li> - </ul></li> - <li><a name="toc-Procesamiento-de-listas-1" href="#Procesamiento-de-listas">1 Procesamiento de listas</a> - <ul class="no-bullet"> - <li><a name="toc-Listas-Lisp-1" href="#Listas-Lisp">1.1 Listas Lisp</a> - <ul class="no-bullet"> - <li><a name="toc-Numeros_002c-listas-dentro-de-listas" href="#Listas-de-n_00fameros">Números, listas dentro de listas</a></li> - <li><a name="toc-Atomos-Lisp" href="#g_t_00c1tomos-Lisp">1.1.1 Átomos Lisp</a></li> - <li><a name="toc-Espacios-en-blanco-en-listas-1" href="#Espacios-en-blanco-en-listas">1.1.2 Espacios en blanco en listas</a></li> - <li><a name="toc-GNU-Emacs-te-ayuda-a-escribir-listas" href="#Escribiendo-listas">1.1.3 GNU Emacs te ayuda a escribir listas</a></li> - </ul></li> - <li><a name="toc-Ejecutar-un-programa-1" href="#Ejecutar-un-programa">1.2 Ejecutar un programa</a></li> - <li><a name="toc-Generar-un-mensaje-de-error" href="#Creando-errores">1.3 Generar un mensaje de error</a></li> - <li><a name="toc-Nombres-de-simbolos-y-definiciones-de-funciones" href="#Nombres-y-definiciones">1.4 Nombres de símbolos y definiciones de funciones</a></li> - <li><a name="toc-El-interprete-Lisp" href="#Interpr_00e9te-Lisp">1.5 El intérprete Lisp</a> - <ul class="no-bullet"> - <li><a name="toc-Complicaciones-1" href="#Complicaciones">Complicaciones</a></li> - <li><a name="toc-Compilacion-de-bytes" href="#Compilaci_00f3n-de-bytes">1.5.1 Compilación de bytes</a></li> - </ul></li> - <li><a name="toc-Evaluacion" href="#Evaluaci_00f3n">1.6 Evaluación</a> - <ul class="no-bullet"> - <li><a name="toc-Como-el-interprete-actua" href="#C_00f3mo-el-int_00e9rprete-act_00faa">Cómo el intérprete actúa</a></li> - <li><a name="toc-Evaluando-listas-propias-1" href="#Evaluando-listas-propias">1.6.1 Evaluando listas propias</a></li> - </ul></li> - <li><a name="toc-Variables-1" href="#Variables">1.7 Variables</a> - <ul class="no-bullet"> - <li><a name="toc-fill_002dcolumn_002c-un-ejemplo-de-variable" href="#Ejemplo-de-rellenar-columna"><code>fill-column</code>, un ejemplo de variable</a></li> - <li><a name="toc-Mensaje-de-error-de-un-simbolo-sin-una-funcion" href="#Funci_00f3n-vac_00eda">1.7.1 Mensaje de error de un símbolo sin una función</a></li> - <li><a name="toc-Mensaje-de-error-de-un-simbolo-sin-un-valor" href="#Variable-vac_00eda">1.7.2 Mensaje de error de un símbolo sin un valor</a></li> - </ul></li> - <li><a name="toc-Argumentos-1" href="#Argumentos">1.8 Argumentos</a> - <ul class="no-bullet"> - <li><a name="toc-Tipos-de-argumentos-de-datos" href="#Tipos-de-datos">1.8.1 Tipos de argumentos de datos</a></li> - <li><a name="toc-Un-argumento-como-el-valor-de-una-variable-o-lista" href="#Argumentos-como-variables-o-listas">1.8.2 Un argumento como el valor de una variable o lista</a></li> - <li><a name="toc-Numero-de-variables-de-argumentos" href="#N_00famero-de-variables-de-argumentos">1.8.3 Número de variables de argumentos</a></li> - <li><a name="toc-Usando-el-tipo-incorrecto-de-objeto-como-un-argumento" href="#Tipo-incorrecto-de-argumento">1.8.4 Usando el tipo incorrecto de objeto como un argumento</a></li> - <li><a name="toc-La-funcion-message" href="#message">1.8.5 La función <code>message</code></a></li> - </ul></li> - <li><a name="toc-Configurando-el-valor-de-una-variable" href="#set-y-setq">1.9 Configurando el valor de una variable</a> - <ul class="no-bullet"> - <li><a name="toc-Usando-set-1" href="#Usando-set">1.9.1 Usando <code>set</code></a></li> - <li><a name="toc-Usando-setq-1" href="#Usando-setq">1.9.2 Usando <code>setq</code></a></li> - <li><a name="toc-Contando-1" href="#Contando">1.9.3 Contando</a></li> - </ul></li> - <li><a name="toc-Resumen-1" href="#Resumen">1.10 Resumen</a></li> - <li><a name="toc-Ejercicios-1" href="#Ejercicios-de-mensajes-de-error">1.11 Ejercicios</a></li> - </ul></li> - <li><a name="toc-Practicando-evaluacion" href="#Practicando-evaluaci_00f3n">2 Practicando evaluación</a> - <ul class="no-bullet"> - <li><a name="toc-Como-evaluar" href="#C_00f3mo-evaluar">Cómo evaluar</a></li> - <li><a name="toc-Nombres-de-buffer" href="#Nombres-de-b_00faffer">2.1 Nombres de búffer</a></li> - <li><a name="toc-Obteniendo-buffers" href="#Obteniendo-b_00faffers">2.2 Obteniendo búffers</a></li> - <li><a name="toc-Cambiando-buffers" href="#Cambiando-b_00faffers">2.3 Cambiando búffers</a></li> - <li><a name="toc-Tamano-de-buffer-y-la-ubicacion-del-punto" href="#Tama_00f1o-de-b_00faffer-y-localizaciones">2.4 Tamaño de búffer y la ubicación del punto</a></li> - <li><a name="toc-Ejercicio" href="#Ejercicio-de-evaluaci_00f3n">2.5 Ejercicio</a></li> - </ul></li> - <li><a name="toc-Como-escribir-definiciones-de-funciones" href="#Escribiendo-funciones">3 Cómo escribir definiciones de funciones</a> - <ul class="no-bullet"> - <li><a name="toc-Una-via-acerca-de-funciones-primitivas" href="#Funciones-primitivas">Una vía acerca de funciones primitivas</a></li> - <li><a name="toc-La-forma-especial-defun" href="#defun">3.1 La forma especial <code>defun</code></a></li> - <li><a name="toc-Instalar-una-definicion-de-funcion" href="#Instalar">3.2 Instalar una definición de función</a> - <ul class="no-bullet"> - <li><a name="toc-El-efecto-de-instalacion" href="#Efecto-de-instalaci_00f3n">El efecto de instalación</a></li> - <li><a name="toc-Cambiar-una-definicion-de-funcion" href="#Cambiar-un-defun">3.2.1 Cambiar una definición de función</a></li> - </ul></li> - <li><a name="toc-Crear-una-funcion-interactive" href="#Interactive">3.3 Crear una función interactive</a> - <ul class="no-bullet"> - <li><a name="toc-Un-multiply_002dby_002dseven-interactivo_002c-Un-resumen" href="#multiply_002dby_002dseven-interactivo">Un <code>multiply-by-seven</code> interactivo, Un resumen</a></li> - <li><a name="toc-multiplicar_002dpor_002dsiente-interactivo" href="#multiply_002dby_002dseven-en-detalle">3.3.1 <code>multiplicar-por-siente</code> interactivo</a></li> - </ul></li> - <li><a name="toc-Diferentes-opciones-para-interactive" href="#Opciones-de-interactive_002e">3.4 Diferentes opciones para <code>interactive</code></a></li> - <li><a name="toc-Instalar-codigo-permanentemente" href="#Instalaci_00f3n-Permanente">3.5 Instalar código permanentemente</a></li> - <li><a name="toc-let-1" href="#let">3.6 <code>let</code></a> - <ul class="no-bullet"> - <li><a name="toc-let-evita-confusiones" href="#Prevenir-confusi_00f3n"><code>let</code> evita confusiones</a></li> - <li><a name="toc-Las-partes-de-una-expresion-let" href="#Partes-de-la-expresi_00f3n-let">3.6.1 Las partes de una expresión <code>let</code></a></li> - <li><a name="toc-Ejemplo-de-Expresion-let" href="#Ejemplo-de-expresi_00f3n-let">3.6.2 Ejemplo de Expresión <code>let</code></a></li> - <li><a name="toc-Variables-sin-inicializar-en-un-sentencia-let" href="#Variables-let-inicializadas">3.6.3 Variables sin inicializar en un sentencia <code>let</code></a></li> - </ul></li> - <li><a name="toc-La-forma-especial-if" href="#if">3.7 La forma especial <code>if</code></a> - <ul class="no-bullet"> - <li><a name="toc-if-en-mas-detalle" href="#if-en-m_00e1s-detalle"><code>if</code> en más detalle</a></li> - <li><a name="toc-La-funcion-tipo_002dde_002danimal-en-detalle" href="#tipo_002dde_002danimal-en-detalle">3.7.1 La función <code>tipo-de-animal</code> en detalle</a></li> - </ul></li> - <li><a name="toc-Expresiones-if_002d_002dthen_002d_002delse" href="#else">3.8 Expresiones if–then–else</a></li> - <li><a name="toc-Verdad-y-falsedad-en-Emacs-Lisp" href="#Verdad-y-falsedad">3.9 Verdad y falsedad en Emacs Lisp</a> - <ul class="no-bullet"> - <li><a name="toc-Una-explicacion-de-nil" href="#nil-explicado">Una explicación de <code>nil</code></a></li> - </ul></li> - <li><a name="toc-save_002dexcursion-1" href="#save_002dexcursion">3.10 <code>save-excursion</code></a> - <ul class="no-bullet"> - <li><a name="toc-Punto-y-Marca" href="#Punto-y-marca">Punto y Marca</a></li> - <li><a name="toc-Plantilla-para-una-expresion-save_002dexcursion" href="#Plantilla-para-save_002dexcursion">3.10.1 Plantilla para una expresión <code>save-excursion</code></a></li> - </ul></li> - <li><a name="toc-Revisar-2" href="#Revisar">3.11 Revisar</a></li> - <li><a name="toc-Ejercicios" href="#Ejercicios-defun">3.12 Ejercicios</a></li> - </ul></li> - <li><a name="toc-Unas-pocas-funciones-de-buffer-relacionadas" href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers">4 Unas pocas funciones de buffer relacionadas</a> - <ul class="no-bullet"> - <li><a name="toc-Encontrando-mas-informacion" href="#Encontrando-m_00e1s">4.1 Encontrando más información</a></li> - <li><a name="toc-Una-definicion-simplificada-de-beginning_002dof_002dbuffer" href="#simplified_002dbeginning_002dof_002dbuffer">4.2 Una definición simplificada de <code>beginning-of-buffer</code></a></li> - <li><a name="toc-La-definicion-de-mark_002dwhole_002dbuffer" href="#mark_002dwhole_002dbuffer">4.3 La definición de <code>mark-whole-buffer</code></a> - <ul class="no-bullet"> - <li><a name="toc-Un-resumen-de-mark_002dwhole_002dbuffer" href="#resumen-de-mark_002dwhole_002dbuffer">Un resumen de <code>mark-whole-buffer</code></a></li> - <li><a name="toc-Cuerpo-de-mark_002dwhole_002dbuffer-1" href="#Cuerpo-de-mark_002dwhole_002dbuffer">4.3.1 Cuerpo de <code>mark-whole-buffer</code></a></li> - </ul></li> - <li><a name="toc-La-definicion-de-append_002dto_002dbuffer" href="#append_002dto_002dbuffer">4.4 La definición de <code>append-to-buffer</code></a> - <ul class="no-bullet"> - <li><a name="toc-Un-resumen-de-append_002dto_002dbuffer" href="#resumen-de-append_002dto_002dbuffer">Un resumen de <code>append-to-buffer</code></a></li> - <li><a name="toc-La-expresion-interactiva-append_002dto_002dbuffer" href="#append-interactivo">4.4.1 La expresión interactiva <code>append-to-buffer</code></a></li> - <li><a name="toc-El-cuerpo-de-append_002dto_002dbuffer" href="#cuerpo-append_002dto_002dbuffer">4.4.2 El cuerpo de <code>append-to-buffer</code></a></li> - <li><a name="toc-save_002dexcursion-en-append_002dto_002dbuffer" href="#append-save_002dexcursion">4.4.3 <code>save-excursion</code> en <code>append-to-buffer</code></a></li> - </ul></li> - <li><a name="toc-Revisar-3" href="#Revisa-lo-relacionado-con-el-b_00faffer">4.5 Revisar</a></li> - <li><a name="toc-Ejercicios-2" href="#Ejercicios-de-b_00faffer">4.6 Ejercicios</a></li> - </ul></li> - <li><a name="toc-Unas-pocas-funciones-mas-complejas" href="#M_00e1s-complejidad">5 Unas pocas funciones más complejas</a> - <ul class="no-bullet"> - <li><a name="toc-La-definicion-de-copy_002dto_002dbuffer" href="#copy_002dto_002dbuffer">5.1 La definición de <code>copy-to-buffer</code></a></li> - <li><a name="toc-La-definicion-de-insert_002dbuffer" href="#insert_002dbuffer">5.2 La definición de <code>insert-buffer</code></a> - <ul class="no-bullet"> - <li><a name="toc-El-codigo-para-insert_002dbuffer" href="#c_00f3digo-insert_002dbuffer">El código para <code>insert-buffer</code></a></li> - <li><a name="toc-La-expresion-interactiva-en-insert_002dbuffer" href="#insert_002dbuffer-interactivo">5.2.1 La expresión interactiva en <code>insert-buffer</code></a> - <ul class="no-bullet"> - <li><a name="toc-Un-buffer-de-solo-lectura" href="#B_00faffer-solo-lectura">Un búffer de solo lectura</a></li> - <li><a name="toc-b-en-una-expresion-interactiva" href="#b-para-interactivo">‘<samp>b</samp>’ en una expresión interactiva</a></li> - </ul></li> - <li><a name="toc-El-cuerpo-de-la-funcion-insert_002dbuffer" href="#cuerpo-insert_002dbuffer">5.2.2 El cuerpo de la función <code>insert-buffer</code></a></li> - <li><a name="toc-insert_002dbuffer-con-un-if-en-vez-de-un-or" href="#si-y-o">5.2.3 <code>insert-buffer</code> con un <code>if</code> en vez de un <code>or</code></a></li> - <li><a name="toc-El-or-en-el-cuerpo" href="#Insertar-o">5.2.4 El <code>or</code> en el cuerpo</a></li> - <li><a name="toc-La-expresion-let-en-insert_002dbuffer" href="#Insertar-let">5.2.5 La expresión <code>let</code> en <code>insert-buffer</code></a></li> - <li><a name="toc-Nuevo-cuerpo-para-insert_002dbuffer" href="#Nuevo-insert_002dbuffer">5.2.6 Nuevo cuerpo para <code>insert-buffer</code></a></li> - </ul></li> - <li><a name="toc-Definicion-completa-de-beginning_002dof_002dbuffer" href="#beginning_002dof_002dbuffer">5.3 Definición completa de <code>beginning-of-buffer</code></a> - <ul class="no-bullet"> - <li><a name="toc-Argumentos-opcionales-1" href="#Argumentos-opcionales">5.3.1 Argumentos opcionales</a></li> - <li><a name="toc-beginning_002dof_002dbuffer-con-un-argumento" href="#beginning_002dof_002dbuffer-opt-arg">5.3.2 <code>beginning-of-buffer</code> con un argumento</a> - <ul class="no-bullet"> - <li><a name="toc-Desenmaranar-beginning_002dof_002dbuffer" href="#Desenmara_00f1ar-beginning_002dof_002dbuffer">Desenmarañar <code>beginning-of-buffer</code></a></li> - <li><a name="toc-Que-ocurre-en-un-buffer-largo" href="#El-caso-del-buffer-largo">Qué ocurre en un búffer largo</a></li> - <li><a name="toc-Que-ocurre-en-un-buffer-pequeno" href="#Peque_00f1o-caso-de-b_00faffer">Qué ocurre en un búffer pequeño</a></li> - </ul></li> - <li><a name="toc-El-beginning_002dof_002dbuffer-completo" href="#Completo-beginning_002dof_002dbuffer">5.3.3 El <code>beginning-of-buffer</code> completo</a></li> - </ul></li> - <li><a name="toc-Revisar-1" href="#Revisar-el-segundo-b_00faffer-relacionado">5.4 Revisar</a></li> - <li><a name="toc-Ejercicio-de-argumento-opcional" href="#Ejercicio-opcional">5.5 Ejercicio de argumento <code>opcional</code></a></li> - </ul></li> - <li><a name="toc-Encogiendo-y-extendiendo-1" href="#Encogiendo-y-extendiendo">6 Encogiendo y extendiendo</a> - <ul class="no-bullet"> - <li><a name="toc-Las-ventajas-de-encoger" href="#Ventajas-de-encoger">Las ventajas de encoger</a></li> - <li><a name="toc-La-forma-especial-save_002drestriction" href="#save_002drestriction">6.1 La forma especial <code>save-restriction</code></a></li> - <li><a name="toc-what_002dline-1" href="#what_002dline">6.2 <code>what-line</code></a></li> - <li><a name="toc-Ejercicio-de-encoger" href="#Ejercicio-narrow">6.3 Ejercicio de encoger</a></li> - </ul></li> - <li><a name="toc-car_002c-cdr_002c-cons_003a-Funciones-fundamentales" href="#Car-cdr-y-cons">7 <code>car</code>, <code>cdr</code>, <code>cons</code>: Funciones fundamentales</a> - <ul class="no-bullet"> - <li><a name="toc-Nombres-extranos" href="#Nombres-extra_00f1os">Nombres extraños</a></li> - <li><a name="toc-car-y-cdr-1" href="#car-y-cdr">7.1 <code>car</code> y <code>cdr</code></a></li> - <li><a name="toc-cons-1" href="#cons">7.2 <code>cons</code></a> - <ul class="no-bullet"> - <li><a name="toc-Construir-una-lista-1" href="#Construir-una-lista">Construir una lista</a></li> - <li><a name="toc-Encuentra-el-tamano-de-una-lista_003a-length" href="#length">7.2.1 Encuentra el tamaño de una lista: <code>length</code></a></li> - </ul></li> - <li><a name="toc-nthcdr-1" href="#nthcdr">7.3 <code>nthcdr</code></a></li> - <li><a name="toc-nth-1" href="#nth">7.4 <code>nth</code></a></li> - <li><a name="toc-setcar-1" href="#setcar">7.5 <code>setcar</code></a></li> - <li><a name="toc-setcdr-1" href="#setcdr">7.6 <code>setcdr</code></a></li> - <li><a name="toc-Ejercicio-2" href="#Ejercicio-cons">7.7 Ejercicio</a></li> - </ul></li> - <li><a name="toc-Cortando-y-almacenando-texto-1" href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a> - <ul class="no-bullet"> - <li><a name="toc-Almacenando-texto-en-una-lista" href="#Almacenando-Texto">Almacenando texto en una lista</a></li> - <li><a name="toc-zap_002dto_002dchar-1" href="#zap_002dto_002dchar">8.1 <code>zap-to-char</code></a> - <ul class="no-bullet"> - <li><a name="toc-La-implementacion-completa-zap_002dto_002dchar" href="#Completar-zap_002dto_002dchar">La implementación completa <code>zap-to-char</code></a></li> - <li><a name="toc-La-expresion-interactive" href="#zap_002dto_002dchar-interactivo">8.1.1 La expresión <code>interactive</code></a></li> - <li><a name="toc-El-cuerpo-de-zap_002dto_002dchar" href="#cuerpo-zap_002dto_002dchar">8.1.2 El cuerpo de <code>zap-to-char</code></a></li> - <li><a name="toc-La-funcion-search_002dforward" href="#search_002dforward">8.1.3 La función <code>search-forward</code></a></li> - <li><a name="toc-La-forma-especial-progn" href="#progn">8.1.4 La forma especial <code>progn</code></a></li> - <li><a name="toc-Resumiendo-zap_002dto_002dchar-1" href="#Resumiendo-zap_002dto_002dchar">8.1.5 Resumiendo <code>zap-to-char</code></a></li> - </ul></li> - <li><a name="toc-kill_002dregion-1" href="#kill_002dregion">8.2 <code>kill-region</code></a> - <ul class="no-bullet"> - <li><a name="toc-La-definicion-completa-kill_002dregion" href="#Completa-kill_002dregion">La definición completa <code>kill-region</code></a></li> - <li><a name="toc-condition_002dcase-1" href="#condition_002dcase">8.2.1 <code>condition-case</code></a></li> - <li><a name="toc-Macro-Lisp-1" href="#Macro-Lisp">8.2.2 Macro Lisp</a></li> - </ul></li> - <li><a name="toc-copy_002dregion_002das_002dkill-1" href="#copy_002dregion_002das_002dkill">8.3 <code>copy-region-as-kill</code></a> - <ul class="no-bullet"> - <li><a name="toc-La-definicion-de-la-funcion-completa-copy_002dregion_002das_002dkill_002e" href="#Completar-copy_002dregion_002das_002dkill">La definición de la función completa <code>copy-region-as-kill</code>.</a></li> - <li><a name="toc-El-cuerpo-de-copy_002dregion_002das_002dkill" href="#cuerpo-copy_002dregion_002das_002dkill">8.3.1 El cuerpo de <code>copy-region-as-kill</code></a> - <ul class="no-bullet"> - <li><a name="toc-last_002dcommand-y-this_002dcommand" href="#last_002dcommand-_0026-this_002dcommand"><code>last-command</code> y <code>this-command</code></a></li> - <li><a name="toc-La-funcion-kill_002dappend" href="#Funci_00f3n-kill_002dappend">La función <code>kill-append</code></a></li> - <li><a name="toc-La-funcion-kill_002dnew" href="#Funci_00f3n-kill_002dnew">La función <code>kill-new</code></a></li> - </ul> -</li> - </ul></li> - <li><a name="toc-Disgresion-dentro-de-C" href="#Disgresi_00f3n-dentro-de-C">8.4 Disgresión dentro de C</a></li> - <li><a name="toc-Inicializando-una-variable-con-defvar" href="#defvar">8.5 Inicializando una variable con <code>defvar</code></a> - <ul class="no-bullet"> - <li><a name="toc-Mirando-el-actual-valor-de-una-variable" href="#Mira-el-valor-actual-de-la-variable">Mirando el actual valor de una variable</a></li> - <li><a name="toc-defvar-y-un-asterisco" href="#defvar-y-asterisk">8.5.1 <code>defvar</code> y un asterisco</a></li> - </ul></li> - <li><a name="toc-Revisar-4" href="#Revisi_00f3n-de-cons-y-search_002dfwd">8.6 Revisar</a></li> - <li><a name="toc-Buscando-ejercicios" href="#Buscar-ejercicios">8.7 Buscando ejercicios</a></li> - </ul></li> - <li><a name="toc-Como-las-listas-se-implementan" href="#Implementaci_00f3n-de-listas">9 Cómo las listas se implementan</a> - <ul class="no-bullet"> - <li><a name="toc-Listas-diagramadas-1" href="#Listas-diagramadas">Listas diagramadas</a></li> - <li><a name="toc-Simbolos-como-una-caja-con-cajones" href="#S_00edmbolos-como-cajas">9.1 Símbolos como una caja con cajones</a></li> - <li><a name="toc-Ejercicio-1" href="#Ejercicio-Lista">9.2 Ejercicio</a></li> - </ul></li> - <li><a name="toc-Pegando-texto" href="#Pegando">10 Pegando texto</a> - <ul class="no-bullet"> - <li><a name="toc-Resumen-del-anillo-de-la-muerte-1" href="#Resumen-del-anillo-de-la-muerte">10.1 Resumen del anillo de la muerte</a></li> - <li><a name="toc-La-variable-kill_002dring_002dyank_002dpointer" href="#kill_002dring_002dyank_002dpointer">10.2 La variable <code>kill-ring-yank-pointer</code></a></li> - <li><a name="toc-Ejercicios-con-yank-y-nthcdr" href="#pegar-Ejercicio-nthcdr">10.3 Ejercicios con <code>yank</code> y <code>nthcdr</code></a></li> - </ul></li> - <li><a name="toc-Bucles-y-recursion" href="#Bucles-y-recursi_00f3n">11 Bucles y recursión</a> - <ul class="no-bullet"> - <li><a name="toc-while-1" href="#while">11.1 <code>while</code></a> - <ul class="no-bullet"> - <li><a name="toc-Bucles-con-while" href="#Bucles-while">Bucles con <code>while</code></a></li> - <li><a name="toc-Un-bucle-while-y-una-lista" href="#Ejemplo-de-bucle">11.1.1 Un bucle <code>while</code> y una lista</a></li> - <li><a name="toc-Un-ejemplo_003a-imprimir_002delementos_002dde_002dla_002dlista" href="#print_002delements_002dof_002dlist">11.1.2 Un ejemplo: <code>imprimir-elementos-de-la-lista</code></a></li> - <li><a name="toc-Un-bucle-con-un-contaje-incremental" href="#Incrementando-el-Bucle">11.1.3 Un bucle con un contaje incremental</a></li> - <li><a name="toc-Detalles-de-un-bucle-que-se-incrementa" href="#Incrementando-los-detalles-de-los-bucles">Detalles de un bucle que se incrementa</a> - <ul class="no-bullet"> - <li><a name="toc-Ejemplo-con-contador-incremental" href="#Ejemplo-de-Incremento">Ejemplo con contador incremental</a></li> - <li><a name="toc-Las-partes-de-la-definicion-de-funcion" href="#Partes-Inc-de-Ejemplo">Las partes de la definición de función</a></li> - <li><a name="toc-Poniendo-la-definicion-de-la-funcion-junta" href="#Ejemplo-Inc-junto">Poniendo la definición de la función junta</a></li> - </ul></li> - <li><a name="toc-Bucle-que-decrementa" href="#Bucle-que-se-decrementa">11.1.4 Bucle que decrementa</a> - <ul class="no-bullet"> - <li><a name="toc-Ejemplo-con-el-contador-que-se-decrementa" href="#Ejemplo-de-Decremento">Ejemplo con el contador que se decrementa</a></li> - <li><a name="toc-Las-partes-de-la-definicion-de-funcion-1" href="#Partes-de-Ejemplo-Dec">Las partes de la definición de función</a></li> - <li><a name="toc-Poniendo-la-definicion-de-la-funcion-junta-1" href="#Ejemplo-Dec-junto">Poniendo la definición de la función junta</a></li> - </ul> -</li> - </ul></li> - <li><a name="toc-Ahorra-tiempo_003a-dolist-y-dotimes" href="#Dolist-y-dotimes">11.2 Ahorra tiempo: <code>dolist</code> y <code>dotimes</code></a> - <ul class="no-bullet"> - <li><a name="toc-La-macro-dolist" href="#dolist">La macro <code>dolist</code></a></li> - <li><a name="toc-La-macro-dotimes" href="#dotimes">La macro <code>dotimes</code></a></li> - </ul></li> - <li><a name="toc-Recursion" href="#Recursi_00f3n">11.3 Recursión</a> - <ul class="no-bullet"> - <li><a name="toc-Construyendo-robots_003a-Extendiendo-la-metafora" href="#Construyendo-robots">11.3.1 Construyendo robots: Extendiendo la metáfora</a></li> - <li><a name="toc-Las-partes-de-una-definicion-recursiva" href="#Partes-de-definici_00f3n-recursiva">11.3.2 Las partes de una definición recursiva</a></li> - <li><a name="toc-Recursion-con-una-lista" href="#Recursi_00f3n-con-lista">11.3.3 Recursión con una lista</a></li> - <li><a name="toc-Recursion-en-lugar-de-un-contador" href="#Funci_00f3n-recursiva-tri_00e1ngulo">11.3.4 Recursión en lugar de un contador</a> - <ul class="no-bullet"> - <li><a name="toc-Un-argumento-de-1-o-2" href="#Ejemplo-recursivo-y-argumento-con-valor-1-o-2">Un argumento de 1 o 2</a></li> - <li><a name="toc-Un-argumento-de-3-o-4" href="#Ejemplo-Recursivo-de-3-o-4-argumentos">Un argumento de 3 o 4</a></li> - </ul></li> - <li><a name="toc-Ejemplo-de-recursion-usando-cond" href="#Recursi_00f3n-con-cond">11.3.5 Ejemplo de recursión usando <code>cond</code></a></li> - <li><a name="toc-Patrones-recursivos-1" href="#Patrones-recursivos">11.3.6 Patrones recursivos</a> - <ul class="no-bullet"> - <li><a name="toc-Patron-recursivo_003a-every" href="#Cada">Patrón recursivo: <em>every</em></a></li> - <li><a name="toc-Patron-recursivo_003a-accumulate" href="#Acumular">Patrón recursivo: <em>accumulate</em></a></li> - <li><a name="toc-Patron-recursivo_003a-keep" href="#Guardar">Patrón recursivo: <em>keep</em></a></li> - </ul></li> - <li><a name="toc-Recursion-sin-diferir" href="#Sin-Aplazar">11.3.7 Recursión sin diferir</a></li> - <li><a name="toc-No-hay-solucion-pospuesta" href="#No-aplazar-la-soluci_00f3n">11.3.8 No hay solución pospuesta</a></li> - </ul></li> - <li><a name="toc-Ejercicio-de-bucles" href="#Ejercicio-de-Bucle">11.4 Ejercicio de bucles</a></li> - </ul></li> - <li><a name="toc-Busquedas-de-expresiones-regulares" href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a> - <ul class="no-bullet"> - <li><a name="toc-La-expresion-regular-para-sentence_002dend" href="#sentence_002dend">12.1 La expresión regular para <code>sentence-end</code></a></li> - <li><a name="toc-La-funcion-re_002dsearch_002dforward" href="#re_002dsearch_002dforward">12.2 La función <code>re-search-forward</code></a></li> - <li><a name="toc-forward_002dsentence-1" href="#forward_002dsentence">12.3 <code>forward-sentence</code></a> - <ul class="no-bullet"> - <li><a name="toc-Completa-la-definicion-forward_002dsentence" href="#Completa-forward_002dsentence">Completa la definición <code>forward-sentence</code></a></li> - <li><a name="toc-Los-bucles-while" href="#Bucles-while-fwd_002dsentence">Los bucles <code>while</code></a></li> - <li><a name="toc-La-busqueda-de-expresiones-regulares" href="#Volver-a-buscar-la-frase-en-sentido-directo">La búsqueda de expresiones regulares</a></li> - </ul></li> - <li><a name="toc-forward_002dparagraph_003a-una-mina-de-oro-de-funciones" href="#forward_002dparagraph">12.4 <code>forward-paragraph</code>: una mina de oro de funciones</a> - <ul class="no-bullet"> - <li><a name="toc-Definicion-de-funcion-forward_002dparagraph" href="#forward_002dparagraph-en-breve">Definición de función <code>forward-paragraph</code></a></li> - <li><a name="toc-La-expresion-let_002a" href="#fwd_002dpara-let">La expresión <code>let*</code></a></li> - <li><a name="toc-El-bucle-while-hacia-adelante" href="#fwd_002dpara-while">El bucle <code>while</code> hacia adelante</a></li> - </ul></li> - <li><a name="toc-Crea-tu-propio-fichero-TAGS" href="#etags">12.5 Crea tu propio fichero ‘<tt>TAGS</tt>’</a></li> - <li><a name="toc-Revisar-5" href="#Revisar-regexp">12.6 Revisar</a></li> - <li><a name="toc-Ejercicios-con-re_002dsearch_002dforward" href="#Ejercicios-re_002dsearch">12.7 Ejercicios con <code>re-search-forward</code></a></li> - </ul></li> - <li><a name="toc-Contando_003a-repeticion-y-regexps" href="#Contando-palabras">13 Contando: repetición y regexps</a> - <ul class="no-bullet"> - <li><a name="toc-Contando-palabras-1" href="#Por-qu_00e9-Contar-Palabras">Contando palabras</a></li> - <li><a name="toc-La-funcion-count_002dwords_002dexample" href="#count_002dwords_002dexample">13.1 La función <code>count-words-example</code></a> - <ul class="no-bullet"> - <li><a name="toc-Disenando-count_002dwords_002dexample" href="#Dise_00f1ar-count_002dwords_002dexample">Diseñando <code>count-words-example</code></a></li> - <li><a name="toc-El-error-de-espacio-en-blanco-en-count_002dwords_002dexample" href="#Error-de-espacio-en-blanco">13.1.1 El error de espacio en blanco en <code>count-words-example</code></a></li> - </ul></li> - <li><a name="toc-Cuenta-palabras-recursivamente" href="#recursive_002dcount_002dwords">13.2 Cuenta palabras recursivamente</a></li> - <li><a name="toc-Ejercicio_003a-contando-puntuacion" href="#Ejercicio-de-Contar">13.3 Ejercicio: contando puntuación</a></li> - </ul></li> - <li><a name="toc-Contando-palabras-en-una-defun" href="#Palabras-en-una-funci_00f3n">14 Contando palabras en una <code>defun</code></a> - <ul class="no-bullet"> - <li><a name="toc-Divide-y-venceras" href="#Divide-y-vencer_00e1s">Divide y vencerás</a></li> - <li><a name="toc-_00bfQue-contar_003f" href="#Palabras-y-S_00edmbolos">14.1 ¿Qué contar?</a></li> - <li><a name="toc-_00bfQue-constituye-una-palabra-o-simbolo_003f" href="#Sintaxis">14.2 ¿Qué constituye una palabra o símbolo?</a></li> - <li><a name="toc-La-funcion-count_002dwords_002din_002ddefun" href="#count_002dwords_002din_002ddefun">14.3 La función <code>count-words-in-defun</code></a></li> - <li><a name="toc-Contar-varias-defuns-en-un-fichero" href="#Varias-funciones">14.4 Contar varias <code>defuns</code> en un fichero</a></li> - <li><a name="toc-Encontrar-un-fichero-1" href="#Encontrar-un-fichero">14.5 Encontrar un fichero</a></li> - <li><a name="toc-lengths_002dlist_002dfile-en-detalle" href="#lengths_002dlist_002dfile">14.6 <code>lengths-list-file</code> en detalle</a></li> - <li><a name="toc-Contar-palabras-en-defuns-en-diferentes-ficheros" href="#Varios-ficheros">14.7 Contar palabras en <code>defuns</code> en diferentes ficheros</a> - <ul class="no-bullet"> - <li><a name="toc-Determina-las-longitudes-de-defuns" href="#lengths_002dlist_002dmany_002dfiles">Determina las longitudes de <code>defuns</code></a></li> - <li><a name="toc-La-funcion-append" href="#append">14.7.1 La función <code>append</code></a></li> - </ul></li> - <li><a name="toc-Recursivamente-cuenta-palabras-en-diferentes-ficheros" href="#Varios-ficheros-recursivamente">14.8 Recursivamente cuenta palabras en diferentes ficheros</a></li> - <li><a name="toc-Preparar-los-datos-para-mostrarlos-en-un-grafo" href="#Preparar-los-datos">14.9 Preparar los datos para mostrarlos en un grafo</a> - <ul class="no-bullet"> - <li><a name="toc-El-dato-para-mostrar-en-detalle" href="#Datos-para-mostrar-en-detalle">El dato para mostrar en detalle</a></li> - <li><a name="toc-Ordenando-listas" href="#Ordenando">14.9.1 Ordenando listas</a></li> - <li><a name="toc-Creando-una-lista-de-ficheros" href="#Listar-ficheros">14.9.2 Creando una lista de ficheros</a></li> - <li><a name="toc-Contando-definiciones-de-funcion" href="#Contando-definiciones-de-funci_00f3n">14.9.3 Contando definiciones de función</a></li> - </ul> -</li> - </ul></li> - <li><a name="toc-Leyendo-un-grafo-1" href="#Leyendo-un-grafo">15 Leyendo un grafo</a> - <ul class="no-bullet"> - <li><a name="toc-Imprimiendo-las-columnas-de-un-grafo" href="#Columnas-de-un-grafo">Imprimiendo las columnas de un grafo</a></li> - <li><a name="toc-La-funcion-graph_002dbody_002dprint" href="#graph_002dbody_002dprint">15.1 La función <code>graph-body-print</code></a></li> - <li><a name="toc-La-funcion-recursive_002dgraph_002dbody_002dprint" href="#recursive_002dgraph_002dbody_002dprint">15.2 La función <code>recursive-graph-body-print</code></a></li> - <li><a name="toc-Necesidad-para-ejes-impresos" href="#Ejes-Impresos">15.3 Necesidad para ejes impresos</a></li> - <li><a name="toc-Ejercicio-3" href="#Ejercicio-de-L_00ednea-de-Grafo">15.4 Ejercicio</a></li> - </ul></li> - <li><a name="toc-Tu-fichero-_002eemacs" href="#Inicializaci_00f3n-de-Emacs">16 Tu fichero ‘<tt>.emacs</tt>’</a> - <ul class="no-bullet"> - <li><a name="toc-Configuracion-por-defecto-de-Emacs" href="#Configuraci_00f3n-por-defecto">Configuración por defecto de Emacs</a></li> - <li><a name="toc-Fichero-de-inicializacion-site_002dwide" href="#Site_002dwide-Init">16.1 Fichero de inicialización site-wide</a></li> - <li><a name="toc-Especificar-variables-usando-defcustom" href="#defcustom">16.2 Especificar variables usando <code>defcustom</code></a></li> - <li><a name="toc-Empieza-por-un-fichero-_002eemacs" href="#Empezando-un-fichero-_002eemacs">16.3 Empieza por un fichero ‘<tt>.emacs</tt>’</a></li> - <li><a name="toc-Modo-texto-y-auto-relleno" href="#Texto-y-Autorelleno">16.4 Modo texto y auto relleno</a></li> - <li><a name="toc-Alias-de-correo-1" href="#Alias-de-correo">16.5 Alias de correo</a></li> - <li><a name="toc-Indentar-modo-de-tabulaciones-1" href="#Indentar-modo-de-tabulaciones">16.6 Indentar modo de tabulaciones</a></li> - <li><a name="toc-Algunos-atajos" href="#Atajos-de-teclado">16.7 Algunos atajos</a></li> - <li><a name="toc-Mapas-de-teclado-1" href="#Mapas-de-teclado">16.8 Mapas de teclado</a></li> - <li><a name="toc-Cargando-ficheros-1" href="#Cargando-ficheros">16.9 Cargando ficheros</a></li> - <li><a name="toc-Autoloading" href="#Autocarga">16.10 Autoloading</a></li> - <li><a name="toc-Una-extension-simple_003a-line_002dto_002dtop_002dof_002dwindow" href="#Extensi_00f3n-simple">16.11 Una extensión simple: <code>line-to-top-of-window</code></a></li> - <li><a name="toc-Colores-X11-1" href="#Colores-X11">16.12 Colores X11</a></li> - <li><a name="toc-Configuraciones-miscelaneas-para-un-fichero-_002eemacs" href="#Miscel_00e1nea">16.13 Configuraciones misceláneas para un fichero ‘<tt>.emacs</tt>’</a></li> - <li><a name="toc-Una-linea-modificada" href="#Mode-Line">16.14 Una línea modificada</a></li> - </ul></li> - <li><a name="toc-Depurando-1" href="#Depurando">17 Depurando</a> - <ul class="no-bullet"> - <li><a name="toc-depurar-1" href="#depurar">17.1 <code>depurar</code></a></li> - <li><a name="toc-debug_002don_002dentry-1" href="#debug_002don_002dentry">17.2 <code>debug-on-entry</code></a></li> - <li><a name="toc-debug_002don_002dquit-y-_0028debug_0029" href="#debug_002don_002dquit">17.3 <code>debug-on-quit</code> y <code>(debug)</code></a></li> - <li><a name="toc-El-depurador-de-nivel-de-fuentes-edebug" href="#edebug">17.4 El depurador de nivel de fuentes <code>edebug</code></a></li> - <li><a name="toc-Ejercicios-de-depuracion" href="#Ejercicios-de-depuraci_00f3n">17.5 Ejercicios de depuración</a></li> - </ul></li> - <li><a name="toc-Conclusion" href="#Conclusi_00f3n">18 Conclusión</a></li> - <li><a name="toc-La-funcion-the_002dthe" href="#the_002dthe">Appendix A La función <code>the-the</code></a></li> - <li><a name="toc-Manejando-el-anillo-de-la-muerte" href="#Kill-Ring">Appendix B Manejando el anillo de la muerte</a> - <ul class="no-bullet"> - <li><a name="toc-Que-hace-el-anillo-de-la-muerte" href="#Qu_00e9-hace-el-anillo-de-la-muerte">Qué hace el anillo de la muerte</a></li> - <li><a name="toc-La-funcion-current_002dkill" href="#current_002dkill">B.1 La función <code>current-kill</code></a> - <ul class="no-bullet"> - <li><a name="toc-El-codigo-current_002dkill" href="#C_00f3digo-para-current_002dkill">El código <code>current-kill</code></a></li> - <li><a name="toc-current_002dkill-en-outline" href="#Comprendiendo-current_002dkill"><code>current-kill</code> en outline</a> - <ul class="no-bullet"> - <li><a name="toc-El-cuerpo-de-current_002dkill" href="#Cuerpo-de-current_002dkill">El cuerpo de <code>current-kill</code></a></li> - <li><a name="toc-Disgresion-acerca-de-la-palabra-_0060error_0027" href="#Disgresi_00f3n-concerniente-de-error">Disgresión acerca de la palabra ‘error’</a></li> - <li><a name="toc-Determinando-el-elemento-1" href="#Determinando-el-elemento">Determinando el elemento</a></li> - </ul> -</li> - </ul></li> - <li><a name="toc-pegar-1" href="#pegar">B.2 <code>pegar</code></a></li> - <li><a name="toc-yank_002dpop-1" href="#yank_002dpop">B.3 <code>yank-pop</code></a></li> - <li><a name="toc-El-fichero-ring_002eel" href="#fichero-anillo">B.4 El fichero ‘<tt>ring.el</tt>’</a></li> - </ul></li> - <li><a name="toc-Un-grafo-con-ejes-etiquetados" href="#Grafo-completo">Appendix C Un grafo con ejes etiquetados</a> - <ul class="no-bullet"> - <li><a name="toc-Grafo-de-ejemplo-etiquetado" href="#Ejemplo-etiquetado">Grafo de ejemplo etiquetado</a></li> - <li><a name="toc-La-varlist-print_002dgraph" href="#print_002dgraph-Varlist">C.1 La varlist <code>print-graph</code></a></li> - <li><a name="toc-La-funcion-print_002dY_002daxis" href="#print_002dY_002daxis">C.2 La función <code>print-Y-axis</code></a> - <ul class="no-bullet"> - <li><a name="toc-La-funcion-print_002dY_002daxis-en-detalle" href="#print_002dY_002daxis-en-Detalle">La función <code>print-Y-axis</code> en detalle</a></li> - <li><a name="toc-_00bfA-que-altura-se-deberia-etiquetar_003f" href="#Altura-de-etiqueta">¿A qué altura se debería etiquetar?</a></li> - <li><a name="toc-Viaje-lateral_003a-Calcula-un-resto" href="#Calcular-un-resto">C.2.1 Viaje lateral: Calcula un resto</a></li> - <li><a name="toc-Construye-un-elemento-del-eje-Y" href="#Elemento-del-Eje-Y">C.2.2 Construye un elemento del eje Y</a></li> - <li><a name="toc-Crea-un-eje-de-la-columna-Y" href="#Y_002daxis_002dcolumn">C.2.3 Crea un eje de la columna Y</a></li> - <li><a name="toc-La-version-no-demasiado-final-de-print_002dY_002daxis" href="#Pen_00faltimo-print_002dY_002daxis">C.2.4 La versión no demasiado final de <code>print-Y-axis</code></a></li> - </ul></li> - <li><a name="toc-La-funcion-print_002dX_002daxis" href="#print_002dX_002daxis">C.3 La función <code>print-X-axis</code></a> - <ul class="no-bullet"> - <li><a name="toc-Similaridades-y-diferencias" href="#Diferencias-similares">Similaridades y diferencias</a></li> - <li><a name="toc-Eje-X-marca-tic-1" href="#Eje-X-marca-tic">C.3.1 Eje X marca tic</a></li> - </ul></li> - <li><a name="toc-Imprimiendo-el-grafo-completo" href="#Imprimir-Grafo-Entero">C.4 Imprimiendo el grafo completo</a> - <ul class="no-bullet"> - <li><a name="toc-Cambios-para-la-version-final" href="#La-versi_00f3n-final">Cambios para la versión final</a></li> - <li><a name="toc-Testeando-print_002dgraph" href="#Testear-print_002dgraph">C.4.1 Testeando <code>print-graph</code></a></li> - <li><a name="toc-Creando-graficas-de-numeros-de-palabras-y-simbolos" href="#Graficar-palabras-en-funciones">C.4.2 Creando gráficas de números de palabras y símbolos</a></li> - <li><a name="toc-Una-expresion-lambda_003a-Anonimicidad-util" href="#lambda">C.4.3 Una expresión <code>lambda</code>: Anonimicidad útil</a></li> - <li><a name="toc-La-funcion-mapcar" href="#mapcar">C.4.4 La función <code>mapcar</code></a></li> - <li><a name="toc-Otro-error-_2026-mas-insidioso" href="#Otro-Error">C.4.5 Otro error … más insidioso</a></li> - <li><a name="toc-El-grafico-impreso" href="#Grafo-impreso-final">C.4.6 El gráfico impreso</a></li> - </ul> -</li> - </ul></li> - <li><a name="toc-Software-Libre-y-Manuales-Libres-1" href="#Software-Libre-y-Manuales-Libres">Appendix D Software Libre y Manuales Libres</a></li> - <li><a name="toc-GNU-Free-Documentation-License-1" href="#GNU-Free-Documentation-License">Appendix E GNU Free Documentation License</a></li> - <li><a name="toc-Indice" href="#g_t_00cdndice">Índice</a></li> - <li><a name="toc-Acerca-del-Autor-1" href="#Acerca-del-Autor">Acerca del Autor</a></li> -</ul> -</div> -<hr> -<a name="SEC_Overview"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<h1>Resumen del Contenido</h1> - -<div class="shortcontents"> -<ul class="no-bullet"> -<li><a name="stoc-Prefacio-1" href="#Prefacio">Prefacio</a></li> -<li><a name="stoc-Procesamiento-de-listas-1" href="#Procesamiento-de-listas">1 Procesamiento de listas</a></li> -<li><a name="stoc-Practicando-evaluacion" href="#Practicando-evaluaci_00f3n">2 Practicando evaluación</a></li> -<li><a name="stoc-Como-escribir-definiciones-de-funciones" href="#Escribiendo-funciones">3 Cómo escribir definiciones de funciones</a></li> -<li><a name="stoc-Unas-pocas-funciones-de-buffer-relacionadas" href="#Un-paseo-a-trav_00e9s-de-los-b_00faffers">4 Unas pocas funciones de buffer relacionadas</a></li> -<li><a name="stoc-Unas-pocas-funciones-mas-complejas" href="#M_00e1s-complejidad">5 Unas pocas funciones más complejas</a></li> -<li><a name="stoc-Encogiendo-y-extendiendo-1" href="#Encogiendo-y-extendiendo">6 Encogiendo y extendiendo</a></li> -<li><a name="stoc-car_002c-cdr_002c-cons_003a-Funciones-fundamentales" href="#Car-cdr-y-cons">7 <code>car</code>, <code>cdr</code>, <code>cons</code>: Funciones fundamentales</a></li> -<li><a name="stoc-Cortando-y-almacenando-texto-1" href="#Cortando-y-almacenando-texto">8 Cortando y almacenando texto</a></li> -<li><a name="stoc-Como-las-listas-se-implementan" href="#Implementaci_00f3n-de-listas">9 Cómo las listas se implementan</a></li> -<li><a name="stoc-Pegando-texto" href="#Pegando">10 Pegando texto</a></li> -<li><a name="stoc-Bucles-y-recursion" href="#Bucles-y-recursi_00f3n">11 Bucles y recursión</a></li> -<li><a name="stoc-Busquedas-de-expresiones-regulares" href="#Buscar-regexp">12 Búsquedas de expresiones regulares</a></li> -<li><a name="stoc-Contando_003a-repeticion-y-regexps" href="#Contando-palabras">13 Contando: repetición y regexps</a></li> -<li><a name="stoc-Contando-palabras-en-una-defun" href="#Palabras-en-una-funci_00f3n">14 Contando palabras en una <code>defun</code></a></li> -<li><a name="stoc-Leyendo-un-grafo-1" href="#Leyendo-un-grafo">15 Leyendo un grafo</a></li> -<li><a name="stoc-Tu-fichero-_002eemacs" href="#Inicializaci_00f3n-de-Emacs">16 Tu fichero ‘<tt>.emacs</tt>’</a></li> -<li><a name="stoc-Depurando-1" href="#Depurando">17 Depurando</a></li> -<li><a name="stoc-Conclusion" href="#Conclusi_00f3n">18 Conclusión</a></li> -<li><a name="stoc-La-funcion-the_002dthe" href="#the_002dthe">Appendix A La función <code>the-the</code></a></li> -<li><a name="stoc-Manejando-el-anillo-de-la-muerte" href="#Kill-Ring">Appendix B Manejando el anillo de la muerte</a></li> -<li><a name="stoc-Un-grafo-con-ejes-etiquetados" href="#Grafo-completo">Appendix C Un grafo con ejes etiquetados</a></li> -<li><a name="stoc-Software-Libre-y-Manuales-Libres-1" href="#Software-Libre-y-Manuales-Libres">Appendix D Software Libre y Manuales Libres</a></li> -<li><a name="stoc-GNU-Free-Documentation-License-1" href="#GNU-Free-Documentation-License">Appendix E GNU Free Documentation License</a></li> -<li><a name="stoc-Indice" href="#g_t_00cdndice">Índice</a></li> -<li><a name="stoc-Acerca-del-Autor-1" href="#Acerca-del-Autor">Acerca del Autor</a></li> -</ul> -</div> -<hr> -<a name="SEC_About"></a> -<table class="header" cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#Top" title="Portada del documento">Arriba</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Índice general">Índice general</a>]</td> -<td valign="middle" align="left">[<a href="#g_t_00cdndice" title="Índice">Índice</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="Acerca de (página de ayuda)"> ? </a>]</td> -</tr></table> -<h1>Acerca de este documento</h1> - -<p> - Este documento se generó el <i>el 28 febrero 2026</i> utilizando <a href="http://www.nongnu.org/texi2html/"><i>texi2html 5.0</i></a>. -</p> -<p> - Los botones de los paneles de navegación tienen el significado siguiente: -</p> -<table border="1"> - <tr> - <th> Botón </th> - <th> Nombre </th> - <th> Ir a </th> - <th> Desde 1.2.3 ir a</th> - </tr> - <tr> - <td align="center"> [ << ] </td> - <td align="center">Retroceso rápido</td> - <td>Inicio de este capítulo o capítulo anterior</td> - <td>1</td> - </tr> - <tr> - <td align="center"> [ < ] </td> - <td align="center">Atrás</td> - <td>Sección anterior en orden de lectura</td> - <td>1.2.2</td> - </tr> - <tr> - <td align="center"> [ Subir ] </td> - <td align="center">Subir</td> - <td>Subir sección</td> - <td>1.2</td> - </tr> - <tr> - <td align="center"> [ > ] </td> - <td align="center">Adelante</td> - <td>Sección siguiente en orden de lectura</td> - <td>1.2.4</td> - </tr> - <tr> - <td align="center"> [ >> ] </td> - <td align="center">Avance rápido</td> - <td>Capítulo siguiente</td> - <td>2</td> - </tr> - <tr> - <td align="center"> [Arriba] </td> - <td align="center">Arriba</td> - <td>Portada del documento</td> - <td> </td> - </tr> - <tr> - <td align="center"> [Índice general] </td> - <td align="center">Índice general</td> - <td>Índice general</td> - <td> </td> - </tr> - <tr> - <td align="center"> [Índice] </td> - <td align="center">Índice</td> - <td>Índice</td> - <td> </td> - </tr> - <tr> - <td align="center"> [ ? ] </td> - <td align="center">Acerca de</td> - <td>Acerca de (página de ayuda)</td> - <td> </td> - </tr> -</table> - -<p> - donde el <strong> Ejemplo </strong> supone que la posición actual está en la <strong> Sub-subsección uno-dos-tres </strong> de un documento de la estructura siguiente: -</p> - -<ul> - <li> 1. Sección Uno - <ul> - <li>1.1 Subsección uno-uno - <ul> - <li>...</li> - </ul> - </li> - <li>1.2 Subsección uno-dos - <ul> - <li>1.2.1 Sub-subsección uno-dos-uno</li> - <li>1.2.2 Sub-subsección uno-dos-dos</li> - <li>1.2.3 Sub-subsección uno-dos-tres - <strong><== Posición actual </strong></li> - <li>1.2.4 Sub-subsección uno-dos-cuatro</li> - </ul> - </li> - <li>1.3 Subsección uno-tres - <ul> - <li>...</li> - </ul> - </li> - <li>1.4 Subsección uno-cuatro</li> - </ul> - </li> -</ul> - -<hr> -<p> - <font size="-1"> - Este documento se generó el <i>el 28 febrero 2026</i> utilizando <a href="http://www.nongnu.org/texi2html/"><i>texi2html 5.0</i></a>. - </font> - <br> - -</p> -</body> -</html> diff --git a/emacs-lisp-intro-es.pdf b/emacs-lisp-intro-es.pdf Binary files differdeleted file mode 100644 index 53910db..0000000 --- a/emacs-lisp-intro-es.pdf +++ /dev/null |
