Eu tenho um colega de trabalho que está ativamente tentando me convencer de que não devo usar do..end e, em vez disso, use chaves para definir blocos de múltiplas linhas no Ruby.
Estou firmemente acostumado a usar apenas chaves para uma linha curta e fazer ... terminar para todo o resto. Mas pensei em alcançar a comunidade maior para obter alguma resolução.
Então, qual é e por quê? (Exemplo de algum código deveria)
context do
setup { do_some_setup() }
should "do somthing" do
# some more code...
end
end
ou
context {
setup { do_some_setup() }
should("do somthing") {
# some more code...
}
}
Pessoalmente, basta olhar para as respostas acima para mim, mas eu queria abrir isso para uma comunidade maior.
ruby-on-rails
ruby
ruby-on-rails-3
coding-style
Blake Taylor
fonte
fonte
Respostas:
A convenção geral é usar do..end para blocos de várias linhas e chaves para blocos de linha única, mas também há uma diferença entre as duas que podem ser ilustradas com este exemplo:
Isso significa que {} tem uma precedência mais alta do que o final .., lembre-se disso ao decidir o que você deseja usar.
PS: Mais um exemplo a ter em mente enquanto você desenvolve suas preferências.
O código a seguir:
realmente significa:
E este código:
realmente significa:
Portanto, para obter a definição real desejada, com chaves, você deve:
Talvez o uso de chaves para parâmetros seja algo que você queira fazer de qualquer maneira, mas se não o fizer, provavelmente é melhor usar do..enviar nesses casos para evitar essa confusão.
fonte
puts [1,2,3].map do |k| k+1; end
apenas imprime o enumerador, ou seja, uma coisa. Não se coloca dois argumentos aqui, a saber,[1,2,3].map
edo |k| k+1; end
?De programação Ruby :
Então o código
Vincula o bloco à
param
variável enquanto o códigoVincula o bloco à função
f
.No entanto, isso não é problema se você colocar argumentos de função entre parênteses.
fonte
Existem alguns pontos de vista sobre isso, é realmente uma questão de preferência pessoal. Muitos rubiistas adotam a abordagem que você faz. No entanto, dois outros estilos comuns são sempre usar um ou outro, ou
{}
para blocos que retornam valores edo ... end
para blocos executados para efeitos colaterais.fonte
Há um grande benefício em chaves - muitos editores têm muito mais facilidade de combiná-las, facilitando muito certos tipos de depuração. Enquanto isso, a palavra-chave "do ... end" é um pouco mais difícil de corresponder, especialmente porque "end" s também corresponde a "if" s.
fonte
do ... end
palavras-chave por defeitodo ... end
é um caso especial que requer lógica específica de idioma.A regra mais comum que eu vi (mais recentemente no Eloquent Ruby ) é:
fonte
Estou votando para fazer / terminar
A convenção é
do .. end
para multilinhas e{ ... }
one-liners.Mas eu gosto
do .. end
mais, então, quando tenho um liner, uso dedo .. end
qualquer maneira, mas formato-o normalmente para fazer / terminar em três linhas. Isso deixa todo mundo feliz.Um problema
{ }
é que ele é hostil ao modo de poesia (porque eles se ligam firmemente ao último parâmetro e não à chamada de método inteira, portanto você deve incluir parênteses de método) e eles, na minha opinião, não parecem tão agradáveis. Eles não são grupos de instruções e se chocam com constantes de hash para facilitar a leitura.Além disso, já vi o suficiente
{ }
em programas em C. O jeito de Ruby, como sempre, é melhor. Existe exatamente um tipo deif
bloco e você nunca precisa voltar e converter uma instrução em uma instrução composta.fonte
do_stuff if x==1
), que é meio irritante de se converter na sintaxe regular. Mas isso é outra discussão.if
, postfixif
, postfixunless
(também um tipo deif
, se não) e uma linhaif
comthen
. A maneira Ruby é ter várias maneiras de expressar de fato algo que é sempre a mesma coisa, muito pior do que o que C oferece, que segue regras muito simples e estritas.Alguns rubiistas influentes sugerem usar chaves quando você usa o valor de retorno e terminar / terminar quando não usa.
http://talklikeaduck.denhaven2.com/2007/10/02/ruby-blocks-do-or-brace (em archive.org)
http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc (em archive.org)
Parece uma boa prática em geral.
Eu modificaria um pouco esse princípio para dizer que você deve evitar o uso de do / end em uma única linha, porque é mais difícil de ler.
Você precisa ter mais cuidado ao usar chaves, porque ele se vincula ao parâmetro final de um método, em vez de à chamada de método inteira. Basta adicionar parênteses para evitar isso.
fonte
Na verdade, é uma preferência pessoal, mas tendo dito isso, nos últimos 3 anos das minhas experiências com ruby, o que aprendi é que o ruby tem seu estilo.
Um exemplo seria, se você está vindo de um plano de fundo JAVA, para um método booleano, você pode usar
observe o caso camel e, na maioria das vezes, o prefixo 'is' para identificá-lo como um método booleano.
Mas no mundo do rubi, o mesmo método seria
então, pessoalmente, acho que é melhor seguir o 'caminho do rubi' (mas sei que leva algum tempo para que alguém entenda (demorei cerca de 1 ano: D)).
Finalmente, eu iria com
blocos.
fonte
Coloquei outra resposta, embora a grande diferença já tenha sido apontada (precedência / encadernação), e isso possa causar problemas difíceis de encontrar (o Homem de Lata e outros apontaram isso). Acho que meu exemplo mostra o problema com um trecho de código não tão comum, mesmo programadores experientes não lêem como os domingos:
Então eu fiz algum código embelezando ...
se você alterar
{}
aqui parado/end
obter o erro, esse métodotranslate
não existe ...Por que isso acontece é apontado aqui mais de uma precedência. Mas onde colocar aparelho aqui? (@ the Tin Man: eu sempre uso aparelho, como você, mas aqui ... supervisionado)
então cada resposta como
está errado se usado sem o "MAS fique de olho nos aparelhos / precedência!"
novamente:
e
(o que quer que o resultado da extensão faça com o bloco ...)
Portanto, se você quiser usar o / end use:
fonte
No que diz respeito ao viés pessoal, prefiro chaves em vez de um bloco do / end, pois é mais compreensível para um número maior de desenvolvedores, porque a maioria das linguagens de segundo plano os usa durante a convenção do / end. Com isso dito, a chave real é chegar a um acordo dentro de sua loja, se do / end for usado por 6/10 desenvolvedores, que TODOS deveriam usá-los, se 6/10 usar chaves, então atenha-se a esse paradigma.
Trata-se de criar um padrão para que a equipe como um todo possa identificar as estruturas de código mais rapidamente.
fonte
Há uma diferença sutil entre eles, mas {} se liga mais estreitamente que do / final.
fonte
Meu estilo pessoal é enfatizar a legibilidade sobre regras rígidas de
{
...}
vsdo
...end
escolha, quando essa escolha é possível. Minha idéia de legibilidade é a seguinte:Em sintaxe mais complexa, como blocos aninhados com várias linhas, tento intercalar
{
...}
edo
...end
delimitadores para obter o resultado mais natural, por exemplo.Embora a falta de regras rígidas possa produzir escolhas ligeiramente diferentes para programadores diferentes, acredito que a otimização caso a caso para legibilidade, embora subjetiva, seja um ganho líquido sobre a aderência a regras rígidas.
fonte
Ruby
era a melhor linguagem pragmática do mercado. Devo dizer linguagem de script. Hoje, acho que você estaria igualmente bem aprendendoBrainfuck
.Tomei um exemplo da resposta mais votada aqui. Dizer,
Se você verificar qual implementação interna no array.rb, o cabeçalho do método map diz :
Invokes the given block once for each element of self.
isto é, aceita um bloco de código - o que estiver entre do e end é executado como rendimento. Em seguida, o resultado será coletado como matriz novamente, retornando um objeto completamente novo.
fonte
Existe uma terceira opção: escreva um pré-processador para inferir "end" em sua própria linha, a partir do recuo. Os pensadores profundos que preferem código conciso estão certos.
Melhor ainda, corte o ruby para que esta seja uma bandeira.
Obviamente, a solução mais simples de "escolher suas lutas" é adotar a convenção de estilo de que uma sequência de fins aparece na mesma linha e ensinar sua cor de sintaxe a silenciá-los. Para facilitar a edição, pode-se usar scripts de editor para expandir / recolher essas seqüências.
20% a 25% das minhas linhas de código ruby são "fim" em sua própria linha, todas trivialmente inferidas por minhas convenções de indentação. Ruby é a linguagem do tipo lisp que alcançou o maior sucesso. Quando as pessoas contestam isso, perguntando onde estão todos os horríveis parênteses, mostro a eles uma função rubi que termina em sete linhas de "fim" supérfluo.
Eu codifiquei por anos usando um pré-processador lisp para inferir a maioria dos parênteses: Uma barra '|' abriu um grupo que foi fechado automaticamente no final da linha, e um cifrão '$' serviu como um espaço reservado vazio, onde de outra forma não haveria símbolos para ajudar a inferir os agrupamentos. É claro que este é um território de guerra religiosa. Lisp / esquema sem parênteses é o mais poético de todos os idiomas. Ainda assim, é mais fácil simplesmente acalmar os parênteses usando cores de sintaxe.
Eu ainda codigo com um pré-processador para Haskell, para adicionar heredocs e usar como padrão todas as linhas de descarga como comentários, tudo recuado como código. Não gosto de comentar os caracteres, seja qual for o idioma.
fonte