Tcl (pronunciado " tickle " o como un acrónimo [8] ) es un lenguaje de programación dinámico , interpretado , de propósito general y de alto nivel . Fue diseñado con el objetivo de ser muy simple pero poderoso. [9] Tcl convierte todo en el molde de un comando , incluso construcciones de programación como la asignación de variables y la definición de procedimientos. [10] Tcl admite múltiples paradigmas de programación , incluidos los estilos orientado a objetos , imperativo , funcional y procedimental .
Se utiliza comúnmente integrado en aplicaciones C , [11] para creación rápida de prototipos , aplicaciones con scripts, GUI y pruebas. [12] Los intérpretes Tcl están disponibles para muchos sistemas operativos , lo que permite que el código Tcl se ejecute en una amplia variedad de sistemas. Debido a que Tcl es un lenguaje muy compacto, se utiliza en plataformas de sistemas integrados , tanto en su forma completa como en varias otras versiones de tamaño reducido. [13]
La popular combinación de Tcl con la extensión Tk se conoce como Tcl/Tk (pronunciado "tickle teak" o como una sigla ) y permite construir una interfaz gráfica de usuario (GUI) de forma nativa en Tcl. Tcl/Tk está incluido en la instalación estándar de Python en forma de Tkinter .
El lenguaje de programación Tcl fue creado en la primavera de 1988 por John Ousterhout mientras trabajaba en la Universidad de California, Berkeley . [14] [15] Originalmente "nació de la frustración", [11] según el autor, con programadores ideando sus propios lenguajes para extender el software de automatización de diseño electrónico (EDA) y, más específicamente, la herramienta de diseño VLSI Magic , que era un enfoque profesional para John en ese momento. [16] Más tarde, Tcl ganó aceptación por sí solo. Ousterhout fue galardonado con el premio ACM Software System Award en 1997 por Tcl/Tk. [17]
El nombre proviene originalmente de Tool Command Language , pero convencionalmente se escribe Tcl en lugar de TCL . [ 18 ]
Se celebran conferencias y talleres sobre Tcl tanto en Estados Unidos como en Europa. [29] Varias corporaciones, incluida FlightAware [30], utilizan Tcl como parte de sus productos.
Las características de Tcl incluyen
uplevel
permite upvar
que los procedimientos interactúen con los ámbitos de las funciones que las encierran.Safe-Tcl es un subconjunto de Tcl que tiene características restringidas para que los scripts de Tcl no puedan dañar la máquina o aplicación que los aloja. [33] El acceso al sistema de archivos está limitado y se evita la ejecución de comandos arbitrarios del sistema. Utiliza un modelo de intérprete dual con el intérprete no confiable ejecutando código en un script no confiable. Fue diseñado por Nathaniel Borenstein y Marshall Rose para incluir mensajes activos en el correo electrónico. Safe-Tcl se puede incluir en el correo electrónico cuando se admiten las funciones application/safe-tcl y multipart/enabled-mail . Desde entonces, la funcionalidad de Safe-Tcl se ha incorporado como parte de las versiones estándar de Tcl/Tk. [34] [35]
La sintaxis y la semántica de Tcl están cubiertas por doce reglas [36] conocidas como Dodekalogue. [37]
Un script Tcl consta de una serie de invocaciones de comandos. Una invocación de comando es una lista de palabras separadas por espacios en blanco y terminadas con una nueva línea o punto y coma. La primera palabra es el nombre de un comando, que puede estar integrado en el lenguaje, encontrarse en una biblioteca disponible o definirse en el propio script. Las palabras siguientes sirven como argumentos del comando:
commandName argumento1 argumento2 ... argumentoN
El siguiente ejemplo utiliza el comando puts (abreviatura de "put string") para mostrar una cadena de texto en la consola del host:
pone "¡Hola, mundo!"
Esto envía la cadena "¡Hola, mundo!" al dispositivo de salida estándar junto con un carácter de nueva línea adjunto.
Las variables y los resultados de otros comandos se pueden sustituir en cadenas, como en este ejemplo que utiliza los comandos set y expr para almacenar el resultado de un cálculo en una variable (tenga en cuenta que Tcl no utiliza =
como operador de asignación) y luego utiliza puts para imprimir el resultado junto con un texto explicativo:
# expr evalúa la cadena de texto como un conjunto de expresiones suma [expr 1 + 2 + 3 + 4 + 5 ] pone "La suma de los números 1..5 es $suma".
El #
carácter introduce un comentario . Los comentarios pueden aparecer en cualquier lugar donde el intérprete espere un nombre de comando.
# con llaves, la sustitución de variable se realiza mediante expr set x 1 set sum [expr { $x + 2 + 3 + 4 + 5 }]; # $x no se sustituye antes de pasar el parámetro a expr; # expr sustituye 1 por $x mientras evalúa la expresión puts "La suma de los números 1..5 es $sum." ; # la suma es 15
# sin llaves, la sustitución de variable ocurre en el sitio de definición (alcance léxico) set x 2 set op * set y 3 set res [expr $x$op$y ]; # $x, $op y $y se sustituyen, y la expresión se evalúa como 6 puts "$x $op $y es $res." ; # $x, $op, $y y $res se sustituyen y se evalúan como cadenas
Como se ve en estos ejemplos, existe una construcción básica en el lenguaje: el comando. Los mecanismos de comillas y las reglas de sustitución determinan cómo se procesan los argumentos de cada comando.
Se produce una sustitución especial antes del análisis de cualquier comando o argumento. Si el carácter final de una línea (es decir, inmediatamente antes de una nueva línea) es una barra invertida, entonces la combinación de barra invertida y nueva línea (y cualquier espacio o tabulación inmediatamente después de la nueva línea) se reemplaza por un solo espacio. Esto proporciona un mecanismo de continuación de línea , por medio del cual las líneas largas en el código fuente pueden pasar a la siguiente línea para comodidad de los lectores.
Continuando con el procesamiento normal de argumentos, una palabra que comienza con un carácter de comillas dobles ( "
) se extiende hasta el siguiente carácter de comillas dobles. Por lo tanto, una palabra de este tipo puede contener espacios en blanco y punto y coma sin que esos caracteres se interpreten como si tuvieran un significado especial (es decir, se tratan como caracteres de texto normales). Una palabra que comienza con un carácter de llave de apertura ( {
) se extiende hasta el siguiente carácter de llave de cierre ( }
). Dentro de las llaves se suprimen todas las formas de sustitución, excepto la eliminación de nueva línea con barra invertida mencionada anteriormente. Las palabras que no están encerradas en ninguna de las construcciones se conocen como palabras simples.
En palabras simples y entre comillas dobles, pueden ocurrir tres tipos de sustitución:
[expr 1+2+3]
se reemplaza por el resultado de evaluar la expresión contenida (en este caso, 6).$foo
se reemplaza por el contenido de la variable llamada "foo". El nombre de la variable puede estar entre llaves para separarlo del texto posterior en casos que de otro modo serían ambiguos (por ejemplo, ${foo}ing
).\n
se reemplaza por una nueva línea.La sustitución se realiza de izquierda a derecha en un solo escaneo de cada palabra. El texto sustituido no se escaneará nuevamente para posibles sustituciones posteriores. Sin embargo, puede aparecer cualquier cantidad de sustituciones en una sola palabra.
Desde Tcl 8.5 en adelante, cualquier palabra puede tener como prefijo {*}
, lo que hace que la palabra se divida en sus subpalabras constituyentes a los efectos de construir la invocación del comando (similar a la ,@
secuencia de la función quasiquote de Lisp ).
Como consecuencia de estas reglas, el resultado de cualquier comando puede usarse como argumento para cualquier otro comando. Nótese que, a diferencia de los shells de comandos de Unix , Tcl no vuelve a analizar ninguna cadena a menos que se le indique explícitamente que lo haga, lo que hace que el uso interactivo sea más complicado, pero el uso con scripts más predecible (por ejemplo, la presencia de espacios en los nombres de archivo no causa dificultades).
El signo de igualdad simple ( =
) no cumple ninguna función especial en el lenguaje. El signo de igualdad doble ( ==
) es la prueba de igualdad que se utiliza en contextos de expresión como el expr
comando y en el primer argumento de if
. (Ambos comandos son parte de la biblioteca estándar; no tienen un lugar especial en la biblioteca y se pueden reemplazar si se desea).
La mayoría de los comandos Tcl, especialmente en la biblioteca estándar, son variádicos , y proc
(el constructor para procedimientos de comandos con script) permite definir valores predeterminados para argumentos no especificados y un argumento general para permitir que el código procese una cantidad arbitraria de argumentos.
Tcl no tiene tipos estáticos: cada variable puede contener números enteros, flotantes, cadenas, listas, nombres de comandos, diccionarios o cualquier otro valor; los valores se reinterpretan (sujetos a restricciones sintácticas) como otros tipos según demanda. Sin embargo, los valores son inmutables y las operaciones que parecen cambiarlos en realidad solo devuelven un nuevo valor.
Los comandos más importantes que hacen referencia a la ejecución de programas y operaciones con datos son:
set
Escribe un nuevo valor en una variable (crea una variable si no existía). Si se utiliza solo con un argumento, devuelve el valor de la variable dada (debe existir en este caso).proc
define un nuevo comando, cuya ejecución da como resultado la ejecución de un script Tcl determinado, escrito como un conjunto de comandos. return
se puede utilizar para devolver inmediatamente el control al llamador.Los comandos de control de ejecución habituales son:
if
ejecuta el cuerpo del script dado (segundo argumento), si se cumple la condición (primer argumento). Puede ir seguido de argumentos adicionales a partir de elseif
la condición y el cuerpo alternativos, o else
del bloque complementario.while
repite la ejecución del cuerpo del script dado, siempre que la condición (primer argumento) permanezca satisfechaforeach
ejecuta el cuerpo dado donde a la variable de control se le asignan los elementos de la lista uno por uno.for
atajo para inicializar la variable de control, la condición (como en while
) y la declaración adicional "próxima iteración" (comando ejecutado después de ejecutar el cuerpo)Los comandos de bucle anteriores se pueden controlar adicionalmente mediante los siguientes comandos:
break
interrumpe la ejecución del cuerpo y regresa del comando de buclecontinue
interrumpe la ejecución del cuerpo, pero el control se devuelve al comando de bucle. For while
significa repetir el bucle, for for
y foreach
, retomar la siguiente iteración.return
interrumpe la ejecución del cuerpo actual sin importar qué tan profundo esté dentro de un procedimiento, hasta alcanzar el límite del procedimiento, y devuelve el valor dado al llamador.expr
Pasa el argumento a un intérprete de expresión independiente y devuelve el valor evaluado. Tenga en cuenta que el mismo intérprete se utiliza también para la expresión "condicional" if
y los comandos de bucle.list
Crea una lista que incluye todos los argumentos o una cadena vacía si no se especifica ningún argumento. El lindex
comando se puede utilizar en el resultado para volver a extraer los argumentos originales.array
manipula variables de matriz .dict
manipula diccionarios (desde 8.5), que son listas con un número par de elementos donde cada dos elementos se interpretan como un par clave/valor.regexp
coincide con una expresión regular con una cadena.regsub
Realiza sustituciones basadas en la coincidencia de patrones de expresiones regulares.uplevel
es un comando que permite ejecutar un script de comando en un ámbito distinto del ámbito más interno actual en la pila.upvar
crea un enlace a una variable en un marco de pila diferente.namespace
le permite crear, acceder y destruir contextos separados para comandos y variables.apply
aplica una función anónima (desde 8.5).coroutine
, yield
, y yieldto
crear y producir valores a partir de corrutinas (desde 8.6).try
Le permite atrapar y procesar errores y excepciones.catch
Le permite capturar retornos excepcionales.zlib
Proporciona acceso a las funciones de compresión y suma de comprobación de la biblioteca Zlib (desde 8.6).uplevel
permite que un script de comando se ejecute en un ámbito distinto del ámbito más interno actual en la pila. Debido a que el script de comando puede llamar por sí mismo a procedimientos que utilizan el comando de nivel superior , esto tiene el efecto neto de transformar la pila de llamadas en un árbol de llamadas. [38]
Originalmente se implementó para permitir que los procedimientos Tcl reimplementaran comandos integrados (como for , if o while ) y aún tuvieran la capacidad de manipular variables locales . Por ejemplo, el siguiente script Tcl es una reimplementación del comando for (omitiendo el manejo de excepciones ):
proc para { initCmd testExpr advanceCmd bodyScript } { uplevel 1 $initCmd establecer testCmd [ lista expr $testExpr ] mientras {[uplevel 1 $testCmd ]} { uplevel 1 $bodyScript uplevel 1 $advanceCmd } }
upvar
organiza que una o más variables locales en el procedimiento actual hagan referencia a variables en una llamada de procedimiento envolvente o a variables globales . El comando upvar simplifica la implementación de la llamada de procedimiento por nombre y también facilita la creación de nuevas construcciones de control como procedimientos Tcl. [39]
Un comando decr que funciona como el comando integrado incr
excepto que resta el valor de la variable en lugar de sumarlo:
proc decr { varName { decremento 1 }} { upvar 1 $varName var incr var [expr { -$decrement }] }
Tcl 8.6 agregó un sistema de objetos dinámicos integrado, TclOO, en 2012. [31] Incluye características como:
oo :: clase crear fruta { método comer {} { pone "¡delicioso!" } } oo :: clase crear plátano { superclase fruta constructor {} { mi variable pelado establecer pelado 0 } método pelar {} { mi variable pelado establecer pelado 1 pone "sin piel" } método comestible ? {} { mi variable pelado devolver $pelado } método comer {} { si { ! [ mi comestible ? ]} { mi cáscara } siguiente } } poner b [ plátano nuevo ] $b comer → imprime "sin piel" y "¡delicioso!" fruta destruir $b comer → error "comando desconocido"
Tcl no tenía sintaxis orientada a objetos (OO) hasta 2012, [31] por lo que surgieron varios paquetes de extensión para permitir la programación orientada a objetos. Están muy extendidos en el código fuente de Tcl existente. Las extensiones más populares incluyen:
TclOO no solo se agregó para construir un sistema orientado a objetos sólido, sino también para permitir que los paquetes de extensión construyan abstracciones orientadas a objetos usándolo como base. Después del lanzamiento de TclOO, incr Tcl se actualizó para usar TclOO como base. [27]
El servidor web Tcl es una implementación puramente Tcl de un servidor de protocolo HTTP. Se ejecuta como un script sobre un intérprete Tcl estándar.
Apache Rivet es un sistema de programación de código abierto para Apache HTTP Server que permite a los desarrolladores utilizar Tcl como lenguaje de scripting para crear aplicaciones web dinámicas. Rivet es similar a PHP , ASP y JSP . Rivet fue desarrollado principalmente por Damon Courtney, David Welton, Massimo Manghi, Harald Oehlmann y Karl Lehenbauer . Rivet puede utilizar cualquiera de los miles de paquetes Tcl disponibles públicamente que ofrecen innumerables funciones como interacción con bases de datos (Oracle, PostgreSQL, MySQL, SQLite, etc.) o interfaces para aplicaciones populares como GD Graphics Library .
Tcl interactúa de forma nativa con el lenguaje C. [40] Esto se debe a que originalmente fue escrito para ser un marco para proporcionar una interfaz sintáctica para los comandos escritos en C, y todos los comandos en el lenguaje (incluyendo cosas que de otra manera podrían ser palabras clave , como if
o while
) se implementan de esta manera. A cada función de implementación de comando se le pasa una matriz de valores que describen los argumentos (ya sustituidos) del comando, y es libre de interpretar esos valores como crea conveniente.
Los simuladores de lógica digital a menudo incluyen una interfaz de scripting Tcl para simular los lenguajes de hardware Verilog , VHDL y SystemVerilog .
Existen herramientas (por ejemplo, SWIG , Ffidl) para generar automáticamente el código necesario para conectar funciones C arbitrarias y el entorno de ejecución de Tcl, y Critcl hace lo contrario, permitiendo incrustar código C arbitrario dentro de un script Tcl y compilarlo en el entorno de ejecución en una DLL .
El lenguaje Tcl siempre ha permitido la creación de paquetes de extensión que brindan funciones adicionales, como una interfaz gráfica de usuario, automatización de aplicaciones basada en terminales, acceso a bases de datos, etc. Las extensiones más utilizadas son: