summaryrefslogtreecommitdiffhomepage
path: root/es-es
diff options
context:
space:
mode:
Diffstat (limited to 'es-es')
-rw-r--r--es-es/tcl-es.html.markdown600
1 files changed, 600 insertions, 0 deletions
diff --git a/es-es/tcl-es.html.markdown b/es-es/tcl-es.html.markdown
new file mode 100644
index 00000000..5db72ae1
--- /dev/null
+++ b/es-es/tcl-es.html.markdown
@@ -0,0 +1,600 @@
+---
+language: Tcl
+contributors:
+ - ["Poor Yorick", "https://pooryorick.com/"]
+translators:
+ - ["Héctor Romojaro", "https://github.com/hromojaro"]
+lang: es-es
+filename: learntcl-es.tcl
+---
+
+Tcl fue creado por [John Ousterhout](https://wiki.tcl.tk/John%20Ousterout) como
+un lenguaje reutilizable de scripting para herramientas de diseño de circuitos
+de las que él era autor. En 1997 recibió el
+[ACM Software System Award](https://en.wikipedia.org/wiki/ACM_Software_System_Award)
+por Tcl. Tcl puede ser utilizado tanto como lenguaje de scripting embebido,
+como lenguaje de programación general. Puede ser utilizado también como una
+biblioteca portable de C, incluso en casos donde no se requieren capacidades
+de scripting, ya que provee de estructuras de datos tales como cadenas (*string*)
+de caracteres dinámicas, listas y tablas hash. La biblioteca de C también
+provee funcionalidad portable para cargar bibliotecas dinámicas, formato de
+cadenas y conversión de código, operaciones sobre el sistema de ficheros,
+operaciones de red y más. Algunas características reseñables de Tcl:
+
+* Conveniente API de red multiplataforma
+
+* Sistema de ficheros totalmente virtualizado
+
+* Canales apilables de E/S
+
+* Asíncrono hasta el núcleo
+
+* Corrutinas completas
+
+* Un modelo de hebras reconocido como robusto y fácil de usar
+
+
+Tcl tiene mucho en común con Lisp pero, en lugar de listas, Tcl utiliza cadenas
+de caracteres como moneda de cambio del lenguaje. Todos los valores son cadenas.
+Una lista es una cadena con un formato definido, y el cuerpo de un procedimiento
+(un script) es también una cadena en lugar de un bloque. Para incrementar el
+rendimiento, Tcl cachea internamente representaciones estructuradas de estos
+valores. Las rutinas con listas, por ejemplo, operan en la representación interna
+en caché, y Tcl se ocupa de actualizar la representación en cadenas si es realmente
+necesario en el script. El diseño *copy-on-write* de Tcl permite a los autores
+de scripts mover grandes volúmenes de datos sin incurrir en el consumo adicional
+de memoria. Los procedimientos son automáticamente compilados (*byte-compiled*)
+a no ser que utilicen rutinas dinámicas como "uplevel", "upvar" o "trace".
+
+Programar en Tcl es un placer. Le resultará atractivo a hackers que encuentren
+atractivo Lisp, Forth o Smalltalk, y a ingenieros y científicos que simplemente
+quieren ponerse a trabajar con una herramienta que se doblega a su voluntad. La
+disciplina de exponer toda la funcionalidad programática como rutinas, incluyendo
+cosas como iteraciones y operaciones matemáticas que normalmente están en la
+sintaxis de otros lenguajes, permitiendo fundirse en el fondo de cualquier
+funcionalidad específica del dominio que necesita un proyecto. Su sintaxis,
+incluso más simple que la de lisp, simplemente se quita de en medio.
+
+
+
+```tcl
+#! /bin/env tclsh
+
+###############################################################################
+## 1. Directrices
+###############################################################################
+
+# ¡Tcl no es ni Sh ni C! Es necesario decirlo porque el entrecomillado estándar
+# de shell casi funciona en Tcl, y es común que la gente empiece con Tcl e
+# intente utilizar sintaxis de otros lenguajes. Funciona al principio, pero
+# rápidamente conduce a frustración cuando los scripts se vuelven más complejos.
+
+# Las llaves son un mecanismo de entrecomillado, no de sintaxis para la construcción
+# de bloques de código o listas. Tcl no tiene ninguna de ellas. Las llaves se
+# usan para escapar caracteres especiales, lo que las hace apropiadas para
+# entrecomillar cuerpos de procedimientos y cadenas que deberían ser interpretadas
+# como listas.
+
+
+###############################################################################
+## 2. Sintaxis
+###############################################################################
+
+# Un script consiste en comandos delimitados por saltos de línea o puntos y coma.
+# Cada comando es una llamada a una rutina. La primera palabra es el nombre de
+# la rutina a llamar, y las siguientes palabras son argumentos de la rutina.
+# Las palabras están delimitadas por espacios. Puesto que cada argumento es una
+# palabra en el comando, y una cadena de caracteres, puede no ser entrecomillada:
+set part1 Sal
+set part2 ut; set part3 ations
+
+
+# el símbolo del dólar introduce la sustitución de variables:
+set greeting $part1$part2$part3
+
+
+# Cuando "set"recibe sólamente el nombre de una variable, devuelve su valor:
+set part3 ;# Returns the value of the variable.
+
+
+# Los corchetes delimitan un script que será evaluado y sustituido por su resultado:
+set greeting $part1$part2[set part3]
+
+
+# Un script incrustado puede estar compuesto de múltiples comandos, el último de
+# los cuales devuelve el resultado de la sustitución:
+set greeting $greeting[
+ incr i
+ incr i
+ incr i
+]
+puts $greeting ;# La salida es "Salutations3"
+
+# Cada palabra en un comando es una cadena, incluyendo el nombre de la rutina,
+# así que se pueden utilizar sustituciones allí también. Dada esta asignación
+# de variable,
+
+set action pu
+
+# los siguientes tres comandos son equivalentes:
+puts $greeting
+${action}ts $greeting
+[set action]ts $greeting
+
+
+# La barra invertida suprime el significado especial de los caracteres:
+set amount \$16.42
+
+
+# La barra invertida añade significado especial a ciertos caracteres:
+puts lots\nof\n\n\n\n\n\nnewlines
+
+
+# Una palabra encerrada entre llaves no está sujeta a interpretación especial o
+# sustitución, excepto que una barra invertida antes de una llave no cuenta al
+# buscar la llave de cierre:
+set somevar {
+ This is a literal $ sign, and this \} escaped
+ brace remains uninterpreted
+}
+
+
+# En una palabra delimitada por comillas dobles, los espacios pierden su significado
+# especial:
+set name Neo
+set greeting "Hello, $name"
+
+
+# Un nombre de variable puede ser cualquier cadena:
+set {first name} New
+
+
+# La forma de sustitución de variables utilizando llaves permite nombres de
+# variable más complejos:
+set greeting "Hello, ${first name}"
+
+
+# "set" puede utilizarse siempre en lugar de la sustitución de variables, y permite
+# utilizar cualquier nombre de variable:
+set greeting "Hello, [set {first name}]"
+
+
+# Para desempaquetar una lista en un el comando, se utiliza el operador de expansión,
+# "{*}". Estos dos comandos son equivalentes:
+set name Neo
+set {*}{name Neo}
+
+
+# Un array es una variable especial que sirve como contenedor de otras variables.
+set person(name) Neo
+set person(destiny) {The One}
+set greeting "Hello, $person(name)"
+
+
+# "variable" se puede utilizar para declarar o asignar variables. Al contrario
+# que "set", que utiliza el espacio de nombres global y el actual para resolver
+# un nombre de variable, "variable" usa solamente el actual:
+variable name New
+
+
+# "namespace eval" crea un nuevo espacio de nombres en caso de no existir.
+# Un espacio de nombres puede contener tanto rutinas como variables:
+namespace eval people {
+ namespace eval person1 {
+ variable name Neo
+ }
+}
+
+
+# Use dos o más ":" para delimitar componentes del espacio de nombres en nombres
+# de variables:
+namespace eval people {
+ set greeting "Hello $person1::name"
+}
+
+# Dos o más ":" también delimitan componentes del espacio de nombres en nombres
+# de rutinas:
+proc people::person1::speak {} {
+ puts {I am The One.}
+}
+
+# Nombres completos comienzan con dos ":":
+set greeting "Hello $::people::person1::name"
+
+
+
+###############################################################################
+## 3. No más sintaxis
+###############################################################################
+
+# El resto de funcionalidades se implementa mediante rutinas. Desde este punto,
+# no hay nueva sintaxis. Todo lo que queda para aprender Tcl es acerca del
+# comportamiento de rutinas individuales y el significado que asignan a sus
+# argumentos.
+
+
+
+###############################################################################
+## 4. Variables y espacios de nombres
+###############################################################################
+
+# Cada variable y cada rutina están asociadas a algún espacio de nombres
+
+# Para terminar con un intérprete inútil, sólo hay que eliminar el espacio de
+# nombres global. No es algo muy útil, pero sirve para ilustrar la naturaleza
+# de Tcl. El nombre del espacio de nombres global es en realidad la cadena
+# vacía, pero la única forma de representarlo es como un nombre completo. Para
+# probarlo, se puede usar esta rutina.
+proc delete_global_namespace {} {
+ namespace delete ::
+}
+
+# Como "set" siempre mantiene su vista en los espacios de nombres global y actual,
+# es más seguro utilizar "variable" para declarar o asignar un valor a una
+# variable. Si una variable llamada "nombre" ya existe en el espacio de nombres
+# global, usar "set" asignará un valor a la variable local en lugar de a la
+# variable del espacio de nombres actual, mientras que "variable" opera en el
+# espacio de nombres actual solamente.
+namespace eval people {
+ namespace eval person1 {
+ variable name Neo
+ }
+}
+
+# Una vez que una variable es declarada en un espacio de nombres, [set] la vé
+# en lugar de una variable de idéntico nombre en el espacio de nombres global:
+namespace eval people {
+ namespace eval person1 {
+ variable name
+ set name Neo
+ }
+}
+
+# En cambio, si "set" tiene que crear una nueva variable, siempre lo hace en el
+# espacio de nombres actual:
+unset name
+namespace eval people {
+ namespace eval person1 {
+ set name neo
+ }
+
+}
+set people::person1::name
+
+
+# Un nombre absoluto siempre comienza con el nombre del espacio de nombres global
+# (cadena vacía), seguido de dos ":":
+set ::people::person1::name Neo
+
+
+# En el interior de un procedimiento, la variable enlaza una variable en el espacio
+# de nombres actual en el ámbito local:
+namespace eval people::person1 {
+ proc fly {} {
+ variable name
+ puts "$name is flying!"
+ }
+}
+
+
+
+
+###############################################################################
+## 4. Rutinas incorporadas
+###############################################################################
+
+# Las operaciones matemáticas se pueden hacer con "expr":
+set a 3
+set b 4
+set c [expr {$a + $b}]
+
+# Como "expr" realiza sustituciones de variables por sí mismo, es necesario
+# poner la expresión entre llaves para prevenir a Tcl sustituir las variables
+# primero. Ver "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" para más
+# detalles.
+
+
+# "expr" entiende sustitución de variables y scripts:
+set c [expr {$a + [set b]}]
+
+
+# "expr" provee de un conjunto de funciones matemáticas:
+set c [expr {pow($a,$b)}]
+
+
+# Los operadores matemáticos están disponibles como rutinas en el espacio de
+# nombres ::tcl::mathop
+::tcl::mathop::+ 5 3
+
+# Las rutinas pueden ser importadas desde otros espacios de nombres:
+namespace import ::tcl::mathop::+
+set result [+ 5 3]
+
+
+# Los valores no numéricos deben ser entrecomillados, y los operadores como "eq"
+# pueden utilizarse para restringir la operación a una comparación de cadenas:
+set name Neo
+expr {{Bob} eq $name}
+
+# Los operadores generales recurren a la comparación de cadenas si una operación
+# numérica no es factible.
+expr {{Bob} == $name}
+
+
+# "proc" crea nuevas rutinas:
+proc greet name {
+ return "Hello, $name!"
+}
+
+# Se pueden especificar múltiples parámetros:
+proc greet {greeting name} {
+ return "$greeting, $name!"
+}
+
+
+# Como se dijo antes, las llaves no construyen un bloque de código. Cada valor,
+# incluso el tercer argumento de "proc", es una cadena. El comando anterior
+# puede ser reescrito sin usar llaves:
+proc greet greeting\ name return\ \"\$greeting,\ \$name!\"
+
+
+
+# Cuando el último parámetro es el valor literal "args", todos los argumentos
+# extra pasados a la rutina son recogidos en una lista y asignado a "args":
+proc fold {cmd first args} {
+ foreach arg $args {
+ set first [$cmd $first $arg]
+ }
+ return $first
+}
+fold ::tcl::mathop::* 5 3 3 ;# -> 45
+
+
+# La ejecución condicional se implementa como una rutina:
+if {3 > 4} {
+ puts {This will never happen}
+} elseif {4 > 4} {
+ puts {This will also never happen}
+} else {
+ puts {This will always happen}
+}
+
+
+# Los bucles se implementan como rutinas. Los primer y tercer argumentos de "for"
+# son tratados como scripts, mientras que el segundo lo es como una expresión:
+set res 0
+for {set i 0} {$i < 10} {incr i} {
+ set res [expr {$res + $i}]
+}
+unset res
+
+
+# El primer argumento de "while" se trata también como una expresión:
+set i 0
+while {$i < 10} {
+ incr i 2
+}
+
+
+# Una lista es una cadena, y los elementos de la lista se delimitan con espacios
+# en blanco:
+set amounts 10\ 33\ 18
+set amount [lindex $amounts 1]
+
+# El espacio en blanco dentro de una lista debe ser entrecomillado:
+set inventory {"item 1" item\ 2 {item 3}}
+
+
+# Generalmente, es mejor idea usar rutinas de listas al modificarlas:
+lappend inventory {item 1} {item 2} {item 3}
+
+
+# Las llaves y barras invertidas pueden utilizarse para formatear valores más
+# complejos en una lista. Una lista parece un script, excepto en que el carácter
+# de nueva línea y el ":" pierden su significado especial, y no hay sustitución
+# de variable o scripts. Esta característica hace Tcl homoicónico. Hay tres
+# elementos en la siguiente lista:
+set values {
+
+ one\ two
+
+ {three four}
+
+ five\{six
+
+}
+
+
+# Como, al igual que todos los valores, una lista es una cadena, operaciones de
+# cadenas pueden ser realizadas sobre ellas, corriendo el riesgo de corromper
+# el formato de la lista:
+set values {one two three four}
+set values [string map {two \{} $values] ;# $values is no-longer a \
+ properly-formatted list
+
+
+# La forma segura de conseguir una lista debidamente formateada es utilizando
+# las rutinas propias de lista:
+set values [list one \{ three four]
+lappend values { } ;# add a single space as an item in the list
+
+
+# Se puede utilizar "eval" para evaluar un valor como un script:
+eval {
+ set name Neo
+ set greeting "Hello, $name"
+}
+
+
+# Una lista siempre puede ser pasada a "eval" como un script compuesto de un único
+# comando:
+eval {set name Neo}
+eval [list set greeting "Hello, $name"]
+
+
+# Por lo tanto, cuando se utiliza "eval", use "list" para construir el comando
+# deseado:
+set command {set name}
+lappend command {Archibald Sorbisol}
+eval $command
+
+
+# Un error común es no usar funciones de listas al construir un comando:
+set command {set name}
+append command { Archibald Sorbisol}
+try {
+ eval $command ;# El error es que "set" tiene demasiados argumentos en \
+ {set name Archibald Sorbisol}
+} on error {result eoptions} {
+ puts [list {received an error} $result]
+}
+
+# Este error puede ocurrir fácilmente con "subst":
+
+set replacement {Archibald Sorbisol}
+set command {set name $replacement}
+set command [subst $command]
+try {
+ eval $command ;# El mismo error que antes: demasiados argumentos a "set" en \
+ {set name Archibald Sorbisol}
+} trap {TCL WRONGARGS} {result options} {
+ puts [list {received another error} $result]
+}
+
+
+# "list" formatea correctamente un valor para su sustitución:
+set replacement [list {Archibald Sorbisol}]
+set command {set name $replacement}
+set command [subst $command]
+eval $command
+
+
+# "list" se utiliza normalmente para formatear valores para su sustitución en
+# scripts: Hay muchos ejemplos de esto más abajo.
+
+
+# "apply" evalúa una lista de dos elementos como una rutina:
+set cmd {{greeting name} {
+ return "$greeting, $name!"
+}}
+apply $cmd Whaddup Neo
+
+# Un tercer elemento puede ser utilizado para especificar el espacio de nombres
+# donde aplicar la rutina:
+set cmd [list {greeting name} {
+ return "$greeting, $name!"
+} [namespace current]]
+apply $cmd Whaddup Neo
+
+
+# "uplevel" evalúa un script en un nivel superior de la pila de llamadas:
+proc greet {} {
+ uplevel {puts "$greeting, $name"}
+}
+
+proc set_double {varname value} {
+ if {[string is double $value]} {
+ uplevel [list variable $varname $value]
+ } else {
+ error [list {not a double} $value]
+ }
+}
+
+
+# "upvar" enlaza una variable en el nivel actual de la pila de llamadas a una
+# variable en un nivel superior:
+proc set_double {varname value} {
+ if {[string is double $value]} {
+ upvar 1 $varname var
+ set var $value
+ } else {
+ error [list {not a double} $value]
+ }
+}
+
+
+# Deshacerse de la rutina "while" incorporada, y utilizar "proc" para definir
+# una nueva:
+rename ::while {}
+# la manipulación se deja como ejercicio:
+proc while {condition script} {
+ if {[uplevel 1 [list expr $condition]]} {
+ uplevel 1 $script
+ tailcall [namespace which while] $condition $script
+ }
+}
+
+
+# "coroutine" crea una nueva pila de llamadas, una nueva rutina en la que
+# introducir esa pila de llamadas, y luego llama a dicha rutina. "yield" suspende
+# la evaluación en esa pila y devuelve el control a la pila que efectúa la llamada.
+proc countdown count {
+ # devuelve algo al creador de la corrutina, efectivamente pausando esta
+ # pila de llamadas por ahora.
+ yield [info coroutine]
+
+ while {$count > 1} {
+ yield [incr count -1]
+ }
+ return 0
+}
+coroutine countdown1 countdown 3
+coroutine countdown2 countdown 5
+puts [countdown1] ;# -> 2
+puts [countdown2] ;# -> 4
+puts [countdown1] ;# -> 1
+puts [countdown1] ;# -> 0
+catch {
+ puts [coundown1] ;# -> invalid command name "countdown1"
+} cres copts
+puts $cres
+puts [countdown2] ;# -> 3
+
+
+# Pilas de corrutinas pueden cederse el control entre sí:
+
+proc pass {whom args} {
+ return [yieldto $whom {*}$args]
+}
+
+coroutine a apply {{} {
+ yield
+ set result [pass b {please pass the salt}]
+ puts [list got the $result]
+ set result [pass b {please pass the pepper}]
+ puts [list got the $result]
+}}
+
+coroutine b apply {{} {
+ set request [yield]
+ while 1 {
+ set response [pass c $request]
+ puts [list [info coroutine] is now yielding]
+ set request [pass a $response]
+ }
+}}
+
+coroutine c apply {{} {
+ set request [yield]
+ while 1 {
+ if {[string match *salt* $request]} {
+ set request [pass b salt]
+ } else {
+ set request [pass b huh?]
+ }
+ }
+}}
+
+# Pon las cosas en marcha
+a
+
+
+```
+
+## Reference
+
+[Documentación oficial de Tcl](http://www.tcl.tk/man/tcl/)
+
+[Tcl Wiki](http://wiki.tcl.tk)
+
+[Tcl Subreddit](http://www.reddit.com/r/Tcl)