Судя по вашим комментариям к этому ответу, вы ожидаете, что в ответе будет сказано и признано, что парадигма zsh «лучше» и, следовательно, так должны работать все оболочки. "Лучше" - это просто мнение. Мнение не требует обсуждения.
Возможно, вы ожидаете узнать, почему $a
можно также использовать для массива.
Это то, что пытается сделать zsh, и даже если он проделал большую работу в этом направлении,
в некоторых случаях он все еще терпит неудачу. Он еще не копирует массивы ().
$ a=(1 2 3)
$ b=$a
$ printf '<%s>' $a ' ' $b; echo
<1><2><3>< ><1 2 3>
В нашем языке мы используем имя для каждой идеи. Каждая новая идея, которая радикально отличается от предыдущих идей , должна иметь собственное имя. Для нашего языка естественно, что мы принимаем новые слова для новых идей. Подумайте о названии «Интернет», новом имени для новой идеи. Использование старых названий для новых понятий всегда приводит к путанице и недопониманию. Вот как мы, люди, устроены, и звучит разумно, если подумать.
С самого началапеременная в оболочке использовала имя (accepta
)и ее значение было результатом расширения (процедуры оболочки )символов $a
. Переменная могла содержать строку или число (, автоматически преобразованное ).
Это именно то, что Perl сделал, используя @a
для обозначения списка , сохраняя при этом $a
для an scalar
.
То есть:Вышеупомянутые два называются контекстом SCALAR и LIST.(В Perl).
Вот почему у нас есть a=(1 2)
для назначения массива (есть и другие способы, но это наиболее распространенный ). Синтаксис, недопустимый в предыдущих оболочках.
В ш (в данном случае тире):
$ a=(12)
sh: 2: Syntax error: "(" unexpected
И расширение переменной было расширено с $a
или эквивалентного ${a}
на новый синтаксис (и недействительно в sh)`${a[@]}:
$ a=(aa bb cc)
$ printf '%s\n' "${a[@]}"
aa
bb
cc
В более простых оболочках (зола в данном случае):
$ a=Strin-Of-Text
$ printf '%s\n' "$a"
ash: syntax error: bad substitution
Очень жаль, что был выбран такой запутанный способ записи массива.
Если бы я предложил один новый синтаксис, я бы, вероятно, последовал примеру Perl и использовал что-то похожее на "@a" для списка значений (или, может быть, #a
или%a
). Это должно стать предметом некоторого обсуждения для достижения определенного консенсуса.
${a[@]}
. Короче :Для обратной совместимости ожидается, что раскрытие простой переменной $a
приводит только к одному значению, а не к списку значений, более того, к отдельным значениям.
Поскольку в POSIX не определены массивы, в -может быть целесообразно указать, что в POSIX определение Расширение параметра говорит:
The value, if any, of parameter shall be substituted.
И, ну,на самом деле, большинство оболочек печатают только скаляр с$a
bash(4.4) : <1><====><1><2><3>
lksh : <1><====><1><2><3>
mksh : <1><====><1><2><3>
ksh93 : <1><====><1><2><3>
astsh : <1><====><1><2><3>
zsh/ksh : <1><====><1><2><3>
zsh : <1><2><3><====><1><2><3>
Таким образом, для написания сценариев оболочки zsh [a] является нечетным.
Протестировано с этим скриптом:
a=(1 2 3)
printf '<%s>' $a '====';
printf '<%s>' "${a[@]}" ;
echo
[а] Тоже яш. csh-совместимые оболочки не тестировались. Скрипты с csh - известная проблема.
причина в том, что normal
— это не стиль/вес, а определение ширины.
[root@ArchTestVM ~]# fc-pattern "Roboto: normal"
Pattern has 2 elts (size 16)
family: "Roboto"(s)
width: 100(i)(s)
[root@ArchTestVM ~]# fc-pattern "Roboto: regular"
Pattern has 2 elts (size 16)
family: "Roboto"(s)
weight: 80(i)(s)
[root@ArchTestVM ~]# fc-pattern "Roboto: medium"
Pattern has 2 elts (size 16)
family: "Roboto"(s)
weight: 100(i)(s)
[root@ArchTestVM ~]# fc-pattern "Roboto: normal:medium"
Pattern has 3 elts (size 16)
family: "Roboto"(s)
weight: 100(i)(s)
width: 100(i)(s)
Шаблон «Roboto :normal» не содержит определения веса или семейства и, таким образом, отображается в обычный.
Можно подобрать по ширине и изменить вес, но это, возможно, не то, что Вам нужно:
<match target="pattern">
<test name="width" qual="any" compare="eq"><int>100</int></test>
<edit name="weight" mode="assign" binding="strong"><int>100</int></edit>
</match>
<match target="pattern">
<test name="weight" qual="any" compare="eq"><int>80</int></test>
<edit name="weight" mode="assign" binding="strong"><int>100</int></edit>
</match>
[root@ArchTestVM ~]# fc-match "Roboto: normal"
SourceCodePro-Medium.otf: "Source Code Pro" "Medium"
[root@ArchTestVM ~]# fc-match "Roboto: normal:bold"
SourceCodePro-Medium.otf: "Source Code Pro" "Medium"
[root@ArchTestVM ~]# fc-pattern "Roboto: normal"
Pattern has 2 elts (size 16)
family: "Roboto"(s)
width: 100(i)(s)
[root@ArchTestVM ~]# fc-pattern "Roboto: normal:bold"
Pattern has 3 elts (size 16)
family: "Roboto"(s)
weight: 200(i)(s)
width: 100(i)(s)
Вы бы изменили жирный шрифт на средний только потому, что он определяет ширину с помощью 100.
Или Вы ищете способ изменить вес по умолчанию, если вес в шаблоне не определен равным 100?
Правка. Даже явно заданный вес вместо ширины не работает:
[root@ArchTestVM ~]# fc-match "Roboto: weight=normal"
Fontconfig error: Unexpected constant name `normal' used for object `weight': should be `width'
Unable to parse the pattern
Это имеет смысл, так как для веса 80 есть обычное слово, а для ширины 100 нет другого слова, и хорошо, что ключевые слова можно различить. Просто вопрос, почему они разрешают «обычный» псевдоним «обычным» в тегах <const>
в соответствии с документами.