Erlang: «расширение» существующего модуля новыми функциями - PullRequest
2 голосов
/ 30 июня 2011

В настоящее время я пишу некоторые функции, связанные со списками, которые я мог бы использовать повторно.

Мой вопрос:

Существуют ли какие-либо соглашения или передовые практики для организации таких функций?

Чтобы сформулировать этот вопрос, в идеале я хотел бы «расширить» существующий модуль списков так, чтобы я вызывал мою новую функцию следующим образом: lists: my_funcion ().На данный момент у меня есть lists_extensions: my_function ().Есть ли способ сделать это?

Я читал о пакетах erlang и о том, что они по сути являются пространствами имен в Erlang.Можно ли определить новое пространство имен для списков с новыми функциями списков?

Обратите внимание, что я не собираюсь разбирать и изменять модуль стандартных списков, но чтобы найти способ определения новых функций в новом модуле, также называемом списками, но избегать последующих конфликтов имен, используя некоторое пространство именсхема.

Буду признателен за любые советы или рекомендации.

Приветствия.

Ответы [ 4 ]

4 голосов
/ 30 июня 2011

Чтобы сформулировать этот вопрос, в идеале я хотел бы «расширить» существующий модуль списков так, чтобы я вызывал мою новую функцию следующим образом: lists: my_funcion (). На данный момент у меня есть lists_extensions: my_function (). Есть ли в любом случае, чтобы сделать это?

Нет, насколько я знаю.

Я читал о пакетах erlang и о том, что они по сути являются пространствами имен в Erlang. Можно ли определить новое пространство имен для списков с новыми функциями списков?

Они экспериментальные и обычно не используются . Вы можете иметь модуль с именем lists в другом пространстве имен, но у вас будут проблемы с вызовом функций из стандартного модуля в этом пространстве имен.

1 голос
/ 07 марта 2017

Я думаю, что этот метод будет работать на любом дистрибутиве:

Вы можете создать приложение, которое автоматически переписывает основные модули erlang, независимо от того, какой дистрибутив работает. Добавьте свои пользовательские функции к основным модулям и перекомпилируйте их перед компиляцией и запуском собственного приложения, которое вызывает пользовательские функции. Это не требует пользовательского распространения. Просто тщательное планирование и использование файловых инструментов и BIF для компиляции и загрузки. * Вы хотите убедиться, что вы не добавляете свои функции каждый раз. После перезаписи файла он будет постоянным, если пользователь не заменит файл позже. Можно использовать проверку с module_info, чтобы подтвердить, что ваши пользовательские функции существуют, чтобы решить, нужно ли вам запускать модуль записи расширений.

Псевдо-пример:

lists_funs() -> ["myFun() -> <<"things to do">>."].
extend_lists() -> 
   {ok, Io} = file:open(?LISTS_MODULE_PATH, [append]),
   lists:foreach(fun(Fun) -> io:format(Io,"~s~n",[Fun]) end, lists_funs()),
   file:close(Io),
   c(?LISTS_MODULE_PATH).

* Возможно, вы захотите сохранить копии исходных модулей для восстановления, если компилятор выйдет из строя таким образом, вам не нужно делать ничего тяжелого, если вы допустили ошибку в своем списке функций, а также использовали в качестве источника в любое время, когда захотите перепишите модуль, чтобы расширить его дополнительными функциями. * Вы можете использовать модуль list_extension, чтобы сохранить всю логику для ваших функций и просто передать функции в список в этой функции, используя funName(Args) -> lists_extension:funName(Args). * Вы также можете создать систему переопределения, которая ищет существующие функции и переписывает их аналогичным образом, но это более сложно. Я уверен, что есть много способов улучшить и оптимизировать этот метод. Я использую нечто подобное для обновления некоторых своих собственных модулей во время выполнения, поэтому я не вижу причин, по которым это не будет работать и для основных модулей.

1 голос
/ 30 июня 2011

Я объясняю, почему не , чтобы использовать lists:your_function(), а вместо этого используйте lists_extension:your_function():

  • Как правило, в Руководстве по проектированию Erlang / OTP говорится, что каждое «Приложение» - библиотеки также являются приложением - содержит модули. Теперь вы можете спросить у системы , какое приложение внедрило определенный модуль? Эта система сломалась бы, если модули фрагментированы.

Однако я понимаю, почему вы хотите a lists:your_function/N:

  • Его проще использовать автору your_function, потому что он очень нуждается в your_function(...) при работе с []. Когда другой программист на Эрланге - который знает stdlb - читает этот код, он не будет знать, что он делает. Это сбивает с толку.
  • выглядит более лаконично, чем lists_extension:your_function/N. Это дело вкуса.
0 голосов
/ 30 июня 2011

Полагаю, вы хотите, чтобы некоторые из ваших функций были доступны из модуля списков.Хорошо, что вы захотите преобразовать часто используемый код в библиотеку.

один из способов сделать это - хорошо протестировать свои функции, и если они в порядке, скопируйте их, вставьте их в модуль lists.erl (ВНИМАНИЕ: убедитесь, что вы не перезаписываете существующие функцииПросто вставьте в конец файла) .этот файл можно найти по пути $ERLANG_INSTALLATION_FOLDER/lib/stdlib-{$VERSION}/src/lists.erl.Убедитесь, что вы добавили свои функции среди тех, которые экспортированы в модуле списков (в -export([your_function/1,.....])), чтобы сделать их доступными из других модулей.Сохраните файл.

Как только вы это сделаете, нам нужно перекомпилировать модуль списков.Вы можете использовать EmakeFile.Содержимое этого файла будет следующим:

{"src/*", [verbose,report,strict_record_tests,warn_obsolete_guard,{outdir, "ebin"}]}.

Скопируйте этот текст в файл с именем EmakeFile.Поместите этот файл в путь: $ERLANG_INSTALLATION_FOLDER/lib/stdlib-{$VERSION}/EmakeFile.

Как только это будет сделано, откройте оболочку erlang и дайте ее pwd() текущей рабочейдиректорией будет путь, по которому находится EmakeFile, т.е. $ERLANG_INSTALLATION_FOLDER/lib/stdlib-{$VERSION}/.

Вызовите функцию: make:all() в оболочке, и вы увидите, что модульсписки перекомпилированы.Закройте оболочку.

После открытия новой оболочки erlang и при условии, что вы экспортировали свои функции в модуль списков, они будут работать так, как вам нужно, прямо в модуле списков.Erlang с открытым исходным кодом позволяет нам добавлять функциональность, перекомпилировать и перезагружать библиотеки.Это должно делать то, что вы хотите, успех.

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