Использование строк вместо символов: добро или зло? - PullRequest
19 голосов
/ 02 марта 2011

Довольно часто я сталкиваюсь со списками параметров функций (или более общими списками замены) вида {foo->value,...}.Это приводит к ошибкам, когда foo уже имеет значение в $ Context.Одним из очевидных способов предотвратить это является использование строки «foo» вместо символа: {"foo"->value,...}.Это работает, но, кажется, привлекает некоторых опытных LISPers, которых я знаю, которые наказывают меня за объединение символов и строк и говорят мне использовать встроенные конструкции цитирования.Можно написать код, который позволяет избежать коллизий без использования строк, это часто кажется больше проблем, чем оно того стоит.С другой стороны, я не видел слишком много примеров правил замены типов {"string"->value}.Итак, вопрос к вам - это приемлемый шаблон использования? .. Есть ли случаи, когда он особенно уместен? .. Где его следует избегать? ..

1 Ответ

17 голосов
/ 02 марта 2011

По моему мнению (отказ от ответственности - это только мое мнение), лучше избегать использования строк в качестве имен опций, по крайней мере, для "основных" опций в вашей функции. Строки OTOH полностью подходят в качестве настроек (ч.с. опций). Это не означает, что вы не можете использовать строки, как вы заметили. Возможно, они могли бы быть более подходящими для подопций, и они используются таким образом многими системными функциями (обычно «суперфункциями», такими как NDSolve, которые могут иметь подопции в опциях). Основные проблемы, с которыми я сталкиваюсь при использовании строк, заключаются в том, что они уменьшают возможности самоанализа как для системы, так и для пользователя. Другими словами, найти вариант с строковым именем труднее, чем с именем символа - для последнего я могу просто проверить имена символов в пакете, а также имена символических опций имеют сообщения об использовании. Вы также можете захотеть автоматизировать некоторые вещи, такие как написание утилиты, которая находит все имена опций в пакете и т. Д. Это проще сделать, когда имена опций являются символами, поскольку все они принадлежат одному и тому же контексту. Также легко обнаружить, что некоторые опции не имеют сообщений об использовании, это можно сделать автоматически, написав служебную функцию.

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

Что касается возможных коллизий, если вы следуете некоторым соглашениям об именах, таким как имя опции, всегда начинающееся с заглавной буквы, плюс большая часть кода добавляется в пакеты, и вы не запускаете имена переменных или функций (для функций в интерактивном сеансе ), с большой буквы, тогда вы значительно уменьшите вероятность таких столкновений. Кроме того, вы должны Protect имен опций, когда вы определяете их, или в конце пакета. Затем столкновения будут обнаружены как случаи затенения. Избегание теневого копирования, OTOH, является общей необходимостью, поэтому регистр параметров в этом отношении не более особенный, чем для имен функций и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...