Qual é o termo usado para descrever uma função / método que modifica o objeto em que é chamado?


12

Desculpe pela pergunta genérica. Eu procurei por todo o lado e encontrei tantos tópicos semelhantes a este, mas nenhum que responda à minha pergunta específica - talvez porque o termo que estou procurando nem sequer exista.

Um amigo meu está aprendendo programação, especificamente JavaScript, e me perguntou por que isso não estava funcionando:

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

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

O motivo é replaceque não modifica a, pois as seqüências são imutáveis ​​no JavaSript. Como ele retorna uma string, você precisa fazer algo como ...

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

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

No entanto, a alternativa é uma função como a do JavaScript reverse(), pois modifica o que é chamado. Por exemplo:

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

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

Quando meu amigo me perguntou por que o dele replacenão estava funcionando, percebi que estava procurando uma palavra que não sabia (até onde sei) ...

"Você precisa definir a string como" string dot replace ", porque a função de substituição é ________."

Você não precisa definir uma matriz igual a "array dot reverse", porque reverse é ________. "

Estou familiarizado com as funções de protótipo , embora não acredite que essa seja a palavra que estou procurando. Alguém pode me ajudar a preencher esses espaços em branco?


6
Talvez a palavra seja "mutador"? como em: You don't need to set an array equal to "array dot reverse", because reverse is a mutator function. Eu acho que eu já ouvi essa terminologia para se referir a funções que "mutação" a instância que lhes chama. Mas você provavelmente deve verificar isso em outro lugar.
FrustratedWithFormsDesigner

Aprecie! Acabei de ler algumas sobre Mutator Methods e acho que definitivamente se encaixa nessa conversa muito bem. Certamente no reino do que estou procurando.
Santi

Estou confuso: no título, você perguntar sobre uma função que modifica o objeto que chamou, mas em seus exemplos, você mostra os métodos que modificam o objeto que eles são chamados em , ou seja, exatamente o oposto do título. Qual dos dois é esse?
Jörg W Mittag

Bem, certamente o explicado em 30 linhas de detalhes. Modificarei o título para ser preciso, obrigado pelo aviso!
Santi

Respostas:


12

O par de conceitos que você está procurando são parâmetros mutáveis ​​/ imutáveis e no local / retorno de resultados.

Nos seus exemplos:

Você precisa definir a string como "string dot replace", porque a função replace opera em uma string que, em python, é imutável, portanto a função replace retorna uma nova string.

Para um programador C / C ++, isso é mais familiar como parâmetros "passados ​​por valor", em vez de "passados ​​por referência", o que os torna imutáveis e retornam o resultado.

Você não precisa definir uma matriz igual a "array dot reverse", porque reverse opera em uma matriz que é mutável , portanto, é possível fazer alterações no local antes de retornar.

Em linguagens como C / C ++ isto é conhecido como parâmetros "passados por referência" ou seja, passando o endereço de que, se não modificado por const, permite que a função de mudança, mutação , o conteúdo do que endereço, que altera os resultados no local , antes de regressar.

Obviamente, não é incomum ter uma função que retorne resultados por ambos os mecanismos, por exemplo int SomeFn(int p1, int p2, int *ErrCode), pode, potencialmente , retornar resultados no valor de retorno e na modificação do conteúdo de ErrCode.

Um terceiro método

Para completar, um terceiro mecanismo para retornar resultados é por efeito colateral ou global , ou seja, modificar o escopo do arquivo, todo o programa, valores compartilhados ou ambientais. Isso geralmente é considerado uma má notícia , pois, a menos que esteja bem documentado, você pode descobrir o que está sendo alterado pela leitura cuidadosa do código. Em linguagens como C / C ++, isso é muito fácil de se ter uma variável de escopo externo com um determinado nome, possivelmente até em outro módulo, e nenhuma variável de escopo local de mascaramento com o mesmo nome. No Python, enquanto você pode ler os valores dos valores nos escopos externos, a menos que os valores do escopo externo sejam explicitamente definidos como disponíveis para serem modificados com oglobal palavra-chave, tentar modificar uma variável de escopo externo cria automaticamente um local com o mesmo nome.


Ah, eu estou familiarizado com esses termos, embora não tenha certeza se havia uma palavra real que descreva a função em si . Como (The reverse function is a _______ function.dito , ) Dito isto, é quase uma resposta idêntica à que acabei dando ao meu amigo, por isso agradeço sua confirmação - embora ainda esteja pensando se há termos específicos. Deixarei a pergunta em aberto por um tempo, mas certamente aceitarei isso como a resposta no caso de essas palavras simplesmente não existirem.
Santi

2
Em algumas linguagens, como python, você também pode ter classes que se modificam - enquanto em alguns contextos esse "patch de macaco" é considerado uma coisa boa em muitos, é considerado "código de auto-modificação" e é proibido. Você também pode ter "código evolutivo", em que fragmentos de código são "mutados" aleatoriamente e / ou combinados; então, são testados e selecionados para o "melhor" desempenho de alguma maneira.
9788 Steve Barnes

-1. Se as strings são mutáveis ​​ou imutáveis, nada tem a ver com a função que está operando nela. A função não é mutável ou imutável e não está "retornando ou no local". Funções podem modificar seus argumentos e ainda retornar.
Route de milhas

O @MilesRout acrescentou que as funções que são modificadas no local ainda retornam e alguns exemplos de C / C ++ para maior clareza, além de resultados por efeitos colaterais, para completude.
Steve Barnes

4

Minha maneira preferida de expressar isso é:

  • O reversemétodo Array está em mutação . É um mutador . Um caso especial comum é um levantador .

  • O replacemétodo String não é mutante . Não é um mutador . Se não modificar nada , é livre de efeitos colaterais . Um caso especial comum é um getter .

  • Como as strings JavaScript são imutáveis , os métodos String não podem sofrer mutações.

    "Olá Mundo". Substitua ("Olá", "Adeus");

    deve deixá-lo desconfortável. Não modifica uma string literal. Ele descarta o resultado. Analisadores de código estático às vezes podem detectar esses erros.

  • Como as matrizes JavaScript são mutáveis , os métodos de matriz podem ser mutantes. O JavaScript tende a usar Arrays como compartimentos de armazenamento local, facilmente modificados e copiados com pouca frequência.

2

Às vezes, quando usado no contexto de programação funcional pura, ouvi funções que modificam o valor de entrada (e, portanto, não são funções puras) chamadas destrutivas . Não tenho certeza se este é o termo correto.

No seu caso, você diria:

Você precisa definir a string como "string dot replace", porque a função de substituição não é destrutiva .

Você não precisa definir um array igual a "array dot reverse", porque o reverso é destrutivo .


1

Talvez pura seja a palavra que você está procurando?

replace()é (ou parece ser) puro porque não parece ter efeitos colaterais (isto é, modificar a string) enquanto reverse()é impuro porque altera o estado da matriz.


É um conceito relacionado, mas também implica outras propriedades (por exemplo, não acessar o estado global e sempre produzir a mesma saída para a mesma entrada).
Jacob Raihle

1

Estes normalmente seriam separados em funções e métodos (onde métodos são um subconjunto de funções). Uma função é uma seção de código que pode ser chamada isoladamente, enquanto um método tem um conceito de 'contexto' atual no qual opera. A ação de um método altera o estado do seu contexto.

Na programação orientada a objetos, o contexto é a instância em que a função está operando.


0

Não sei se há uma resposta oficial, mas aqui estão duas que você pode gostar.

Procedimento

Só porque pareceu uma boa resposta para esta pergunta , que se parece muito com a sua pergunta, aliás - você deve dar uma olhada.

Operação unária no local

Revise esta página: java.util.function . Ele fornece uma espécie de nome inventado para delegados (assinaturas de entrada / saída) de vários protótipos, por exemplo, um delegado que aceita um argumento e retorna que nada é chamado consumidor .

Agora, como um estudante astuto de OOP, você deve estar ciente de que um método a é apenas uma função que aceita um parâmetro oculto ( this). Como é fornecido como referência, serve como parâmetro de entrada e de saída.

De acordo com esses caras do Java (e eles parecem bastante inteligentes), um delegado que aceita uma única entrada e retorna um valor do mesmo tipo é chamado de operador unário .

Agora, no caso de array::Reverse(), uma matriz não é imutável e pode potencialmente ocupar muito espaço; portanto, é mais eficiente e conveniente executar a operação no local. Portanto, Reverse()é um operador unário no local .

Mas para mim, um "operador" é um símbolo especial (como o operador de adição, também conhecido como +) ou uma palavra-chave matemática como mod. Portanto, eu prefiro chamá-lo um operat ion , produzindo no local operação unária .


Você está misturando conceitos. Reverse()não é um operador, um operador não precisa unária devolver um valor do mesmo tipo (por exemplo !, delete, typeof), e os operadores não são pessoas. Mas "no local" é um bom termo para um método que modifica sua instância. [. Eu não fiz down-voto, mas parece que alguém para baixo votado todas as respostas, mesmo que todos eles são úteis]
Jerry101

Não tenho certeza se você está seguindo. Qualquer protótipo pode ser representado por um delegado. "Operador" não funciona para mim (como afirmei), por isso digo "Operação" e, de fato, Reverse()é uma operação unária. Mas, no geral, concordo que tudo isso é um pouco estranho, mas estou usando literalmente a terminologia do documento vinculado , que parece ter sido de autoria de algumas pessoas bastante inteligentes. Pelo menos é melhor que nada.
John Wu

Ah eu vejo! Observe que, para modernizar lambdas em Java, eles se basearam na idéia de uma interface funcional (uma interface Java com apenas 1 método), para que possamos passar objetos Java comuns para aplicar como "funções". (Brian Goetz tem uma palestra técnica sobre a adição de lambdas. Várias vezes ele diz que "a abordagem óbvia seria péssima".) Ao criar interfaces funcionais para objetos de processamento de fluxo, eles meio que abusaram de termos como "operador". Isso é confuso! Eles devem ter ficado sem bons nomes. Eu não acho que seja uma boa fonte de termos para métodos OOP que modificam / não modificam o objeto receptor.
Jerry101
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.