tcl "switch -glob" не совпадает с переменной - PullRequest
1 голос
/ 16 июля 2010

Я столкнулся с этой проблемой как в Solaris, так и в Linux с tcl версии 8.3 / 8.4

см. Следующий код:

#!/usr/bin/tclsh

set pattern "this is * and *"
set str "this is tcl and c++"

switch -glob $str {

  $pattern {
    puts "matched pattern"
  }
  "this is * and *" {
    puts "matched plain text"
  }
  default {
    puts "matched none"
  }

}

и в результате получается "соответствующий простой текст". Я думал, что он должен соответствовать шаблону $ ... это неправильное использование ключа или я не даю правильный шаблон для опции -glob?

пожалуйста, кто-нибудь подскажет, и было бы лучше, если бы вы могли рассказать, как изменить код, чтобы он работал с переключателем и переменной.

Спасибо! XM

1 Ответ

7 голосов
/ 16 июля 2010

Полагаю, вы неправильно понимаете, как работает анализ / замена Tcl. В частности, команда glob получает аргументы:

1: -glob
2: $str
3: {

  $pattern {
    puts "matched pattern"
  }
  "this is * and *" {
    puts "matched plain text"
  }
  default {
    puts "matched none"
  }

}

Конструкция {...} "группирует" вещи внутри него в один незамещенный (дословно) фрагмент данных. Таким образом, третий аргумент для переключения содержит «$ pattern», а не результат замены $ pattern значением переменной pattern.

Если вам нужна замена, вам следует избегать использования фигурных скобок (я упрощаю). Таким образом, если вы действительно хотите подставить значение для шаблона, самый простой способ сделать это - использовать другую форму переключателя (которая передается в каждом блоке шаблона / кода в качестве отдельного аргумента):

switch -glob $str $pattern {
    puts "matched pattern"
} "this is * and *" {
    puts "matched plain text"
} default {
    puts "matched none"
}

Как примечание, почти всегда неплохо использовать флаг - (не более флагов) с параметром switch, когда вы используете подстановку переменной для соответствия строки. Это позволяет избежать проблемы, когда ваш $str содержит что-то, начинающееся с -

switch -glob -- $str $pattern {
    puts "matched pattern"
} "this is * and *" {
    puts "matched plain text"
} default {
    puts "matched none"
}
...