Erlang re и перечисляет основную разницу индексов - PullRequest
0 голосов
/ 12 мая 2018

Просто столкнулся с этим странным случаем, нарушив Принцип наименьшего удивления (каким бы субъективным он ни был).

При использовании re: run / 2 я получаю кортежи для захваченных групп.На следующей строке я извлекаю захваченные подстроки.К моему большому удивлению, индексация символов несовместима между этими двумя операциями.Re: run / 2 CaptureData основан на 0, а списки: sublist / 3 основан на 1:

172> Line = "8#123abc#".                  
"8#123abc#"
173> re:run(Line,"^(\\d+)#(.+#$)").
{match,[{0,9},{0,1},{2,7}]}
174> lists:sublist(Line,0,1).
** exception error: no function clause matching lists:nthtail(-1,"8#123abc#") (lists.erl, line 180)
     in function  lists:sublist/3 (lists.erl, line 345)
175> lists:sublist(Line,1,1).
"8"

У кого-нибудь есть идеи, как объяснить это удивительное несоответствие?Извините, если этот вопрос больше касается философии решения проблем (решение здесь достаточно очевидно).

1 Ответ

0 голосов
/ 24 мая 2018

К сожалению, по историческим причинам в библиотеках OTP имеется ряд несоответствий API.Erlang / OTP очень серьезно относится к обратной совместимости, что, к сожалению, также означает, что для исправления плохих API требуется очень много времени.Если когда-либо.

Некоторые примеры подобных несоответствий:

  • Названия модулей string и queue являются существительными в единственном числе по сравнению с существительными во множественном числе, использованными для lists илиmaps.
  • Модуль string использует индексирование на основе 1, а binary - на основе 0.
  • Если вы хотите найти значение из dict илиmap, вы передаете ключ в качестве первого аргумента, а коллекцию - в качестве второго.Для ets таблиц порядок аргументов противоположен.

Elixir приложил большие усилия для создания непротиворечивых API в своих стандартных библиотеках.

Что касается этого конкретногопроблема, которую вы обнаружили: я предполагаю, что модуль string использует индексирование на основе 1, поскольку строки на самом деле представляют собой списки кодовых точек, а модуль lists также использует индексирование на основе 1 (но я не знаю почему).Что касается re, он, вероятно, использует индексирование на основе 0, потому что двоичные файлы используют это, и я думаю, что сопоставление регулярному выражению выполняется для двоичных файлов, а не списков (код регулярного выражения основан на libpcre, проекте C,поэтому здесь имеет смысл использовать двоичные файлы и индексирование на основе 0).

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