Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore Rails-Style-Guide-PT-BR

Rails-Style-Guide-PT-BR

Published by mjaojr, 2016-07-17 21:04:50

Description: Rails-Style-Guide-PT-BR

Search

Read the Text Version

Prelúdio Modelos são importantes. --Oficial Alex Murphy de J. / RoboCopUma coisa que sempre me incomodou como um desenvolvedor Ruby - desenvolvedores Pythontem uma ótima referência de estilo de programação ([PEP-8](http://www.python.org/dev/peps/pep-0008/)) e nós nunca tivemos um guia oficial, documentandoum estilo de codificação em Ruby e as melhores práticas. E eu acredito que o estilo importe. Eutambém acredito que uma grande comunidade hacker, tal como Ruby tem, deve ser capaz deproduzir este documento tão cobiçado.Este guia começou sua vida com as diretrizes internas de codificação em Ruby (escrito por mimmesmo). Em um dado momento eu decidi que o trabalho que estava fazendo poderia serinteressante para os membros da comunidade Ruby em geral e que o mundo não tinhanecessidade para outra diretriz interna de uma empresa. Mas o mundo certamente poderia sebeneficiar de um conjunto de práticas, expressões idiomáticas e prescrições de estilo deprogramação Ruby orientado e sancionado pela Comunidade.Desde a criação do guia, eu recebi um monte de feedback de membros da excepcionalcomunidade Ruby mundo a fora. Obrigado por todas as sugestões e o apoio! Juntos podemos fazerum recurso benéfico para cada desenvolvedor Ruby lá fora.A propósito, se você está no Rails você pode querer verificar o complementar Ruby on Rails 3 & 4Style Guide.O Guia de Estilo RubyEste guia de estilo Ruby recomenda as melhores práticas para que programadores reais de Rubypossam escrever códigos que possam ser mantidos por outros programadores reais de Ruby. Umguia de estilo que reflete o uso que o mundo real está acostumado e um guia de estilo que seprende a um ideal que foi rejeitado pelo povo supõe-se que o melhor é não usá-lo para nada – nãoimporta o quão bom seja.O guia é separado em várias seções de regras relacionadas. Tentei adicionar a lógica por trás dasregras (se estiver omitido, eu assumi que é bastante óbvio).Eu não vim com todas as regras do nada - são na maioria com base na minha extensa carreiracomo profissional de engenharia de software, comentários e sugestões dos membros dacomunidade Ruby e vários recursos de programação Ruby altamente recomendados, tais como\"Programming Ruby 1.9\" e \"The Ruby Programming Language\".Há algumas áreas em que não há nenhum consenso na Comunidade Ruby em relação um

determinado estilo (como estilo de declaração de cadeia de caracteres literais, espaçamento dentrode hashes literais, posição do ponto no método de encadeamento multi-linha, etc.). Em taissituações, todos os estilos populares são reconhecidos e cabe a você escolher um e aplicá-lo deforma consistente.O guia ainda é um trabalho em andamento - algumas regras possuem exemplos escassos, algumasregras não tem exemplos que as ilustrem claramente. No devido tempo, estas questões serãoabordadas - apenas mantenha-los em mente por while.Você pode gerar um PDF ou uma cópia HTML deste guia usando Transmuter.RuboCop é um analisador de código, baseado neste guia de estilo.Traduções do guia estão disponíveis nos seguintes idiomas:q Chinês simplificadoq Chinês tradicionalq Francêsq Japonêsq Espanholq VietnamitaTabela de conteúdosq Layout do código fonteq Sintaxeq Nomenclaturaq Comentários r Anotações em Comentárioq Classesq Exceçõesq Coleçõesq Stringsq Expressões Regularesq Literais Percentuaisq Meta-programaçãoq Miscelâneaq FerramentasLayout do código fonte Quase todo mundo está convencido que todos os estilos, exceto os seus são > feios e ilegíveis. Deixe de lado o \"exceto seus próprios\" e eles estarão provavelmente certo... -- Jerry Coffin (sobre recuo)

q Use UTF-8 como a codificação do arquivo de fonte.q Use dois espaços por nível de recuo (conhecido como soft tabs). Nada de hard tabs.# ruim - quatro espaços def algum_metodo fazer_algo end # bom def algum_metodo fazer_algo endq Use os finais de linha no estilo Unix. (* Usuários BSD/Solaris/Linux/OS X estão cobertos por padrão, usuários do Windows precisam ter cuidado extra).q Se você estiver usando o Git, você pode querer adicionar a seguinte definição de configuração para proteger o seu projeto do aterrorizante end de linha do Windows: $ git config --global core.autorcrlf trueq Não use ';' para separar as declarações e expressões. Como um corolário - use uma expressão por linha. # ruim puts 'foobar'; # ponto e vírgula supérfluo puts 'foo'; puts 'bar' # duas expressões na mesma linha # bom puts 'foobar' puts 'foo' puts 'bar' puts 'foo', 'bar' # isto aplica-se ao puts em particularq Prefira um formato de linha único para as definições de classe sem corpo. # ruim class FooError < StandardError end # ok class FooError < StandardError; end # bom FooError = Class.new(StandardError)

Evite os métodos de linha única. Embora sejam um tanto populares no mundo selvagem, existemalgumas peculiaridades sobre a sintaxe de definição que torna seu uso indesejável. De qualquerforma - não deveria haver mais do que uma expressão em um método de linha única. # ruim def muito; alguma_coisa; alguma_outra_coisa; end # ok - Observe que o primeiro ; é necessário def metodo_sem_parenteses; corpo end # ok - Observe que o segundo ; é opcional def metodo_sem_parenteses; corpo; end # okish - sintaxe válida, mas sem o ; é difícil de ler def metodo() corpo end # bom def algum_metodo corpo endUma exceção à regra são os métodos de corpo vazio. # bom def no_op; endq Use espaços em torno de operadores, após vírgulas, dois-pontos e ponto e vírgula, em volta do { e antes do }. Espaço em branco pode ser (na maioria dos casos) irrelevante para o intérprete de Ruby, mas sua utilização correcta é a chave para escrever um código facilmente legível. soma = 1 + 2 a, b = 1, 2 1 > 2 ? true : false; puts 'Olá' [1, 2, 3].each { |e| puts e }A única exceção, sobre os operadores, é o operador de expoente: # ruim e=M*c**2 # bom e = M * c**2{ e } merecem um pouco de esclarecimento, pois eles são usados para blocos e hashes literais,bem como expressões incorporadas em seqüências de caracteres. Para hash, dois estilos literaissão considerados aceitáveis.

# bom - espaço após { e antes } { um: 1, dois: 2 } # bom - sem espaço após { e antes } {um: 1, dois: 2}A primeira variante é ligeiramente mais legível (e sem dúvida mais popular na comunidade Rubyem geral). A segunda variante tem a vantagem de adicionar a diferença visual entre o bloco e hashliterais. Qualquer um que você escolher - aplique-o de forma consistente.Com as expressões incorporadas, há também duas opções aceitáveis: # bom - sem espaços \"string #{expr}\" # ok - indiscutivelmente mais legível \"string #{ expr }\"O primeiro estilo é extremamente mais popular e é geralmente aconselhado a ficar com ele. Osegundo, por outro lado, é (sem dúvidas) um pouco mais legível. Como com hashes - escolha umestilo e aplique-o de forma consistente.q Sem espaços após (, [ ou antes ], ). some(arg).other [1, 2, 3].sizeq Sem espaço após !. # ruim ! algo # bom !algoq Idente when no nível do case. Eu sei que muitos discordariam com isso, mas é o estilo estabelecido em ambos \"The Ruby Programming Language\" e \"Programming Ruby\". # ruim case when musica.nome == 'Misty' puts 'Não!' when musica.duracao > 120 puts 'Muito tempo'! when Time.now.hour > 21 puts \"É tarde demais\" else musica.Play

end # bom case when musica.nome == 'Misty' puts 'Não!' when musica.duracao > 120 puts 'Muito tempo'! when Time.now.hour > 21 puts \"É tarde demais\" else musica.play endq Quando você atribuir o resultado de uma expressão condicional a uma variável, preservar o alinhamento normal dos seus ramos. # ruim - muito complicado tipo = case ano when 1850..1889 then 'Blues' when 1890..1909 then 'Ragtime' when 1910..1929 then 'New Orleans Jazz' when 1930..1939 then 'Swing' when 1940..1950 then 'Bebop' else 'Jazz' end resultado = if condicao calc_algo else calc_outro_algo end # bom - é evidente o que está acontecendo tipo = case ano when 1850..1889 then 'Blues' when 1890..1909 then 'Ragtime' when 1910..1929 then 'New Orleans Jazz' when 1930..1939 then 'Swing' when 1940..1950 then 'Bebop' else 'Jazz' end resultado = if condicao calc_algo else calc_outro_algo end # bom (e um pouco mais largamente eficiente) tipo = case ano when 1850..1889 then 'Blues' when 1890..1909 then 'Ragtime' when 1910..1929 then 'New Orleans Jazz'

when 1930..1939 then 'Swing' when 1940..1950 then 'Bebop' else 'Jazz' end resultado = if condicao calc_algo else calc_outro_algo endq Usar linhas vazias entre as definições de método e também para quebrar um método em parágrafos de lógica internas. def algum_metodo data = initialize(options) data.manipulate! data.result end def algum_metodo result endq Evitar a vírgula após o último parâmetro em uma chamada de método, especialmente quando os parâmetros não são em linhas separadas. # ruim - mais fácil de mover ou adicionar/remover parâmetros, mas ainda não preferível algum_metodo ( tamanho, contagem, cor, ) # ruim algum_metodo (tamanho, contagem, cor, ) # bom algum_metodo (tamanho, contagem, cor)q Use espaços em torno do operador = quando para atribuição de valores padrão para os parâmetros do método: # ruim def algum_metodo (arg1=:default, arg2=nil, arg3=[]) # fazer alguma coisa... end # bom

def algum_metodo (arg1 =: default, arg2 = nil, arg3 = []) # fazer alguma coisa... endEnquanto diversos livros de Ruby sugerem o primeiro estilo, o segundo é muito mais proeminentena prática (e, possivelmente, um pouco mais legível).Evitar a continuação da linha \ onde não é necessário. Na prática, evitar o uso de continuação dalinha para nada além de concatenação de seqüência de caracteres. # ruim resultado = 1 - \ 2 # bom (mas ainda feio como o inferno) resultado = 1 \ -2 long_string = 'Primeira parte da longa cadeia de caracteres' \ 'e a segunda parte da seqüência de caracteres longa'q Adote um método consistente de estilo de encadeamento multi-linha. Existem dois estilos populares na comunidade Ruby, ambos dos quais são considerados bom - iniciando . (Opção A) e finalizando de . (Opção B).q (Opção A) Quando continuando uma invocação de método encadeada em outra linha, mantenha o . na segunda linha. # ruim - precisa consultar a primeira linha para entender a segunda linha um.dois.tres. quatro # bom - é imediatamente evidente o que está acontecendo a segunda linha um.dois.tres .quatroq (Opção B) quando continuando uma invocação de método encadeada na outra linha, incluir o . na primeira linha para indicar que a expressão continua. # ruim - precisa ler em frente para a segunda linha de saber que a corrente continua um.dois.tres .quatro # bom - é imediatamente evidente que a expressão continua além da primeira linha um.dois.tres. quatroUma discussão sobre os méritos de ambos os estilos alternativos pode ser encontrada aqui.

q Alinhar os parâmetros de um método chamado se eles se espalham por mais de um linha. Quando alinhar parâmetros não é apropriado devido à restrições de comprimento da linha, identação única para as linhas após a primeira é também aceitável. # ponto de início (a linha é muito longa) def enviar_email(source) Mailer.deliver(to: '[email protected],' from: '[email protected]', subject: 'Mensagem importante', body: source.text) end # ruim (dupla identação) def send_mail(source) Mailer.deliver( to: '[email protected]', from: '[email protected]', subject: 'Mensagem importante', body: source.text) end # bom def send_mail(source) Mailer.deliver(to: '[email protected]', from: '[email protected]', subject: 'Mensagem importante', body: source.text) end # bom (identação única) def send_mail(source) Mailer.deliver( to: '[email protected]', from: '[email protected]', subject: 'Mensagem importante', body: source.text ) endq Alinhe os elementos do array de literais, abrangendo várias linhas. # ruim - identação única menu_item = ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Feijão', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam'] # bom menu_item = [ 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Feijão', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam' ] # bom menu_item = ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Feijão', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']

q Adicione sublinhados para literais numéricos grandes para melhorar a sua legibilidade. # ruim - quantos 0s existem? num = 1000000 # bom - muito mais fácil de analisar para o cérebro humano num = 1_000_000q Use RDoc e suas convenções para a documentação da API. Não coloque uma linha vazia entre o bloco de comentários e o def.q Limitar as linhas à 80 caracteres.q Evite o espaço em branco à direita.q Termine cada arquivo com uma nova linha.q Não use comentários em bloco. Eles não podem ser precedidos por um espaço em branco e não são tão fácil de identificar como os comentários regulares. # mau =begin linha de comentário outra linha de comentário =end # bom # linha de comentário # outra linha de comentárioSintaxeq Use :: apenas para referências constantes (isso inclui as classes e módulos) e construtores (como Array() ou Nokogiri::HTML()). Nunca use :: para invocação de método regular. # mau AlgumaCasse::algum_metodo algum_objeto::algum_metodo # bom AlgumaClasse.algum_metodo algum_objeto.algum_metodo AlgumModulo::AlgumaClasse::SOME_CONST AlgumModulo::AlgumaClasse()q Use def com parênteses, quando há argumentos. Omita os parênteses quando o método não aceita quaisquer argumentos. # mau def algum_metodo() # corpo omitido end

# bom def algum_metodo # corpo omitido end # mau def algum_metodo_com_argumentos arg1, arg2 # corpo omitido end # bom def algum_metodo_com_argumentos(arg1, arg2) #corpo omitido endq Nunca use for, à menos que você saiba exatamente o porquê. A maioria dos iteradores de vezes devem ser usado em vez disso. for é implementado em termos de each (assim você está adicionando um nível de indireção), mas com uma reviravolta - for não introduz um novo escopo (ao contrário de each) e as variáveis definidas em seu bloco serão visíveis fora dela. arr = [1, 2, 3] # mau for elem in arr do puts elem end # note que elem é acessível de fora do loop for elem #=> 3 # bom arr.each { |elem| puts elem } # elem não é acessível fora do cada bloco elem #=> NameError: undefined local variable or method 'elem'q Nunca use then para multi-linhas if/unless. # mau if alguma_condicao then # corpo omitido end # bom if alguma_condicao # corpo omitido endq Sempre colocar a condição na mesma linha que o if / unless em uma condicional de várias linha. # mau if alguma_condicao

faca_alguma_coisa faca_alguma_outra_coisa end # bom if alguma_condicao faca_alguma_coisa faca_alguma_outra_coisa endq Favoreça o operador ternário (?:) sobre construções de if/then/else/end. É obviamente mais conciso e mais comum. # mau resultado = if alguma_condicao then alguma_coisa else outra_coisa end # bom resultado = alguma_condicao ? alguma_coisa : outra_coisaq Use uma expressão por ramo em um operador ternário. Isto também significa que os operadores ternários não devem ser aninhados. Prefira construtores if/else nesses casos. # mau alguma_condicao ? (condicao_aninhada ? alguma_coisa_aninhada : outra_coisa_aninhada) : outra_coisa # bom if alguma_condicao condicao_aninhada ? alguma_coisa_aninhada : outra_coisa_aninhada else outra_coisa endq Nunca use if x: ... - a partir de Ruby 1.9, ele foi removido. Use o operador ternário em vez disso. # mau resultado = if alguma_condicao : alguma_coisa else outra_coisa end # bom resultado = alguma_condicao ? alguma_coisa : outra_coisaq Nunca use if x; .... Use o operador ternário.q Aproveitar o fato de que, if e case são expressões que retornam um resultado. # mau if condicao resultado = x else resultado = y end

# bom resultado = if condicao x else y endq Use when x then ... para os casos de uma linha. A sintaxe alternativa when x: ... foi removido a partir do Ruby 1.9.q Nunca use when x; .... Consulte a regra anterior.q Use ! em vez de not. # mau - chaves são necessárias por causa da precedência de operadores x = (not algo) # bom x = !algoEvitar a utilização de !!. # mau x = 'teste' # obscura checagem de nil if !!x # corpo omitido end x = false # dupla negação é inútil em booleanos !!x # => false # bom x = 'teste' unless x.nil? # corpo omitido endq As palavras-chave and e or são proibidas. Não valem a pena. Sempre use && e || em vez disso. # mau # expressão booleana if alguma_condicao and alguma_outra_condicao faca_alguma_coisa end # controle de fluxo document.saved? or document.save! # bom # expressão booleana if alguma_condicao && alguma_outra_condicao

faca_alguma_coisa end # controle de fluxo document.saved? || document.save!Evitar a multi-linha ?: (o operador ternário); Use if/unless.q Favorite o uso do modificador if/unless quando você tem um corpo de linha única. Outra boa alternativa é o uso de fluxo de controle &&/||. # mau if alguma_condicao faca_alguma_coisa end # bom faca_alguma_coisa if alguma_condicao # outra boa opção alguma_condicao && faca_alguma_coisaq Favorecer unless sobre if para negativo condições (ou controle fluxo ||). # mau faca_alguma_coisa if !alguma_condicao # mau faca_alguma_coisa if not alguma_condicao # bom faca_alguma_coisa unless alguma_condicao # outra boa opção alguma_condicao || faca_alguma_coisaq Nunca use unless com else. Reescreva estas com o caso positivo primeiro. # mau unless sucesso? puts 'fracasso' else puts 'sucesso' end # bom if sucesso? puts 'sucesso' else puts 'fracasso' end

q Não use parênteses em torno da condição de uma if/unless/while/until. # mau if (x > 10) # corpo omitido end # bom if x > 10 # corpo omitido endq Nunca utilize while/until condição do para a multi-linha while/until. # mau while x > 5 do # corpo omitido end until x > 5 do # corpo omitido end # bom while x > 5 # corpo omitido end until x > 5 # corpo omitido endq Favoreça o uso do modificador while/until quando você tem uma linha única. # mau while alguma_condicao faca_alguma_coisa end # bom faca_alguma_coisa while alguma_condicaoq Favoreça until sobre o while para condições negativas. # mau faca_alguma_coisa while !alguma_condicao # bom faca_alguma_coisa until alguma_condicaoq Use Kernel#loop com break ao invés de begin/end/until ou begin/end/while para testes

pós-loop. # mau being puts val val += 1 end while val < 0 # bom loop do puts val val += 1 break unless val < 0 endq Omitir parênteses em torno de parâmetros para métodos que fazem parte de uma DSL interna (por exemplo, Rake, Rails, RSpec), métodos que têm status de \"palavra-chave\" em Ruby (por exemplo, attr_reader, puts) e o métodos de acesso de atributos. Use parênteses em torno dos argumentos de todas as outras invocações de método. class Pessoa attr_reader :nome, :idade # omitido end temperanca = Pessoa.new('Temperança', 30) temperanca.nome puts temperanca.idade x = Math.sin(y) array.delete(e) boliche.score.should == 0q Omita o aparelho exterior em torno de um hash de opções implícita. # mau Usuario.set({nome: 'John', idade: 45, permissoes: {leitura: true}}) # bom Usuario.set(nome: 'John', idade: 45, permissoes: {leitura: true})q Omitir ambas as chaves e parênteses exteriores para métodos que são parte de uma DSL interna. class Pessoa < ActiveRecord::Base # mau validates(:nome, { presence: true, length: { within: 1..10 } }) # bom validates :nome, presence: true, length: { within: 1..10 }

endq Omita parênteses para chamadas de método sem argumentos. # mau Kernel.exit!() 2.even?() fork() 'test'.upcase() # bom Kernel.exit! 2.even? fork 'teste'.upcaseq Prefira {...} ao invés de do..end para blocos de linha única. Evite o uso de {...} para a linha multi blocos (encadeamento de várias linhas é sempre feio). Use sempre do..end para \"fluxo de controle\" e \"definições de métodos\" (por exemplo, em Rakefiles e certos DSLs). Evite o do..end quando encadeando. nomes = ['Bozhidar', 'Steve', 'Sarah'] # mau nomes.each |nome| puts nome end # bom nomes.each { |nome| puts nome } # mau nomes.select |nome| nome.start_with?('S') end.map { |nome| nome.upcase } # bom nomes.select { |nome| nome.start_with?('S') }.map { |nome| nome.upcase }Alguns argumentam que o encadeamento de várias linhas ficaria bem com o uso de {...}, mas elesdevem se perguntar - é esse código realmente legível e podem ser extraídos os conteúdos dosblocos em métodos estilosos?q Considere usar argumento explícito de nomes para evitar a escrita de bloco literal que só passa seus argumentos para outro bloco. Cuidado com os impactos no desempenho, assim que, os blocos são convertidos para um Proc. require 'tempfile' # mau def com_dir_tmp

Dir.mktmpdir do |dir_tmp| Dir.chdir(dir_tmp) { |dir| yield dir } # bloco só passa argumentos end end # bom def com_dir_tmp(&block) Dir.mktmpdir do |dir_tmp| Dir.chdir(dir_tmp, &block) end end com_dir_tmp do |dir| puts \"dir é acessível como um parâmetro e pwd é definido: #{dir}\" endq Evite return, onde não é necessário para o fluxo de controle. # mau def algum_metodo(algum_array) return algum_array.size end # bom def algum_metodo(algum_array) algum_array.size endq Evitar self onde não é necessário. (Só é necessário ao chamar um acessador de auto gravação.) # bad def pronto? if self.revisado_em > self.atualizado_em self.trabalhador.update(self.contudo, self.opcoes) self.status = :em_progresso end self.status == :verificado end # good def pronto? if revisado_em > atualizado_em trabalhador.update(contudo, opcoes) self.status = :em_progresso end status == :verificado end


Like this book? You can publish your book online for free in a few minutes!
Create your own flipbook