<?xml version="1.0" encoding="utf8"?>
<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=uft8">
   <META NAME="DATE" CONTENT="11/2/2003">
   <META NAME="Author" CONTENT="J. J. Merelo">
   <META NAME="Description" CONTENT="Tutorial de PERL en castellano, con ejemplos y ejercicios">
   <META NAME="Keywords" CONTENT="curso de perl, tutorial de perl, manual de perl, programacion"> 
   <TITLE>Tutorial de Perl:  Presentando lo impresentable  </TITLE>
<script language="JavaScript">
var contador = 1;
var contadores= new Array;
function multicontador(  numero ) {
      if ( ! contadores[ numero ]  )
          contadores[ numero ] = 1;
      else
          contadores[numero ]++;
      document.write( contadores[numero] );
};

</script>
<link rel ='stylesheet' type = "text/css" href = "perl.css">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#ffffff" LINK="#0000FF" VLINK="#551A8B" ALINK="#FF0000">
<TABLE  align=center cellpadding=5 bgcolor='darkseagreen'>
	<tr>

	<td>
			 <!-- Atomz.com Search HTML for Tutorial de PERL en castellano -->
	  <form method="get" action="http://search.atomz.com/search/">
	    <input size=25 name="sp-q"><br /><input type=submit value="Busca en el tutorial">
	    <input type=hidden name="sp-a" value="0002147b-sp00000001">
	  </form>
	</td>

	<td align='center'>
			<h1><a href='indice.html'>Tutorial de <strong>PERL</strong> en castellano </a>: Presentando lo impresentable</h1>
	</td>

    <td align='right' valign='top'><a href='tutoperl16.html'> Preguntas frecuentemente preguntadas</a><br><a href='tutoperl17.html'> Bibliograf&iacute;a.</a><br><a href='tutoperl18.html'> Recursos Internet</a><br><a href='tutoperl10.html'> Regularizando la situaci&oacute;n</a><br><a href='tutoperl12.html'> Decodificando</a><br></td>
	</tr>
</table>

<h3>Usando subrutinas y secuencias de escape ANSI</h3>



<P>Tanto trabajo est&aacute; acabando con la salud de nuestro pol&iacute;tico.
La campa&ntilde;a electoral est&aacute; cerca, tiene que inaugurar unas
cuantas obras inacabadas todav&iacute;a, y decide descargarse de un poco
de trabajo. Para ello contrata a un militante de base como experto de Inform&aacute;tica
con cargo a los fondos reservados. Este se encuentra un trabajo ingente,
y para empezar decide facilitar un poco su labor escribiendo una utilidad
que le permita sacar directorios un poco m&aacute;s monos. Y, ni corto
ni perezoso ("Este chico llegar&aacute; lejos", comenta nuestro pol&iacute;tico)
escribe el programa <a href=dir.pl><code>dir.pl,</CODE></a>que aparece en el
listado siguiente.

<table class=listado cellspacing=0 border=0 cellpadding=1><tr><td bgcolor=black><table><tr><td bgcolor=white>
<pre><font size=+2>
1&nbsp;#<em>!/usr/bin/perl
</em>2&nbsp;
3&nbsp;<font color=blue>sub</font> inverso {
4&nbsp;#<em>Añade la secuencia ANSI de escape para video inverso
</em>5&nbsp;	<font color=blue>return</font> "[7m<font color=green>@_</font>";
6&nbsp;}
7&nbsp;
8&nbsp;<font color=blue>sub</font> negrita {
9&nbsp;#<em>Añade la secuencia ANSI de escape para letra resaltada
</em>10&nbsp;	<font color=blue>return</font> "[1m<font color=green>@_</font>";
11&nbsp;}
12&nbsp;
13&nbsp;<font color=blue>sub</font> borra {
14&nbsp;#<em>Borra pantalla
</em>15&nbsp;	<font color=red>print</font>  "[2J";
16&nbsp;}
17&nbsp;
18&nbsp;<font color=blue>sub</font> normal {
19&nbsp;#<em>Restablece modo normal
</em>20&nbsp;	<font color=red>print</font> "[0m";
21&nbsp;}
22&nbsp;
23&nbsp;&amp;borra;
24&nbsp;<font color=green>$dirSep</font> = "/";				#<em>Solo para MS-DOS
</em>25&nbsp;
26&nbsp;
27&nbsp;<font color=blue>if</font> (<font color=green>$ARGV</font>[0] eq "" ) {
28&nbsp;	<font color=green>$dir</font> = <font color=green>$dirSep</font>;
29&nbsp;}else {
30&nbsp;	<font color=green>$dir</font> = <font color=green>$ARGV</font>[0];
31&nbsp;}
32&nbsp;
33&nbsp;#<em>Abre directorio
</em>34&nbsp;<font color=red>opendir</font>( DIR, <font color=green>$dir</font> );
35&nbsp;<font color=blue>while</font>( <font color=green>$fichero</font> = <font color=red>readdir</font>( DIR ) ) {
36&nbsp;	<font color=red>push</font>( <font color=green>@ficheros</font>, <font color=green>$fichero</font> );
37&nbsp;}
38&nbsp;<font color=red>closedir</font>( DIR);
39&nbsp;
40&nbsp;#<em>Cabecera del listado
</em>41&nbsp;<font color=green>$msg</font> = "Listado del directorio ".&amp;inverso( <font color=green>$dir</font> ); 
42&nbsp;<font color=red>print</font> "<font color=green>$msg</font>\n";&amp;normal;
43&nbsp;<font color=red>print</font> "=" x (<font color=red>length</font>(<font color=green>$msg</font>) - <font color=red>length</font>(&amp;inverso(""))); <font color=red>print</font> "\n";
44&nbsp;
45&nbsp;<font color=blue>if</font> ( <font color=green>$dir</font> !~ m!\\$! ) {
46&nbsp;	<font color=green>$prefijo</font> = <font color=green>$dir</font>.<font color=green>$dirSep</font>;
47&nbsp;} else {
48&nbsp;	<font color=green>$prefijo</font> = "<font color=green>$dirSep</font>";
49&nbsp;}
50&nbsp;
51&nbsp;<font color=blue>foreach</font> (<font color=red>sort</font> <font color=green>@ficheros</font> ) {
52&nbsp;	<font color=red>print</font> &amp;inverso( <font color=green>$_</font> ) <font color=blue>if</font> -f "<font color=green>$prefijo</font><font color=green>$_</font>";
53&nbsp;	<font color=red>print</font> &amp;negrita( <font color=green>$_</font> ) <font color=blue>if</font> -d "<font color=green>$prefijo</font><font color=green>$_</font>";
54&nbsp;	&amp;normal;
55&nbsp;	<font color=red>print</font> "\n";
56&nbsp;}
</font></pre>


</td></tr></table></td></tr><caption><font face="arial,helvetica">Listado <script>multicontador(1);</script>: Programa dir.pl</font></caption></table>


<P><IMG SRC="dirout.gif" HEIGHT=167 WIDTH=336 ALIGN=RIGHT> En este programa
ya estamos hablando de palabras mayores. Para empezar, es un poco m&aacute;s
largo. Para continuar, es s&oacute;lo para MS-DOS o Win95, pero se puede
adaptar m&aacute;s o menos f&aacute;cilmente a cualquier otro sistema operativo
cambiando el separador de directorios contenido en la variable <code>$dirSep</CODE>
(: para el Mac, / para UNIX). El programa saca un listado del directorio,
ordenado en orden alfab&eacute;tico, resaltando los directorios con un
tipo de letra m&aacute;s brillante, y los ficheros en video inverso.
</p>

<P>Se le llama de la forma siguiente<pre>
C:\> perl dir.pl &lt;nombre del directorio></pre>

<P>Si no se da ning&uacute;n nombre de directorio, toma el directorio ra&iacute;z;
para el directorio actual hay que introducir <pre>perl dir.pl .</pre>.
</p>

<P>Veremos primero el truco de sacar las cosas en diferentes tonos, y que
se expresan en el programa con extra&ntilde;os signos (para obtener la
flechica p'atr&aacute;s, se pulsa control-P, y sin dejar de pulsarlo, control-[;
dif&iacute;cil, pero es as&iacute;). El programa usa secuencias de escape
ANSI, que son &oacute;rdenes est&aacute;ndar para trabajar con terminales;
son tanto aplicables a terminales UNIX (por ejemplo, los tipo vt-100 o
ansi), como MS-DOS; en este &uacute;ltimo habr&aacute; que a&ntilde;adir
la l&iacute;nea<Pre>
device=c:\dos\ansi.sys
</pre>
<p>al fichero <code>config.sys</code>.
Con estas secuencias de escape se puede imprimir en diferentes lugares
de la pantalla, borrar l&iacute;neas o la pantalla completa, y cambiar,
como aqu&iacute;, los atributos de partes de la pantalla, todo ello de
forma m&aacute;s o menos independiente del sistema. Es algo as&iacute;
como el interfaz gr&aacute;fico de usuario de los pobres.
</p>

<P>El siguiente concepto que introduce este programa es el de <I>subrutinas</I>.
Las subrutinas en <strong>PERL</strong> se pueden declarar en cualquier parte del programa,
al principio o al final. Para declararlas, simplemente se precede el nombre
de la subrutina con la palabra <code>sub</code> y se le
sigue del bloque de instrucciones que se van a ejecutar. Pueden no utilizar
par&aacute;metros (como <code>borra</code> y <code>normal</code>).
En este caso se llaman precedi&eacute;ndo el nombre con el s&iacute;mbolo
<code>&amp;</CODE>, o bien escribiendo <code>do
borra</CODE>. Tambi&eacute;n se puede llamar a una subrutina con par&aacute;metros,
en cuyo caso forman todos parte de la matriz <code>@_</CODE>,
como se ve por ejemplo en la subrutina <code>negrita</CODE>.
Los elementos de esta matriz son, como es natural, <code>$_[0],
$_[1]</CODE> y as&iacute; sucesivamente, aunque se pueden asignar todos
de una vez a par&aacute;metros locales de la subrutina, de esta forma<code>local($zipi,
$zape) = @_;</CODE>En esta sentencia se declaran simult&aacute;neamente
<code>$zipi</CODE> y <code>$zape</CODE> como
variables locales y se les asignan los dos primeros par&aacute;metros que
se le han pasado a la subrutina. Si no se declararan como <code>local</CODE>,
las variables ser&iacute;an visibles por todo el programa, como sucede
en el resto de las variables en <strong>PERL</strong>.</p>

<p><span class=v5>[v5]</span>En realidad, <code>local</code> crea
variables globales pero con valores locales; es decir, se crea una
variable que se puede ver en todo el programa, pero cuyo valor se
guarda al principio de la subrutina y se recupera al final de la
subrutina. En la versión 5 se introduce la palabra clave
<code>my</code>, que declara verdaderas variables locales. En la
versión 5, por tanto, se suele preferir <code>my</code> para declarar
las variables de las subrutinas.
<span class=v5>[/v5]</span>
</p>

<P>La lectura del directorio se hace a partir de la l&iacute;nea 31; para
eso utiliza funciones similares a las que hay en C o Pascal; una funcion,
<code>opendir,</CODE> "abre" el directorio, y las otras
van leyendo secuencialmente los nombres de todos los ficheros de ese directorio
y meti&eacute;ndolos en la matriz <code>@ficheros</CODE>.</p>

<TABLE align=right width=50% cellpadding=2 cellspacing=0 border=0>
    <tr><td bgcolor=blue><table bgcolor=white cellspacing=0 cellpadding = 6><tr>
<td><table><tr><td>-e</td><td>	Comprueba si el fichero existe o no</td></tr>
<tr><td>-f</td><td>	Comprueba si es un fichero normal</td></tr>
<tr><td>
-d	</td><td>Comprueba si es un directorio</td></tr>
<tr><td>
-T/-B</td><td>	Comprueba si es de texto o binario. Pero no funcionan fuera de Linux. 
</td></tr></table></td></tr></table></td></tr><caption><font
face="arial,helvetica">Tabla <script>multicontador(2)</script>:
Operadores de comprobación de ficheros</font></caption></table> 

<P>Luego, a partir de la l&iacute;nea 49, y utilizando los operadores <code>-f</CODE>
y <code>-d</CODE>, que comprueban si el fichero cuyo nombre
viene despu&eacute;s es un fichero normal o un directorio, se va imprimiendo
con los atributos correspondientes. Estos son un ejemplo de los <I>operadores
de fichero</I> que se utilizan mucho en <strong>PERL</strong> (ver la tabla 4), y que vienen heredados de comandos similares en los shell de UNIX
(como <code>csh </CODE>y <code>bash</CODE>),
nosotros tenemos la suerte de poder usarlos en ms-dos tambi&eacute;n. Otros
operadores figuran en la tabla 4.
</p>



<TABLE  align=center cellpadding=5 bgcolor='darkseagreen'><tr><td>[<a href='tutoperl16.html'> Preguntas frecuentemente preguntadas</a>] [<a href='tutoperl17.html'> Bibliograf&iacute;a.</a>] [<a href='tutoperl18.html'> Recursos Internet</a>] [<a href='tutoperl10.html'> Regularizando la situaci&oacute;n</a>] [<a href='tutoperl12.html'> Decodificando</a>] </td></tr></table>

</BODY>
</HTML>
