Qual è il termine usato per descrivere una funzione / metodo che modifica l'oggetto su cui è chiamato?

12

Ci scusiamo per la domanda generica. Ho cercato dappertutto e ho trovato così tanti thread simili a questo, ma non uno che risponde alla mia domanda specifica - forse perché il termine che sto cercando non esiste nemmeno.

Un mio amico sta imparando la programmazione, JavaScript in particolare, e mi ha chiesto perché non funzionava:

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

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

Il motivo è perché replace non modifica a , poiché le stringhe sono immutabili in JavaSript. Perché restituisca una stringa, avresti bisogno di fare qualcosa del tipo ...

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

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

Tuttavia, l'alternativa è una funzione come reverse() di JavaScript, poiché modifica qualunque cosa la chiami. Ad esempio:

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

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

Quando il mio amico mi ha chiesto perché il suo replace non funzionava, ho capito che stavo raggiungendo una parola che non so (per quanto ne so) ...

"You have to set the string to "string dot replace", because the replace function is ________."

You don't need to set an array equal to "array dot reverse", because reverse is ________."

Ho familiarità con le funzioni prototype anche se non credo che sia la parola che sto cercando. Qualcuno può aiutarmi a riempire questi spazi vuoti?

    
posta Santi 08.03.2017 - 20:38
fonte

6 risposte

12

La coppia di concetti che stai cercando sono mutabili / immutabili parametri e in-place / return of results.

Nei tuoi esempi:

Devi impostare la stringa su "stringa dot replace", perché la funzione replace funziona su una stringa che, in python, è immutable in modo che la funzione di sostituzione restituisca una nuova stringa.

Per un programmatore C / C ++ questo è più familiare dei parametri "passati per valore", piuttosto che "passato per riferimento", che li rende immutabili e restituisce il risultato.

Non è necessario impostare un array uguale a "array dot reverse", perché reverse opera su un array, che è mutable , quindi è in grado di apportare modifiche sul posto prima di tornare.

In linguaggi come C / C ++ questo è noto come parametri "passati per riferimento", cioè passando l'indirizzo che, se non modificato da const , consente alla funzione di cambiare, mutare , il contenuto di tale indirizzo che modifica i risultati in-place prima di tornare.

Ovviamente non è raro avere una funzione che restituisca risultati da entrambi i meccanismi, ad es. int SomeFn(int p1, int p2, int *ErrCode) can, potenzialmente restituisce risultati sia nel valore restituito che modificando il contenuto di ErrCode .

Un terzo metodo

Per completezza un terzo meccanismo per la restituzione dei risultati è effetto collaterale o globale , ovvero modifica dell'ambito del file, del programma, dei valori condivisi o ambientali. Questo è generalmente considerato cattive notizie poiché, a meno che non sia ben documentato, puoi solo scoprire cosa viene modificato leggendo attentamente il codice. In linguaggi come C / C ++ questo è troppo facile da fare avendo una variabile di scope esterna con un nome dato, possibilmente anche in un altro modulo, e nessuna variabile di scope locale masking con lo stesso nome. In Python, mentre è possibile leggere i valori dei valori negli ambiti esterni, a meno che i valori dell'ambito esterno siano impostati esplicitamente come disponibili per essere modificati con la parola chiave global , il tentativo di modificare una variabile dell'ambito esterno crea automaticamente un locale con lo stesso nome.

    
risposta data 08.03.2017 - 20:50
fonte
4

Il mio modo preferito per esprimerlo è:

  • Il metodo Array reverse è mutante . È un mutator . Un caso speciale comune è un setter .

  • Il metodo String replace è non mutante . È non un mutatore . Se non modifica nulla , è privo di effetti collaterali . Un caso speciale comune è un getter .

  • Poiché le stringhe JavaScript sono immutable , i metodi String non possono essere modificati.

    "Hello World".replace("Hello", "Goodbye");

    dovrebbe metterti a disagio. Non modifica una stringa letterale. Scarta il risultato. Gli analizzatori di codici statici a volte possono rilevare tali errori.

  • Poiché gli array JavaScript sono mutabili , i metodi array possono essere mutati. JavaScript tende a utilizzare gli array come contenitori di archiviazione locali, facilmente modificati e copiati di rado.
risposta data 09.03.2017 - 07:45
fonte
2

A volte, quando usato nel contesto della pura programmazione funzionale, ho sentito funzioni che modificano il valore di input (e quindi non sono pure funzioni) chiamate distruttivo . Non sono sicuro se questo è il termine corretto, però.

Nel tuo caso, diresti:

You have to set the string to "string dot replace", because the replace function is not destructive.

You don't need to set an array equal to "array dot reverse", because reverse is destructive.

    
risposta data 09.03.2017 - 04:28
fonte
1

Forse puro è la parola che stai cercando?

replace() è (o sembra essere) puro perché non sembra che abbia effetti collaterali (cioè, modificando la stringa) mentre reverse() è impuro perché cambia lo stato dell'array.

    
risposta data 08.03.2017 - 22:23
fonte
1

Questi di solito sarebbero separati in funzioni e metodi (dove i metodi sono un sottoinsieme di funzioni). Una funzione è una sezione di codice che può essere chiamata in isolamento, mentre un metodo ha un concetto di "contesto" corrente su cui opera. L'azione di un metodo cambia lo stato del suo contesto.

Nella programmazione orientata agli oggetti, il contesto è l'istanza su cui sta operando la funzione.

    
risposta data 08.03.2017 - 21:13
fonte
0

Non so se esiste una risposta ufficiale, ma ecco due che potrebbero piacerti.

Procedura

Solo perché sembrava un buon answer a questo domanda , che assomiglia molto alla tua domanda BTW-- dovresti verificarlo.

Operazione unario sul posto

Verifica questa pagina: java.util.function . Fornisce una sorta di nome inventato per i delegati (firme di input / output) di vari prototipi, ad es. un delegato che accetta un argomento e restituisce nulla è chiamato consumer .

Ora, come studente astuto di OOP, dovresti sapere che un metodo è solo una funzione che accetta un parametro nascosto ( this ). Poiché viene fornito come riferimento, funge sia da parametro di input che di output.

Secondo questi ragazzi Java (e sembrano abbastanza intelligenti), un delegato che accetta un singolo input e restituisce un valore dello stesso tipo è chiamato un unario operatore .

Ora nel caso di array::Reverse() , un array non è immutabile e può potenzialmente occupare molto spazio, quindi è più efficiente e conveniente eseguire l'operazione sul posto. Pertanto Reverse() è un operatore unario sul posto .

Ma per me, un "operatore" è un simbolo speciale (come l'operatore di addizione, noto anche come + ) o una parola chiave matematica come mod . Pertanto preferisco chiamarlo operat ion , offrendo un'operazione sul posto unario .

    
risposta data 09.03.2017 - 03:55
fonte

Leggi altre domande sui tag