Какой термин используется для описания функции / метода, который модифицирует вызываемый объект?

12

Извините за общий вопрос. Я искал повсюду и нашел так много тем, похожих на эту, но не ту, которая отвечает на мой конкретный вопрос - возможно, потому что искомый термин даже не существует.

Мой друг изучает программирование, особенно JavaScript, и спросил меня, почему это не работает:

var a = "Hello World";
a.replace("Hello", "Goodbye");

console.log(a)  // Logs "Hello World"

Причина в том, что replaceне изменяется a, поскольку строки являются неизменяемыми в JavaSript. Поскольку он возвращает строку, вам нужно сделать что-то вроде ...

var a = "Hello World";
a = a.replace("Hello", "Goodbye");

console.log(a);  // Logs "Goodbye World"

Однако альтернативой является функция, подобная JavaScript reverse(), так как она изменяет все, что ее вызывает. Например:

var fruits = ["Apples", "Oranges", "Bananas"];
fruits.reverse();

console.log(fruits)  // ["Bananas", "Oranges", "Apples"]

Когда мой друг спросил меня, почему он replaceне работает, я понял, что искал слово, которое я не знаю (насколько я знаю) ...

Msgstr "Вы должны установить строку как" замена точки строки ", потому что функция замены - ________."

Вам не нужно устанавливать массив равным «обратная точка массива», потому что обратный - ________. »

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

Santi
источник
6
Может быть, слово «мутатор»? как в: You don't need to set an array equal to "array dot reverse", because reverse is a mutator function. Я думаю, что я слышал эту терминологию для обозначения функций, которые "видоизменяют" экземпляр, который их вызывает. Но вам, вероятно, стоит проверить это еще где-нибудь.
FrustratedWithFormsDesigner
Ценить это! Я только что прочитал Mutator Methods и думаю, что он вполне вписывается в этот разговор. Конечно, в области того, что я ищу.
Санти
Я смущен: в названии, вы спрашиваете о функции , которая модифицирует объект , который назвал его, но в ваших примерах, вы показываете методы , которые изменяют объект их называют на , то есть полную противоположность названию. Что из двух это?
Йорг Миттаг
Ну, конечно, тот, который объяснен в 30 строках. Я изменю название, чтобы быть точным, спасибо за заголовок!
Санти

Ответы:

12

Пара понятий, которые вы ищете, это изменчивые / неизменные параметры и на месте / возвращение результатов.

В ваших примерах:

Вы должны установить строку «string dot replace», потому что функция replace работает со строкой, которая в python неизменна, поэтому функция replace возвращает новую строку.

Для программиста C / C ++ это более привычно, поскольку параметры «передаются по значению», а не «передаются по ссылке», что делает их неизменяемыми и возвращает результат.

Вам не нужно устанавливать массив равным «обратному массиву точек», потому что обратный метод работает с массивом, который является изменяемым , поэтому может вносить изменения на месте перед возвратом.

В таких языках, как C / C ++, это называется параметрами, «передаваемыми по ссылке», то есть передачей адреса, который, если он не изменен const, позволяет функции изменять, мутировать содержимое этого адреса, изменяя результаты на месте перед возвратом.

Конечно, нет ничего необычного в том, чтобы иметь функцию, которая возвращает результаты обоими механизмами, например, int SomeFn(int p1, int p2, int *ErrCode)может, потенциально возвращать результаты как в возвращаемом значении, так и путем изменения содержимого ErrCode.

3-й метод

Для полноты 3-й механизм возврата результатов является побочным эффектом или глобальным , то есть изменяя область файла, обще программные, общие или окружающие значения. Обычно это считается плохой новостью, поскольку, если не очень хорошо задокументировано, вы можете узнать только то, что изменяется, внимательно прочитав код. В таких языках, как C / C ++, это слишком легко сделать, имея внешнюю переменную области с заданным именем, возможно, даже в другом модуле, и не маскируя локальную переменную области с тем же именем. В Python вы можете читать значения значений во внешних областях, если только внешние значения области явно не установлены как доступные для изменения с помощьюglobal Ключевое слово, при попытке изменить внешнюю переменную области автоматически создает локальный файл с тем же именем.

Стив Барнс
источник
Ах, я знаком с этими терминами, хотя я не был уверен, было ли на самом деле слово, которое описывает саму функцию . Как и в (The reverse function is a _______ function.) Это, как говорится, это почти идентичный ответ на тот, который я в конечном итоге дал мой друг, поэтому я ценю ваше подтверждение - хотя я все еще задаюсь вопросом, есть ли конкретные условия. Я позволю этому вопросу остаться открытым некоторое время, но, безусловно, приму это как ответ в случае, если этих слов просто не существует.
Santi
2
В некоторых языках, таких как python, у вас также могут быть классы, которые изменяют сами себя - в то время как в некоторых контекстах это «исправление обезьян» считается хорошим, во многих оно считается «самоизменяющимся кодом» и запрещено. Вы также можете иметь «эволюционный код», где фрагменты кода случайным образом «видоизменяются» и / или комбинируются, а затем тестируются и выбираются для «лучшей» производительности тем или иным способом.
Стив Барнс,
-1. Независимо от того, являются ли строки изменяемыми или неизменяемыми, это не имеет отношения к функции, которая над ними работает. Функция не является изменяемой или неизменной, и она не «возвращается или находится на месте». Функции могут изменять свои аргументы и по-прежнему возвращать.
Майлз Рут
@MilesRout добавил, что функции, которые модифицируются на месте, по-прежнему возвращают и некоторые примеры C / C ++ для ясности плюс результаты по побочным эффектам для полноты.
Стив Барнс
4

Мой предпочтительный способ выразить это:

  • Массив reverseметод мутирует . Это мутатор . Распространенным частным случаем является сеттер .

  • Метод String не replaceявляется мутирующим . Это не мутатор . Если это не меняет ничего , это побочный эффект бесплатно . Распространенным частным случаем является добытчик .

  • Поскольку строки JavaScript являются неизменяемыми , методы String не могут быть мутированными.

    "Hello World" .replace ("Привет", "До свидания");

    должно сделать вас неудобным. Он не изменяет строковый литерал. Это отбрасывает результат. Статические анализаторы кода иногда могут обнаруживать такие ошибки.

  • Поскольку JavaScript-массивы являются изменяемыми , методы Array могут изменяться. JavaScript имеет тенденцию использовать массивы в качестве локальных хранилищ, которые легко модифицируются и редко копируются.
Jerry101
источник
2

Иногда при использовании в контексте чисто функционального программирования я слышал функции, которые изменяют входное значение (и, следовательно, не являются чисто функциями), называемые деструктивными . Я не уверен, что это правильный термин, хотя.

В вашем случае вы бы сказали:

Вы должны установить строку как «замена точечной строки», потому что функция замены не является разрушительной .

Вам не нужно устанавливать массив, равный «обратная точка массива», потому что обратный является разрушительным .

Challenger5
источник
1

Возможно, чистое слово, которое вы ищете?

replace()является (или кажется) чистым, потому что не имеет побочных эффектов (т. е. reverse()изменяет строку), тогда как является нечистым, потому что изменяет состояние массива.

Кайл Раш
источник
Это связанная концепция, но она подразумевает и другие свойства (например, отсутствие доступа к глобальному состоянию и всегда выдачу одного и того же вывода для одного и того же ввода).
Джейкоб Райл
1

Они обычно разделяются на функции и методы (где методы являются подмножеством функций). Функция - это фрагмент кода, который можно вызывать изолированно, в то время как у метода есть понятие текущего «контекста», над которым он работает. Действие метода изменяет состояние его контекста.

В объектно-ориентированном программировании контекст является экземпляром, над которым работает функция.

richzilla
источник
0

Я не знаю, есть ли официальный ответ, но вот два, которые вам могут понравиться.

Процедура

Только потому, что это казалось хорошим ответом на этот вопрос , который очень похож на ваш вопрос, кстати, вы должны это проверить.

На месте одинарная операция

Просмотрите эту страницу: java.util.function . Он предоставляет своего рода выдуманное имя для делегатов (входные / выходные сигнатуры) различных прототипов, например, делегат, который принимает аргумент и ничего не возвращает, называется потребителем .

Теперь, будучи проницательным учеником ООП, вы должны знать, что метод - это просто функция, которая принимает скрытый параметр ( this). Поскольку он предоставляется в качестве ссылки, он служит как входным, так и выходным параметром.

Согласно этим Java-парням (и они кажутся довольно умными), делегат, который принимает один вход и возвращает значение того же типа, называется унарным оператором .

Теперь, в случае array::Reverse(), массив не является неизменным и потенциально может занимать много места, поэтому более эффективно и удобно выполнять операцию на месте. Поэтому Reverse()это унарный оператор на месте .

Но для меня «оператор» - это специальный символ (например, оператор сложения, также известный как +) или математическое ключевое слово, подобное mod. Поэтому я предпочитаю называть это Operat ионом , получая в месте унарных операций .

Джон Ву
источник
Вы путаете понятия. Reverse()не является оператором, унарный оператор не должен возвращать значение одного и того же типа (например !, delete, typeof), а операторы не являются делегатами. Но «на месте» - это хороший термин для метода, который модифицирует его экземпляр. [Я не голосовал против, но похоже, что кто-то проголосовал против всех ответов, хотя все они полезны.]
Jerry101
Не уверен, что вы подписаны Любой прототип может быть представлен делегатом. «Оператор» не работает для меня (как я уже сказал), поэтому я говорю «Операция», и да, действительно Reverse(), это унарная операция. Но в целом я согласен, что все это немного странно, но я дословно использую терминологию из связанного документа , который, кажется, был создан некоторыми довольно умными людьми. По крайней мере, это лучше, чем ничего.
Джон Ву
А ну понятно! Обратите внимание, что для модернизации лямбд в Java они основывались на идее функционального интерфейса ( интерфейс Java только с одним методом), чтобы мы могли передавать обычные объекты Java для применения в качестве «функций». (У Брайана Гетца есть технический доклад по добавлению лямбд. Несколько раз он говорит, что «очевидный подход был бы отстой».) При создании функциональных интерфейсов для объектов потоковой обработки они используют такие термины, как «оператор». Это сбивает с толку! Должно быть, у них кончились добрые имена. Я не думаю, что это хороший источник терминов для методов ООП, которые делают / не модифицируют объект-получатель.
Jerry101