#!/usr/bin/tclsh
set n 42
puts -nonewline "Adivina en que número estoy pensando ? "
flush stdout
scan [gets stdin] "%d" v
if {$v < 0} {
puts "Solo números positivos"
return
}
if {$n == $v} {
puts "Bien Hecho!";
} else {
set h [ expr ($v > $n) ? $v - $n : $n - $v]
puts "Sigue Probando!."
puts "El número es [expr {$v > $n ? "MAYOR" : "MENOR"}]"
puts -nonewline "PISTA : "
if {$h < 5} {puts "TE QUEMAS!!!"
} elseif {$h < 10} {puts "CALENTITO!!!"
} elseif {$h < 15} {puts "TEMPLADO"
} else {puts "FRIO"}
}
TCL nos proporciona un buen conjunto de instrucciones para construir
nuestras condiciones. Además del operador ternario con la sintaxis
clásica, nos ofrece bloques if-elseif-else
con una sintaxis
estilo C, utilizando {}
para agrupar instrucciones.
SABIAS QUE
La posición de las llaves importa. Las llaves de apertura deben estar en la misma línea que la clausula a la que pertenecen (
if
,elseif
oelse
). De la misma forma las llaves de cierre deben estar en la misma línea que las clausulas que deseemos encadenar (elseif
oelse
). La última llave}
, puede ponerse en una línea separada
TCL ofrece la instrucción switch
y al igual que
bash
trabaja directamente sobre cadenas de caracteres (algo
típico de este lenguaje). El comando switch
en TCL tiene la
peculiaridad de que ofrece diferentes opciones para determinar que caso
debe ejecutarse:
-nocase
. Ignora mayúsculas y minúsculas.-exact
. Los casos se comparan de forma exacta-glob
. Permite utilizar comodines para especificar los casos-regexp
. Permite utilizar expresiones regulares en los casos-matchvar varName
. Solo funciona con-regexp
y nos permite indicar una variable en la que se almacenaran las partes de la expresión regular que coincidan-indexvar varName
. Igual a la anterior, pero almacena los índices de inicio y fin de cada ocurrencia en la variable indicada--
. Utilizado para indicar el final de las opciones cuando se utilizan varias
Un ejemplo normal de switch
sería el siguiente:
scan [gets stdin] "%s" v
switch $v {
"ciao" -
"bye" {puts "CU" }
"hello" {puts "Hi!!" }
default {puts "A quien le importa?" }
}
Podemos utilizar el caracter -
para indicar que el
comando asociado a un determinado caso es el mismo que el del caso
siguiente…. Mirad el caso ciao en el ejemplo anterior.
TCL nos permite utilizar variables como condición para los casos,
pero en este caso debemos utilizar "
en lugar de
{}
para encerar nuestros casos, o escribir todos los casos
en una línea.
set foo "hello"
switch $v "ciao" - "bye" {puts "CU"} $foo {puts "Hi!"} \
default {puts "a quien le importa")
o
set foo "hello"
switch $v "
\"ciao\" -
\"bye\" {puts \"CU\" }
$foo {puts \"Hi!!\" }
default {puts \"A quien le importa?\" } "
Nota como es necesario escapar todas las comillas dentro de los casos.
SOY NOVATO
En la mayoría de lenguajes utilizamos algún carácter para delimitar las cadenas de caracteres, normalmente las comillas dobles
"
o las comillas simples'
. La diferencia suele ser que una permite la expansión de variables (en lenguajes que soportan esa capacidad) y las otras toman la cadena tal y como está escrita. En lenguajes como C/C++/Java, las comillas simples se utilizan para representar caracteresPero que sucede si queremos que nuestra cadena de caracteres contenga comillas?… Algo como
"Hola "fulanito""
… como podéis ver, las comillas que abrimos con la palabra fulanito serán consideradas como el final de cadena de"Hola "
… Esto normalmente producirá un error. En esos casos es necesario escapar los caracteres especiales como las comillas. En prácticamente todos los lenguajes de programación, esto se consigue anteponiendo el caracter\
al caracter especial. Así, nuestra cadena se escribiría como"Hola \"fulanito\""
.Y si.. el caracter
\
es necesario escaparlo también, así que veréis, sobre todo en windows cadenas como conteniendo\\
cuando definimos rutas a ficheros.
La razón es que si utilizamos las llaves la cadena no es expandida y por lo tanto la condición que creemos que estamos utilizando no es la correcta. En nuestro ejemplo usando las llaves:
set foo "hello"
switch $v {
"ciao" -
"bye" {puts "CU" }
$foo {puts "Hi!!" }
default {puts "A quien le importa?" }
}
Si le damos a v
el valor hello
en el
ejemplo de arriba, el bloque switch
imprimirá
A quien le importa?
. Pero si le damos el valor
$foo
, obtendremos el resultado deseado.
Podéis comprobar esto interactivamente en la shell de tcl
set foo "hello"
%
helloset v $foo
%
helloset v "$foo"
%
helloset v {$foo}
% $foo
Como podéis ver, la variable foo
es sustituida cuando se
utiliza directamente o dentro de una cadena de caracteres, sin embargo,
cuando la utilizamos dentro de un bloque, lo que obtenemos es el nombre
literalmente lo que hemos escrito $foo
en nuestro caso.
SABÍAS QUE
TCL no ofrece funciones para leer tipos especifícos de datos directamente desde un fichero. La forma de hacerlo es leer una línea completa usando
[gets stdin]
y luego utilizar la funciónscan
para obtener el tipo que queramos.gets
functiona igual que elgets
de C yscan
funciona igual que elsscanf
de C.
TCL no soporta la definición de constantes, aunque hay distintas formas de conseguir ese comportamiento. La más sencilla es utilizar el convenio de nombre en mayúsculas como en otros lenguajes, pero también se puede utilizar una traza, de la siguiente forma:
set CONSTANTE 123
trace add variable CONSTANTE write {apply {args {
global CONSTANTE
set CONSTANT 123
error "may not change constant"
}}}
La traza es un código que se ejecuta cuando sucede un determinado
evento en el programa. En este ejemplo, cuando intentamos escribir en la
variable CONSTANTE
, lo que hacemos es ignorar el nuevo
valor y volver a poner el valor constante que deseamos y mostrar un
error… ya que el hecho de que un programa intente modificar una
constante es un error lógico que debe corregirse.
Resumen
- Soporta
if ... [elsrif] ...[else] ...
- Soporta operador terciario
(cond) ? valor_Verdad : Valor_Falso
- No soporta tipo booleano:
==0 -> FALSO y !=0 VERDADERO
- Soporta
switch
- No soporta constantes nativamente
Interesado en aprender TCL
A través de nuestra cuenta del Programa de Afiliados de Amazon, te recomendamos este libro:Effective Tcl/Tk Programming: Writing Better Programs with Tcl and Tk.
Como parte de este programa, recibimos una comisión por compras realizadas utilizando este enlace.■