Vindo de um background em Python, onde sempre existe uma "maneira certa de fazer" (uma maneira "Pythonic") quando se trata de estilo, estou me perguntando se o mesmo existe para Ruby. Eu tenho usado minhas próprias diretrizes de estilo, mas estou pensando em liberar meu código-fonte e gostaria que ele seguisse as regras não escritas que possam existir.
É "The Ruby Way" digitar explicitamente return
métodos? Eu já vi isso com e sem, mas existe uma maneira certa de fazê-lo? Existe talvez um momento certo para fazê-lo? Por exemplo:
def some_func(arg1, arg2, etc)
# Do some stuff...
return value # <-- Is the 'return' needed here?
end
ruby
coding-style
return-value
Sasha Chedygov
fonte
fonte
Respostas:
Pergunta antiga (e "respondida"), mas colocarei meus dois centavos como resposta.
TL; DR - Você não precisa, mas pode tornar seu código muito mais claro em alguns casos.
Embora não usar um retorno explícito possa ser "o caminho do Ruby", é confuso para programadores que trabalham com código desconhecido ou não familiarizado com esse recurso do Ruby.
É um exemplo um tanto artificial, mas imagine ter uma pequena função como essa, que adiciona uma ao número passado e a atribui a uma variável de instância.
Isso deveria ser uma função que retornou um valor ou não? É realmente difícil dizer o que o desenvolvedor quis dizer, pois atribui a variável de instância E retorna o valor atribuído também.
Suponha que, muito mais tarde, outro programador (talvez não familiarizado com o modo como o Ruby retorna com base na última linha de código executada) apareça e deseje colocar algumas instruções de impressão para registro, e a função se torne essa ...
Agora a função está quebrada se algo espera um valor retornado . Se nada espera um valor retornado, tudo bem. Claramente, se em algum lugar mais abaixo da cadeia de código, algo chamando isso de espera de um valor retornado, ele falhará, pois não receberá de volta o que espera.
A verdadeira questão agora é esta: algo realmente esperava um valor retornado? Isso quebrou alguma coisa ou não? Será que vai quebrar algo no futuro? Quem sabe! Somente uma revisão completa do código de todas as chamadas informará você.
Portanto, para mim, pelo menos, a abordagem da melhor prática é ser muito explícito que você está retornando algo, se for o caso, ou não devolve nada quando isso não acontece.
Portanto, no caso de nossa pequena função de demonstração, supondo que desejássemos retornar um valor, seria escrito assim ...
E seria muito claro para qualquer programador que ele retornasse um valor, e muito mais difícil para eles quebrá-lo sem perceber.
Como alternativa, pode-se escrever assim e deixar de fora a declaração de retorno ...
Mas por que se preocupar em deixar de fora a palavra retorno? Por que não colocá-lo lá e deixar 100% claro o que está acontecendo? Literalmente, não terá impacto na capacidade de execução do seu código.
fonte
return
adiciona significado semântico ao código, por que não? Dificilmente é muito detalhado - não estamos falando de 5 linhas x 3, apenas mais uma palavra. Eu preferiria verreturn
pelo menos em funções (talvez não em blocos) para expressar o que o código realmente faz. Às vezes, você precisa retornar a função intermediária - não deixe de fora a últimareturn
palavra-chave na última linha apenas porque pode. Não sou a favor da verbosidade, mas sou a favor da consistência.side_effect()
e outro desenvolvedor decidir (ab) usar o valor implícito de retorno do seu procedimento. Para corrigir isso, você pode fazer seus procedimentos explicitamentereturn nil
.Não. O bom estilo Ruby geralmente usaria apenas retornos explícitos para um retorno antecipado . Ruby é especialista em minimalismo de código / magia implícita.
Dito isto, se um retorno explícito tornar as coisas mais claras ou mais fáceis de ler, não prejudicará nada.
fonte
return
já tem um significado semântico significativo como uma SAÍDA ANTECIPADA da função.return
na última linha como uma saída precoce de qualquer maneira?Pessoalmente, uso a
return
palavra-chave para distinguir entre o que chamo de métodos funcionais , ou seja, métodos executados principalmente por seu valor de retorno e métodos processuais executados principalmente por seus efeitos colaterais. Portanto, métodos nos quais o valor de retorno é importante, obtenha umareturn
palavra-chave extra para chamar a atenção para o valor de retorno.Uso a mesma distinção ao chamar métodos: métodos funcionais obtêm parênteses, métodos processuais não.
E por último, mas não menos importante, também uso essa distinção com blocos: blocos funcionais recebem chaves, blocos de procedimentos (ou seja, blocos que "fazem" alguma coisa) recebem
do
/end
.No entanto, tento não ser religioso: com blocos, chaves e
do
/ /end
tem precedência diferente e, em vez de adicionar parênteses explícitos para desambiguar uma expressão, apenas mudo para o outro estilo. O mesmo vale para a chamada de método: se adicionar parênteses em torno da lista de parâmetros torna o código mais legível, eu o faço, mesmo que o método em questão seja de natureza processual.fonte
Na verdade, o importante é distinguir entre:
O Ruby não tem uma maneira nativa de diferenciá-los - o que o deixa vulnerável a escrever um procedimento
side_effect()
e outro desenvolvedor que decide abusar do valor implícito de retorno do seu procedimento (basicamente tratando-o como uma função impura).Para resolver isso, retire uma folha do livro de Scala e Haskell e faça com que seus procedimentos retornem explicitamente
nil
(akaUnit
ou()
em outros idiomas).Se você seguir isso, o uso de
return
sintaxe explícita ou não se tornará apenas uma questão de estilo pessoal.Para distinguir ainda mais entre funções e procedimentos:
do/end
()
, enquanto que ao invocar funções, nãoObserve que Jörg W Mittag realmente defendeu o contrário - evitando
()
s para procedimentos -, mas isso não é aconselhável, porque você deseja que as invocações de métodos com efeito colateral sejam claramente distinguíveis das variáveis, principalmente quando a aridade é 0. Consulte o guia de estilo Scala sobre invocação de métodos para detalhes.fonte
function_a
efunction_a
foi gravado para chamar (e só pode operar chamando)procedure_b
, então éfunction_a
realmente uma função? Ele retorna um valor, cumprindo seus requisitos de funções, mas tem um efeito colateral, cumprindo os requisitos de procedimentos.function_a
poderia conter uma árvore deprocedure_...
chamadas, como de fatoprocedure_a
poderia conter uma árvore defunction_...
chamadas. Como Scala, mas diferentemente de Haskell, não há garantia no Ruby de que uma função não tenha efeito colateral.O guia de estilo declara que você não deve usar
return
sua última declaração. Você ainda pode usá-lo se não for o último . Essa é uma das convenções que a comunidade segue estritamente, e você também deve fazer isso se planejar colaborar com alguém que usa Ruby.Dito isto, o principal argumento para o uso de
return
s explícito é que é confuso para pessoas vindas de outras línguas.Uma heurística comum para o comprimento do método (excluindo getters / setters) em java é uma tela . Nesse caso, você pode não estar vendo a definição do método e / ou já se esqueceu de onde estava retornando.
Por outro lado, no Ruby é melhor seguir métodos com menos de 10 linhas . Dado isso, alguém poderia se perguntar por que ele tem que escrever ~ 10% mais declarações, quando elas estão claramente implícitas.
Como Ruby não possui métodos nulos e tudo é muito mais conciso, você estará adicionando sobrecarga para nenhum dos benefícios se usar
return
s explícitos .fonte
Eu concordo com Ben Hughes e discordo de Tim Holt, porque a pergunta menciona a maneira definitiva como o Python faz e pergunta se Ruby tem um padrão semelhante.
Faz.
Esse é um recurso tão conhecido da linguagem que qualquer pessoa que depure um problema no ruby deve razoavelmente saber disso.
fonte
return
palavra - chave quando desnecessária.É uma questão de qual estilo você prefere na maior parte. Você precisa usar a palavra-chave return se desejar retornar de algum lugar no meio de um método.
fonte
Como Ben disse. O fato de 'o valor de retorno de um método ruby ser o valor de retorno da última instrução no corpo da função' faz com que a palavra-chave return raramente seja usada na maioria dos métodos ruby.
fonte
if failed_check then nil else @list end
? Isso é realmente funcional .