{"id":14991258,"url":"https://github.com/serradura/dicas-de-programacao-em-ruby","last_synced_at":"2025-10-17T08:39:46.263Z","repository":{"id":47461322,"uuid":"175323186","full_name":"serradura/dicas-de-programacao-em-ruby","owner":"serradura","description":"Dicas para iniciantes de boas práticas de desenvolvimento de software em Ruby","archived":false,"fork":false,"pushed_at":"2019-03-19T05:25:46.000Z","size":288,"stargazers_count":98,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-25T23:22:11.193Z","etag":null,"topics":["aruba","oop","oop-principles","orientacao-a-objetos","refactoring","refatoracao","rspec","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/serradura.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-13T01:25:28.000Z","updated_at":"2025-03-01T07:10:44.000Z","dependencies_parsed_at":"2022-08-23T23:41:16.554Z","dependency_job_id":null,"html_url":"https://github.com/serradura/dicas-de-programacao-em-ruby","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serradura%2Fdicas-de-programacao-em-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serradura%2Fdicas-de-programacao-em-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serradura%2Fdicas-de-programacao-em-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serradura%2Fdicas-de-programacao-em-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/serradura","download_url":"https://codeload.github.com/serradura/dicas-de-programacao-em-ruby/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514221,"owners_count":21116899,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aruba","oop","oop-principles","orientacao-a-objetos","refactoring","refatoracao","rspec","ruby"],"created_at":"2024-09-24T14:22:02.327Z","updated_at":"2025-10-17T08:39:41.209Z","avatar_url":"https://github.com/serradura.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dicas de programação em Ruby\n\n## Propósito\n\nRegistrar dicas de programação que surgiram por conta de uma conversa/[pergunta](https://t.me/rubybrasil/82504) que rolou no grupo [Ruby Brasil do Telegram](https://t.me/rubybrasil).\n\nPor favor registre dúvidas e/ou sugestões como [issues](https://github.com/serradura/dicas-programacao-em-ruby/issues). 😉\n\n[Contribuições](https://www.digitalocean.com/community/tutorials/como-criar-um-pull-request-no-github-pt) são mais que bem-vindas! 😊\n\n## Implementação original\n\nA ideia deste projeto é demonstrar pequenas dicas/mudanças para aprimorar o exemplo abaixo.\n\nPor conta disso, seguiremos a proposta original implementando o código com palavras/termos em português.\n\nPorém, como é de conhecimento de mercado é recomendado que você pratique/desenvolva em inglês ([confira alguns motivos](https://www.lucascaton.com.br/2015/05/22/8-motivos-pra-programar-em-ingles/#)).\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    puts 'Seja bem-vindo ' \u003c\u003c nome \u003c\u003c '!'\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n\n    resposta = gets\n\n    if resposta.downcase[0] == ('s')\n      jogar = true\n    else\n      jogar = false\n    end\n\n    return jogar\n  end\nend\n\n# Uso:\nuser = User.new\nuser.nome = 'André'\nuser.idade = '30'\nuser.cidade = 'São José do Rio Preto'\n\nif user.boasvindas\n  puts 'Iniciando jogo...'\nend\n```\n\n---\n\n## Como utilizar este guia/projeto?\n\n### 1) Use o menu de [dicas](#dicas):\n\n![Como utilizar este guia](https://raw.githubusercontent.com/serradura/dicas-de-programacao-em-ruby/master/assets/como-utilizar-este-guia.png)\n\n---\n\n### 2) Configure o projeto e teste cada mudança/dica:\n\n**Configurando o projeto**\n\n1. Instale o Ruby (dica: [rbenv](https://medium.com/@phinfonet/primeiros-passos-com-ruby-instala%C3%A7%C3%A3o-com-rbenv-ab705559fc5c))\n2. Instale o bundler: `gem install bundler`\n3. Execute o bundler: `bundle install`\n\n**Executando os testes**\n\n```sh\nbundle exec rspec\n```\n\n**Sugestão:**\n\nApós configurar, acesso o primeiro commit `git checkout f42f6b92` e aplique os conceitos deste guia. Feito isso, use a suite de testes para verificar se o comportamento da aplicação continua sendo o garantido.\n\n---\n\n## Dicas\n\nExemplos de boas práticas de desenvolvimento de software em Ruby + técnicas de refatoração.\n\n* [`400d121`](https://github.com/serradura/dicas-programacao-em-ruby/compare/f42f6b9..400d121#diff-cc95738088603531796e0d0f246a5d77) Dica 1 - Interpolação [🔗](#dica-1-diff)\n* [`11445ef`](https://github.com/serradura/dicas-programacao-em-ruby/compare/400d121..11445ef#diff-cc95738088603531796e0d0f246a5d77) Dica 2 - Use métodos privados [🔗](#dica-2-diff)\n* [`824501f`](https://github.com/serradura/dicas-programacao-em-ruby/compare/11445ef..824501f#diff-cc95738088603531796e0d0f246a5d77) Dica 3 - Remova variáveis desnecessárias [🔗](#dica-3-diff)\n* [`f6300e9`](https://github.com/serradura/dicas-programacao-em-ruby/compare/824501f..f6300e9#diff-cc95738088603531796e0d0f246a5d77) Dica 4 - Defina métodos predicativos [🔗](#dica-4-diff)\n* [`9f8f36e`](https://github.com/serradura/dicas-programacao-em-ruby/compare/f6300e9..9f8f36e#diff-cc95738088603531796e0d0f246a5d77) Dica 5 - Ternário [🔗](#dica-5-diff)\n* [`b7fb557`](https://github.com/serradura/dicas-programacao-em-ruby/compare/9f8f36e..b7fb557#diff-cc95738088603531796e0d0f246a5d77) Dica 6 - Elimine a condicional quando o retorno for um boolean [🔗](#dica-6-diff)\n* [`baeb46e`](https://github.com/serradura/dicas-programacao-em-ruby/compare/b7fb557..baeb46e#diff-cc95738088603531796e0d0f246a5d77) Dica 7 - return é opcional quando usado na última linha de um método [🔗](#dica-7-diff)\n* [`f86e29d`](https://github.com/serradura/dicas-programacao-em-ruby/compare/baeb46e..f86e29d#diff-cc95738088603531796e0d0f246a5d77) Dica 8 - Use o construtor + getters (métodos somente leitura) [🔗](#dica-8-diff)\n* [`4d79c49`](https://github.com/serradura/dicas-programacao-em-ruby/compare/f86e29d..4d79c49#diff-cc95738088603531796e0d0f246a5d77) Dica 9 - Use keywords arguments [🔗](#dica-9-diff)\n* [`ec016e0`](https://github.com/serradura/dicas-programacao-em-ruby/compare/4d79c49..ec016e0#diff-cc95738088603531796e0d0f246a5d77) Dica 10 - Escreva métodos e variáveis no formato snake_case [🔗](#dica-10-diff)\n* [`66b1048`](https://github.com/serradura/dicas-programacao-em-ruby/compare/ec016e0..66b1048#diff-cc95738088603531796e0d0f246a5d77) Dica 11 - Separe classes por responsabilidade (coesão) [🔗](#dica-11-diff)\n* [`b690234`](https://github.com/serradura/dicas-programacao-em-ruby/compare/66b1048..b690234#diff-cc95738088603531796e0d0f246a5d77) Dica 12 - Organize os métodos por responsabilidade (coesão) [🔗](#dica-12-diff)\n\n---\n\n### Dica 1 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/f42f6b9..400d121#diff-cc95738088603531796e0d0f246a5d77)]\n\nFaça uso de interpolação, é mais performático que concatenar strings.\n\n\u003csmall\u003e**[Link](https://guru-sp.github.io/tutorial_ruby/mais-sobre-strings.html)** para aprender mais sobre o assunto.\u003c/small\u003e\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar um jogo?'\n    puts 'Digite S ou N'\n    resposta = gets\n\n    if resposta.downcase == 's'\n      jogar = true\n    else\n      jogar = false\n    end\n\n    return jogar\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 2 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/400d121..11445ef#diff-cc95738088603531796e0d0f246a5d77)]\n\nUse métodos privados, para:\n1. Encapsular/esconder comportamentos\n2. Melhorar a legibilidade de métodos públicos\n3. Permitir reuso\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    return prosseguir_para_o_jogo(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo(resposta)\n    if resposta.downcase[0] == 's'\n      jogar = true\n    else\n      jogar = false\n    end\n\n    return jogar\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 3 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/11445ef..824501f#diff-cc95738088603531796e0d0f246a5d77)]\n\nRemova variáveis caso o valor atribuído seja o último a ser retornado.\n(Mudança: Foi removido a variável `jogar` do método `prosseguir_para_o_jogo`).\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    return prosseguir_para_o_jogo(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo(resposta)\n    if resposta.downcase[0] == 's'\n      true\n    else\n      false\n    end\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 4 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/824501f..f6300e9#diff-cc95738088603531796e0d0f246a5d77)]\n\nDefina métodos predicativos (terminam com `?` - interrogação) quando o resultado do mesmo for um `boolean` (`true` ou `false`).\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    return prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    if resposta.downcase[0] == 's'\n      true\n    else\n      false\n    end\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 5 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/f6300e9..9f8f36e#diff-cc95738088603531796e0d0f246a5d77)]\n\nUse um ternário para expressar condicionais simples/curtas.\n\n\u003csmall\u003e**[Link](https://guru-sp.github.io/tutorial_ruby/construcoes-simples.html)** para aprender mais sobre o assunto.\u003c/small\u003e\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    return prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's' ? true : false\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 6 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/9f8f36e..b7fb557#diff-cc95738088603531796e0d0f246a5d77)]\n\nElimine o ternário/expressão condicional quando o retorno for um boolean.\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    return prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's'\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 7 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/b7fb557..baeb46e#diff-cc95738088603531796e0d0f246a5d77)]\n\nMétodos sempre retornam o resultado da última linha, logo o uso de return se torna opcional/desnecessário.\n\n```ruby\nclass User\n  attr_accessor :nome, :idade, :cidade\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's'\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 8 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/baeb46e..f86e29d#diff-cc95738088603531796e0d0f246a5d77)]\n\nFaça uso do construtor + getters (métodos de leitura) para evitar que o estados do(s) seu(s) objetos se corrompa por conta de uma manipulação indevida/equivocada.\n\n```ruby\nclass User\n  attr_reader :nome, :idade, :cidade\n\n  def initialize(nome, idade, cidade)\n    @nome = nome\n    @idade = idade\n    @cidade = cidade\n  end\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's'\n  end\nend\n\n# Uso:\n\nuser = User.new('André', '30', 'São José do Rio Preto')\n\nif user.boasvindas\n  puts 'Iniciando jogo...'\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 9 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/f86e29d..4d79c49#diff-cc95738088603531796e0d0f246a5d77)]\n\nFaça uso de keywords arguments para tornar os argumentos/dependências de seus métodos mais expressivos.\n\n```ruby\nclass User\n  attr_reader :nome, :idade, :cidade\n\n  def initialize(nome:, idade:, cidade:)\n    @nome = nome\n    @idade = idade\n    @cidade = cidade\n  end\n\n  def boasvindas\n    imprime_pergunta\n\n    resposta = gets\n\n    prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's'\n  end\nend\n\n# Uso:\nuser = User.new(nome: 'André', idade: '30', cidade: 'São José do Rio Preto')\n\nif user.boasvindas\n  puts 'Iniciando jogo...'\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 10 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/4d79c49..ec016e0#diff-cc95738088603531796e0d0f246a5d77)]\n\nPor convensão Ruby faz uso de `snake_case` na declaração de métodos e variáveis, quando o mesmo contém mais de um termo. Com isso o método *boasvindas* se torna _**boas_vindas**_.\n\n```ruby\nclass User\n  attr_reader :nome, :idade, :cidade\n\n  def initialize(nome:, idade:, cidade:)\n    @nome = nome\n    @idade = idade\n    @cidade = cidade\n  end\n\n  def boas_vindas\n    imprime_pergunta\n\n    resposta = gets\n\n    prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's'\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 11 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/ec016e0..66b1048#diff-cc95738088603531796e0d0f246a5d77)]\n\nSepare suas classes de acordo com suas responsabilidades (que conceito elas expressam?).\nIsso poderá facilitar a manutenção e entendimento do código.\n\nPS: Responsabilidade única/pouca tem haver com o que chamamos de [coesão](https://pt.stackoverflow.com/a/81337).\n\n```ruby\nclass User\n  attr_reader :nome, :idade, :cidade\n\n  def initialize(nome:, idade:, cidade:)\n    @nome = nome\n    @idade = idade\n    @cidade = cidade\n  end\nend\n\nclass Game\n  attr_reader :user\n\n  def initialize(user)\n    @user = user\n  end\n\n  def start\n    boas_vindas\n    # Poderá receber mais métodos que venham fazer sentindo ao jogo/projeto...\n  end\n\n  private\n\n  def boas_vindas\n    imprime_pergunta\n\n    resposta = gets\n\n    prosseguir_para_o_jogo?(resposta)\n  end\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{user.nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's'\n  end\nend\n\nuser = User.new(nome: 'André', idade: '30', cidade: 'São José do Rio Preto')\ngame = Game.new(user)\n\nif game.start\n  puts 'Iniciando jogo...'\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n\n### Dica 12 [[diff](https://github.com/serradura/dicas-programacao-em-ruby/compare/66b1048..b690234#diff-cc95738088603531796e0d0f246a5d77)]\n\nOrganize os métodos de acordo com suas responsabilidades.\nAssim como as classes isso poderá facilitar a manutenção e entendimento do código.\n\nPS: Essa prática também tem haver com o que chamamos de [coesão](https://pt.stackoverflow.com/a/81337).\n\n**Mudança:**\n\nPerceba que na versão anterior, o método `boas_vindas` tem diversas responsabilidades.\nAlém disso, ele retorna um boolean e não aplica a convenção de predicado ([nem sempre isso será necessário](https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save)).\n\n**O que fizemos para melhorar?**\n\nNessa versão o início do jogo (start), tem duas etapas:\n1. Começa com uma pergunta\n2. Processa a resposta para resolver se o mesmo será ou não iniciado.\n\nDada essa estrutura, criamos métodos para representar cada uma dessas etapas.\n\n```ruby\nclass User\n  attr_reader :nome, :idade, :cidade\n\n  def initialize(nome:, idade:, cidade:)\n    @nome = nome\n    @idade = idade\n    @cidade = cidade\n  end\nend\n\nclass Game\n  attr_reader :user\n\n  def initialize(user)\n    @user = user\n  end\n\n  def start\n    resposta = pergunta_se_deseja_jogar\n\n    prosseguir_para_o_jogo?(resposta)\n  end\n\n  private\n\n  def pergunta_se_deseja_jogar\n    imprime_pergunta\n\n    gets\n  end\n\n  def imprime_pergunta\n    puts \"Seja bem-vindo #{user.nome}!\"\n    puts 'Você quer jogar?'\n    puts 'Digite S ou N'\n  end\n\n  def prosseguir_para_o_jogo?(resposta)\n    resposta.downcase[0] == 's'\n  end\nend\n```\n\n\u003csmall\u003e[🔝 Ir para menu de dicas](#dicas)\u003c/small\u003e\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserradura%2Fdicas-de-programacao-em-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fserradura%2Fdicas-de-programacao-em-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserradura%2Fdicas-de-programacao-em-ruby/lists"}