Manual de Tablas de Apuntes.

Nivel de conocimiento requerido en scripting: medio.
Autor: Arphean (arphean@zalau.ro)
Dedicatorias:
A SyntheroS por su editor.
A Matyas666 por todas las conversaciones que llevamos en #ScriptHelp [Argentina roolz!]
A Yuraba.

Mi intención al escribir el presente y pequeño "manual" sobre las tablas para guardar datos vino de las preguntas que muchos scripters, que necesitaban almacenar gran cantidad de información, hacían en diferentes canales de IRC. Siempre les respondíamos, a su interrogante de: "¿cómo hago para crear una hash?", aparte de mi humor relativo referente al detergente, les decíamos que se mirasen la ayuda. Casi siempre volvían y decían: "¿y ahora qué?".
Bueno, pues a ése "¿y ahora qué?" es a lo que voy a dedicarme en los siguientes párrafos.
Acompaña a éste artículo un editor hash verdaderamente bueno, que espero te ayude en tus trabajos.
Si lo deseas, estaré encantado de tu compañía. Empezamos.

1-Una tabla... sin madera.
Con un editor de tablas como el que acompaña éste artículo podremos hacer, visionar, guardar, incorporar y modificar datos sin problema alguno. Pero claro, ¿qué es una tabla de datos o tabla de apuntes? Básicamente, es un archivo donde podemos guardar cantidades más o menos grandes de datos. Pero bueno -te preguntarás- éso también puedo hacerlo en un txt o en un ini, ¿qué diferencia hay entonces con la tabla de apuntes? ¿Para qué la necesito? Principalmente, es por la eficiencia. Ésa es la cualidad innata y el valor de una tabla de datos. mIRC es capaz de guardar, leer, visionar, cargar y descargar una tabla de apuntes de una forma mucho más rápida que cualquier otro archivo.
Por éso, una tabla de apuntes es necesaria y cómoda para utilizar en supuestos donde la información a guardar sea grande y, además, donde se necesite consultarla de una forma rápida. Ejemplos de éstos casos -pero no únicos- son:
-Detectores de cambios de nicks genéricos (fuera de canales, dentro de servidores...)
-Correctores de texto (bien sean autocorrectores o correctores de frases totales)
-Traductores integrados en el mIRC
y un largo etcétera.
Bien, llegados a éste punto, vamos a ver los comandos necesarios para trabajar con una tabla de datos. Ni qué decir tiene que lo que necesitas cuando acabes de leer éste manual será, principalmente, experiencia. Así que, con la facilidad del editor, trabaja tú mism@ con las tablas y podrás rápidamente crear, descargar y consultarlas y, además, sabrás cómo utilizar todos ésos datos.
-Comandos para el manejo de tablas de datos.
HMAKE
Sintaxis:
/hmake -s <name> <N>
El comando /hmake crea una tabla, asignándole un nombre y dándole unos espacios. El valor de N es importante, son los espacios requeridos y, aunque una tabla puede tener ilimitados, asignándoselos aumentarás su rapidez.
El parámetro -s hace que el mIRC te muestre el resultado de la operación.
Experimenta el siguiente ejemplo:
/hmake -s constantes 100
HSAVE
Bueno, el siguiente comando es diferente del anterior, ya que, si el anterior la creaba, éste comando lo que hace es salvarla (guardarla) en un archivo, donde podrás, después, volver a recuperarla y modificarla o leerla.
Sintaxis:
/hsave -sbnoa <name> <file>
Es decir, imagínate que nuestra anterior tabla (constantes) la tuviéramos guardada en el archivo contstantes.lsl, en la raíz del mIRC, y que, en un momento dado, necesitas recurrir a ella. Lo que harías sería:
/hmake constantes
/hload constantes constantes.lsl
El comando /hload aún no lo hemos visto (lo veremos más adelante) pero como ves, su uso es relativamente simple: lo que hace, es cargar una tabla desde un archivo (justo lo contrario de hsave, que la guarda al archivo).
Ejemplo:
Bueno, pues vamos a guardar la tabla a un archivo. Apuntar, antes de hacerlo, que la tabla se guarda sin retornos de carro etc. a no ser que la guardes en formato binario (parámetro -b). Por defecto está hecho así, y es mejor y más rápido así. Si utilizas el parámetro -n los datos serán guardados sin temas, es decir, similar a un ini asignándoles un número de correlación.
Decirte, por si aún no lo has notado, que en todos éstos ejemplos, para aprender, utilices el parámetro -s, pues así mIRC te dará información sobre lo que vas haciendo.
/hsave -s constantes constantes.lsl
Bueno, ahora mira tu directorio mIRC y, si has seguido todos los pasos, verás en él el archivo constantes.lsl Por ahora no hemos trabajado con información pero, como puedes ver, paso a paso ya vas aprendiendo cosas: ya sabes crearla, cargarla y guardarla.
Una nota importantísima a añadir es unos parámetros que se pueden incorporar al hsave, que son:
-o y -a
Con -o lo que haces es sobreescribir, es decir: escribirás sobre lo que haya en la tabla (si hay algo)
Con -a lo que haces es añadir, es decir: añadirás información.
Basicamente, los pasos que hemos seguido han sido:
hmake - que la crea
hsave - que la guarda a archivo
hload - que la recupera.
Bueno, vamos a profundizar ahora sobre el hload.
HLOAD
Sintaxis:
/hload -sbn <name> <file>
¿A que ya te resulta familiar ésta sintaxis? Bien, éste comando es sencillo. y vamos a trabajar sobre él. Primero, liberaremos la tabla:
/hfree -s constantes
Después, la cargaremos:
/hmake -s constantes
/hload -s constantes constantes.lsl
En pantalla tiene que aparecerte algo como ésto:
* Loaded hash table 'constantes' from 'constantes.lsl'
Es decir, que la tabla constantes a sido cargada del archivo constantes.lsl (que hemos hecho en el ejemplo anterior).
Debes tener siempre en mente que lo que estás haciendo no es más que reservar espacios de memoria en la RAM de tu ordenador para los datos. Lo que haces con éstos comandos es similar a lo que harías trabajando con arrays, pero de una forma algo más "llevadera" (aunque depende de cada uno, personalmente prefiero los arrays...)
Como en el hsave, el parámetro -b trabaja en binario y el -n carga los datos sin temas.
Vamos con el hfree ya tratado:
HFREE
Sintaxis:
/hfree -sw <name>
Lo que hace éste comando es "liberar" la tabla, para los más "puritanos", es el contrario de hmake. Si no liberas la tabla, aunque la hayas guardado seguirá en memoria, por ello, si no la necesitas, tras haberla salvado lo correcto es que la liberes. Es, por decirlo de alguna manera -y si vienes del mundo de la programación estoy seguro que lo entenderás mejor así- un recogedor de basura.
Como buen recogedor de basura que es, podemos recurrir al modificador -w, que lo que hace es buscar por comodines las tablas liberando las que coincidan con ésa búsqueda (salvando las distancias, es un unload %co*, para los menos entendidos).
2-Trabajando con los datos.
Bueno, aunque no lo creas ya has aprendido mucho sobre éste tema hasta aquí, y estoy seguro que, cuando te pongas a trabajar con el editor que acompaña éste manual -si es que lo necesitas- ya no te sonará tanto a chino lo que hagas.
Pero ahora metámonos de lleno en la materia de trabajar sobre la tabla. Ya la hemos creado, sabemos cargarla, liberarla y guardarla, vayamos a lo que podemos introducir en ella.
La forma de introducir datos realmente es bastante libre, y depende de lo que necesites en cada circunstancia para hacerlo. Pero con unos fáciles ejemplos sabrás cómo se realiza.
HADD
Sintaxis:
/hadd -sm <name> <theme> <data>
Éste comando lo que hace es añadir un tema a una tabla. La tabla, recuerda siempre, se referencia por EL NOMBRE que le hayas dado en hmake, no por el nombre que tenga en el archivo. El tema hará que los datos a insertar en él sean referenciados, a su vez, por éste. Es decir: un dato es únicamente para un tema, y no interfiere con los demas.
El parámetro -m hace un /hmake, es decir, si no existiese, crearía la tabla. Pero ojo, no la guardaría, recuerda siempre que estás trabajando en la memoria de tu ordenador, no en tu disco duro.
Eje.:
Vamos a añadir un tema, Libros, a nuestra tabla. Dentro de ése tema incluiremos el género Drama.
/hadd -s constantes Libros Drama
Si lo has hecho bien, el mIRC debe responderte algo así:
* Added item 'Libros' to hash table 'constantes'
Experimenta ahora por tí mismo añadiendo más temas y más datos, por ejemplo:
/hadd -s constantes Romantica Poesia
Cambia de tema, de datos, etc.
Recuerda que ahora podrías salvar la tabla con el comando ya visto:
/hsave -os constantes constantes.lsl
Mientras no la guardes, la tabla estará en la memoria RAM y será destruida en cuanto cierres el mIRC o similar.
Asimismo, normalmente lo que se suele hacer a la hora de programar y trabajar sobre hashs es crear alias genéricos, que serán los ocupados de hacer el trabajo repetitivo, tal como cargarla, actualizarla, borrarla, etc.
HDEL
Sintaxis:
/hdel -sw <name> <theme>
hdel es el comando contrario a hadd, y lo que hace es borrar un tema. Como cumple función antagónica, y no creo que haya problemas al trabajar sobre él, te dejo a tu libre albedrío que borres y añadas datos y temas a la tabla que ya tienes creada. Solamente apuntarte que, si borras un tema, los datos a él supeditados también serán borrados.
Identificadores de tablas de datos.
Bien, llegados a éste punto, y si has seguido los sencillos pasos anteriores con atención, ya sabes cómo crear, destruir, cargar y descargar tablas.
Anotarte, antes de entrar de lleno con los identificadores, cómo harías para obtener datos de una tabla e introducirlos en un list de un diálogo, por ejemplo. Como lo mejor es, -perdón por la redundancia- que lo veas con ejemplos, voy a ponerte uno. Éste ejemplo utiliza un bucle while -como harías con cualquier otro archivo- para cargarlo, y hace uso de los identificadores de tablas de datos que vamos a ver más adelante. Creo que, si te fijas atentamente, por su sencillez hará que tengas las ideas muy claras sobre cómo es el trabajo de recuperación de datos en tablas y, además de quitarte el miedo, te darás cuenta de lo mucho que hasta aquí has avanzado en el conocimiento del manejo de éstas tablas.
var %x = 1
var %y = $hget(constantes,%x).item
did -r listbox 4 ;éste es el id del listbox, imagínate que es el número 4 por ejemplo
while (%y != $null) {
did -a diálogo_name 2 %y $+ $hget(constantes,%y)
inc %x
var %y = $hget(corrector,%x).item
}
Simple ¿verdad? ¿A que ahora ya no te dan tanto miedo las hastables?
Identificadores $get y modificadores
Sintaxis:
$hget(name/N)
Éste identificador nos devuelve el nombre de la tabla, si existe, y su tamaño -tamaño que se ha asignado en el comando hmake-. Principalmente, cumple tareas de verificación.
Sintaxis:
$hget(name/N,theme)
Con éste identificador se obtienen los datos que hemos incluido en un tema. El tema, como ves en la sintaxis, puedes referenciarlo bien por su nombre o por un número. Lo verás mejor seguro con un ejemplo:
//echo -s $hget(constantes,libros)
Si hiciste correctamente los pasos que te dije en el apartado de introducción de datos en la tabla, obtendrás:
Poesia
Otro ejemplo, ésta vez referenciado por número:
//echo -s $hget(2,libros)
Te daría:
Poesía
Como ves, todo lo que es suceptible de indexarse por números también lo es de ser tratado mediante bucles.
Ahora prueba con éste ejemplo, que te dará una idea de todo lo que puedes hacer con las hashs:
//echo -s $hget(constantes,1).item
Te dará:
Libros
Otro ejemplo:
//echo -s $hget(constantes,0).item
Te dará:
1
Si tienes un tema, o 2 si tienes dos, es decir: te darán los items totales de la tabla constantes.
¿Entiendes ahora por qué las hash tables son tan apreciadas y utilizadas, y lo que te estabas perdiendo?
Sintaxis:
$hget(name/N,N).theme
Ésta es la sintaxis del ejemplo anterior, pero referenciada por el tema.
Sintaxis
$hfind(name/N,text,N)
Éste es un identificador de búsqueda, busca, en una tabla, el texto pasado en el parámetro "text". Puedes usar la propiedad data, que da como resultado el valor del dato a comparar. Cuidado porque éste identificador puede llevar a error, y su uso es relativamente complejo. Casi siempre se utiliza, por su comodidad y similitud, $hmatch que es más interesante.
Sintaxis:
$hmatch(name/N,text,N)
Busca un texto en la tabla de datos pero permite utilizar comodines. Al igual que el identificador anterior, posee la propiedad data.
Ejemplo:
//echo -s $hmatch(constantes,*lib*,poesia)
Experimenta con éste identificador utilizando comodines, y como tú desees.
Sintaxis:
$hregex(name/N, re, N)
Otro identificador de búsqueda. Posee también la propiedad data y nos da el nombre que tenga la posición que le pasemos como argumento (obligatorio).
Como puedes comprobar, los identificadores más interesantes son los que devuelven los temas de la tabla, no su valor, que entran en la familia de los $hget.
Bien, llegados a éste punto, ya puedes crear, eliminar, liberar, guardar, modificar y buscar en una hash table, que es lo que querías, ¿no? Como punto final, voy a ponerte un sencillo ejemplo de un corrector, cada vez que alguien escriba algo en el campo de edición de un canal, será reemplazado por lo que hayamos puesto en nuestra tabla de datos. Con éste sencillo ejemplo doy por finalizado éste manual, esperando que te haya servido de ayuda y emplazándote y animándote a que investigues y pruebes lo aprendido, que es la mejor manera de que puedas desenvolverte con facilidad.

APÉNDICE A
Ejemplo práctico de creación de un corrector.
Para utilizar el corrector deberás crear una tabla llamada corrector.lsl, y guardarla. No hagas más, el corrector se encargará del resto.
Nota. Éste es un sencillísimo corrector con la única intención de que veas un ejemplo práctico de lo aprendido, con un poco de esfuerzo podrás mejorarlo mucho e, incluso, crearte uno mucho más desarrollado y capacitado.
Para utilizarlo, escribe en cualquier ventana de canal una palabra que hayas puesto como errónea (por ejemplo, ola) y el corrector te la sustituirá por la correcta (por ejemplo, hola).
Como ves es sumamente sencillo, a partir de aquí, hasta donde quieras llegar.
Me he evitado muchos alias, he tratado de hacerlo sumamente sencillo y claro, etc. etc., solamente con la intención de que veas el uso de hash.
;;;Código Corrector
alias tbcorr {
dialog -m tbcorr tbcorr
}
dialog tbcorr {
title "Manual de tablas de datos by Arphean"
size -1 -1 190 115
option dbu
box "Datos guardados", 1, 1 1 187 76
text "Reemplazar:", 2, 7 10 30 8
text "Por:", 3, 97 10 10 8
list 4, 4 21 180 50, size vsbar
button "Añadir palabra", 5, 6 81 57 12
button "&Cerrar", 6, 148 101 37 12, ok
}
on *:dialog:tbcorr:init:0:{
haccorrector
var %x = 1
var %y = $hget(corrector,%x).item
while (%y != $null) {
did -a tbcorr 4 %y $+ $chr(9) $+ $hget(corrector,%y)
inc %x
var %y = $hget(corrector,%x).item
}
}
on *:dialog:tbcorr:sclick:5:{
var %poncorr = $$?="ntroduce la palabra ERRÓNEA"
var %poncorrd $$?="ntroduce la palabra CORRECTA"
did -a tbcorr 4 %poncorr $+ $chr(9) $+ %poncorrd
hadd corrector $gettok(%poncorr,1,32) %poncorrd
hsave -a corrector corrector.lsl
}
on *:dialog:tbcorr:sclick:6:{
hfree corrector
}
;menús
menu status,channel,menubar {
-
Corrector:tbcorr
}
on 1:input:#: {
if ($left($1,1) != /) {
echo # $poncorrector($1-) | halt
}
}
alias poncorrector {
haccorrector
var %texto = $1-
var %x = 1
if ($exists(corrector.lsl) != $true) { write -c corrector.lsl }
while (%x <= $numtok(%texto,32)) {
var %errors = $hget(corrector, $ [ $+ [ %x ] ] )
if (%errors) {
%texto = $replace(%texto, $ [ $+ [ %x ] ] ,%errors)
}
inc %x 1
}
unset %errors
return %texto
}
alias haccorrector {
if ($hget(corrector,0).item > 0) { hfree corrector }
hmake corrector
hload corrector corrector.lsl
}
APÉNDICE B
Editor hash.
;Hashish (Hash table editor) v.01 - Scripting by SyntheroS
;puedes pastear éste código directamente en el remotes de tu mIRC, pero cuidado: no pastees códigos de color ni de html o no te funcionará. Lo que puedes hacer, es pegarlo previamente en un .txt y allí limpiarlo para, después, llevarlo a tu mIRC.
;el editor es propiedad intelectual de SyntheroS
on *:load:{
if ($version < 5.81) {
echo -at Hashish requiere mIRC v5.81 o superior para operar. Tú usas el mIRC v $+ $version $+ .
unload -rs " $+ $script $+ "
}
else { echo -at Hashish loaded. Right click in status/channel window, or click the menubar command button. }
}
menu status,channel,menubar {
-
Hashish editor:dialog -m hashish hashish.table
}
dialog hashish.table {
title "Hashish - Hash table editor"
size -1 -1 327 90
option dbu

list 700, 3 3 100 90, vsbar
list 701, 105 3 100 90, vsbar

edit "", 200, 230 7 50 11,autohs
edit "10", 201, 230 20 50 11,autohs
button "Create", 301, 285 7 35 11
button "Free", 304, 285 21 35 11

edit "", 202, 230 45 50 11,autohs
edit "", 203, 230 58 50 11,autohs
button "Update", 302, 285 45 35 11
button "Remove", 303, 285 58 35 11

button "Save as...", 305, 209 75 35 11
button "Load...", 306, 247 75 35 11

button "", 300, 0 0 0 0, cancel
text "Name", 100, 212 9 15 11
text "Size", 101, 212 21 15 11
text "Item", 102, 212 47 15 11
text "Data", 103, 212 60 15 11
box "Table", 600, 207 0 117 35
box "Edit", 601, 207 38 117 35
}
on *:dialog:hashish:init:0:hash.ref
on *:dialog:hashish:edit:200:{
set %tmp1 $did(hashish,200)
set %tmp2 $did(hashish,201)
if ((%tmp1 == $null) || ($hget(%tmp1) != $null) || ($chr(32) isin %tmp1) || (%tmp2 !isnum) || ($ishash(%tmp1) == $true)) { did -b hashish 301,306 }
else { did -e hashish 301,306 }
if ((%tmp1 == $null) || ($hget(%tmp1) != $null) || ($chr(32) isin %tmp1) || (%tmp2 !isnum) || ($ishash(%tmp1) == $false)) { did -b hashish 304,305 }
else { did -e hashish 304,305 }
unset %tmp1
unset %tmp2
}
on *:dialog:hashish:edit:201:{
set %tmp1 $did(hashish,200)
set %tmp2 $did(hashish,201)
if ((%tmp1 == $null) || ($hget(%tmp1) != $null) || ($chr(32) isin %tmp1) || (%tmp2 !isnum) || ($ishash(%tmp1) == $true)) { did -b hashish 301,306 }
else { did -e hashish 301,306 }
unset %tmp1
unset %tmp2
}
on *:dialog:hashish:edit:202:{
if (($did(hashish,202) == $null) || ($chr(32) isin $did(hashish,202)) || ($did(hashish,700).sel < 1)) { did -b hashish 302,303 }
else { did -e hashish 302,303 }
}
on *:dialog:hashish:edit:203:{
if ($did(hashish,700).sel < 1) { did -b hashish 302,303 }
else { did -e hashish 302,303 }
}
on *:dialog:hashish:sclick:301:hmake $did(hashish,200) $did(hashish,201) | hash.ref
on *:dialog:hashish:sclick:302:hadd $hash.name $did(hashish,202) $did(hashish,203) | hash.ref
on *:dialog:hashish:sclick:303:hdel $hash.name $hash.item | hash.ref
on *:dialog:hashish:sclick:304:hfree $hash.name | hash.ref
on *:dialog:hashish:sclick:305:hsave -bo $hash.name " $+ $sfile($scriptdir [ $+ [ $hash.name ] [ $+ .hsh ] ] ,Save hash file as...,Save) $+ " | hash.ref
on *:dialog:hashish:sclick:306:hmake $did(hashish,200) $did(hashish,201) | hload -b $did(hashish,200) " $+ $sfile($scriptdir [ $+ *.hsh ] ,Load hash file...,Load) $+ " | hash.ref
on *:dialog:hashish:sclick:700:{
did -r hashish 701,202,203
var %loop 1
while (%loop <= $hget($hash.name,0).item) {
did -a hashish 701 $hget($hash.name,%loop).item
inc %loop 1
}
did -e hashish 202,203,701,304,305
did -o hashish 200 1 $hash.name
did -o hashish 201 1 $hget($hash.name).size
}
on *:dialog:hashish:sclick:701:{
did -e hashish 202,203,302,303
did -o hashish 202 1 $hash.item
did -o hashish 203 1 $hget($hash.name,$hash.item)
}
alias hash.ref {
did -b hashish 202,203,301,306,302,303,701,304,305,300
did -r hashish 200,700,701,202,203
did -o hashish 201 1 10
var %loop 1
while (%loop <= $hget(0)) {
did -a hashish 700 $hget(%loop)
inc %loop 1
}
if ($did(hashish,701,0).sel > 0) {
var %loop 1
while (%loop <= $hget($hash.name,0).item) {
did -a hashish 701 $hget($hash.name,%loop).item
inc %loop 1
}
did -e hashish 202,203,302,303,701
}
}
alias ishash return $iif($hget($1) == $null,$false,$true)
alias hash.name return $did(hashish,700,$did(hashish,700,1).sel).text
alias hash.item return $did(hashish,701,$did(hashish,701,1).sel).text


[c] Arphean 2002 [Revisión 2003]
-Manual original de Arphean. Todos los derechos reservados. No se permite copia, reproducción ni modificación del presente manual sin el permiso de su autor.
Ejemplos y ejemplos de codificación propiedad de Arphean.

Editor hash propiedad de SyntheroS