All Projects → serradura → Dicas De Programacao Em Ruby

serradura / Dicas De Programacao Em Ruby

Dicas para iniciantes de boas práticas de desenvolvimento de software em Ruby

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to Dicas De Programacao Em Ruby

memo
다양한 MD 메모
Stars: ✭ 87 (+47.46%)
Mutual labels:  refactoring, oop
Learning Oop In Php
A collection of resources to learn object-oriented programming and related concepts for PHP developers.
Stars: ✭ 2,359 (+3898.31%)
Mutual labels:  oop, refactoring
Comby
A tool for structural code search and replace that supports ~every language.
Stars: ✭ 912 (+1445.76%)
Mutual labels:  refactoring
Pig Ci Rails
Monitor your Ruby Applications metrics (Memory, SQL Requests & Request Time) as part of your test suite.
Stars: ✭ 53 (-10.17%)
Mutual labels:  rspec
Refactoring Aware Diff
RAID is a tool pipeline that seamlessly enriches GitHub diff results with refactoring information.
Stars: ✭ 50 (-15.25%)
Mutual labels:  refactoring
Rspec Capybara Docker Grid
A dockerized Selenium Grid with RSpec and Capybara
Stars: ✭ 31 (-47.46%)
Mutual labels:  rspec
Instantobjects
Pupular OOP-OPF Library for Delphi (from D2010 to 10.4 Sydney)
Stars: ✭ 50 (-15.25%)
Mutual labels:  oop
Drl Theme Manager
Xcode File Template to generate theme manager for Swift 3+
Stars: ✭ 12 (-79.66%)
Mutual labels:  oop
Cxxctp
DEPRECATED. USE INSTEAD github.com/blockspacer/flextool
Stars: ✭ 58 (-1.69%)
Mutual labels:  refactoring
Fabrication
This project has moved to GitLab! Please check there for the latest updates.
Stars: ✭ 1,017 (+1623.73%)
Mutual labels:  rspec
Experiment
A Go package for experimenting with and evaluating new code paths.
Stars: ✭ 51 (-13.56%)
Mutual labels:  refactoring
Clink
A developer assistance tool to help with refactoring and keeping related code up to date with changes
Stars: ✭ 40 (-32.2%)
Mutual labels:  refactoring
Solrb
Solr + Ruby + OOP + ❤️ = Solrb
Stars: ✭ 37 (-37.29%)
Mutual labels:  oop
A Tiny Js World
A tiny task for those who isn't familiar with OOP and JS OOP in particular yet
Stars: ✭ 50 (-15.25%)
Mutual labels:  oop
Wenoof
WENO interpolation Object Oriented Fortran library
Stars: ✭ 27 (-54.24%)
Mutual labels:  oop
Refactoring2 Zh
《重构 改善既有代码的设计第二版》中文翻译
Stars: ✭ 54 (-8.47%)
Mutual labels:  refactoring
Honeyjs
An open source Javascript Honey Pot implementation
Stars: ✭ 20 (-66.1%)
Mutual labels:  refactoring
Transpec
The RSpec syntax converter
Stars: ✭ 997 (+1589.83%)
Mutual labels:  rspec
Vscode Ruby Test Adapter
A Ruby test adapter extension for the VS Code Test Explorer
Stars: ✭ 50 (-15.25%)
Mutual labels:  rspec
Danf
Danf is a Node.js full-stack isomorphic OOP framework allowing to code the same way on both client and server sides. It helps you to make deep architectures and handle asynchronous flows in order to help in producing scalable, maintainable, testable and performant applications.
Stars: ✭ 58 (-1.69%)
Mutual labels:  oop

Dicas de programação em Ruby

Propósito

Registrar dicas de programação que surgiram por conta de uma conversa/pergunta que rolou no grupo Ruby Brasil do Telegram.

Por favor registre dúvidas e/ou sugestões como issues. 😉

Contribuições são mais que bem-vindas! 😊

Implementação original

A ideia deste projeto é demonstrar pequenas dicas/mudanças para aprimorar o exemplo abaixo.

Por conta disso, seguiremos a proposta original implementando o código com palavras/termos em português.

Porém, como é de conhecimento de mercado é recomendado que você pratique/desenvolva em inglês (confira alguns motivos).

class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    puts 'Seja bem-vindo ' << nome << '!'
    puts 'Você quer jogar?'
    puts 'Digite S ou N'

    resposta = gets

    if resposta.downcase[0] == ('s')
      jogar = true
    else
      jogar = false
    end

    return jogar
  end
end

# Uso:
user = User.new
user.nome = 'André'
user.idade = '30'
user.cidade = 'São José do Rio Preto'

if user.boasvindas
  puts 'Iniciando jogo...'
end

Como utilizar este guia/projeto?

1) Use o menu de dicas:

Como utilizar este guia


2) Configure o projeto e teste cada mudança/dica:

Configurando o projeto

  1. Instale o Ruby (dica: rbenv)
  2. Instale o bundler: gem install bundler
  3. Execute o bundler: bundle install

Executando os testes

bundle exec rspec

Sugestão:

Apó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.


Dicas

Exemplos de boas práticas de desenvolvimento de software em Ruby + técnicas de refatoração.

  • 400d121 Dica 1 - Interpolação 🔗
  • 11445ef Dica 2 - Use métodos privados 🔗
  • 824501f Dica 3 - Remova variáveis desnecessárias 🔗
  • f6300e9 Dica 4 - Defina métodos predicativos 🔗
  • 9f8f36e Dica 5 - Ternário 🔗
  • b7fb557 Dica 6 - Elimine a condicional quando o retorno for um boolean 🔗
  • baeb46e Dica 7 - return é opcional quando usado na última linha de um método 🔗
  • f86e29d Dica 8 - Use o construtor + getters (métodos somente leitura) 🔗
  • 4d79c49 Dica 9 - Use keywords arguments 🔗
  • ec016e0 Dica 10 - Escreva métodos e variáveis no formato snake_case 🔗
  • 66b1048 Dica 11 - Separe classes por responsabilidade (coesão) 🔗
  • b690234 Dica 12 - Organize os métodos por responsabilidade (coesão) 🔗

Dica 1 [diff]

Faça uso de interpolação, é mais performático que concatenar strings.

Link para aprender mais sobre o assunto.

class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar um jogo?'
    puts 'Digite S ou N'
    resposta = gets

    if resposta.downcase == 's'
      jogar = true
    else
      jogar = false
    end

    return jogar
  end
end

🔝 Ir para menu de dicas


Dica 2 [diff]

Use métodos privados, para:

  1. Encapsular/esconder comportamentos
  2. Melhorar a legibilidade de métodos públicos
  3. Permitir reuso
class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    imprime_pergunta

    resposta = gets

    return prosseguir_para_o_jogo(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo(resposta)
    if resposta.downcase[0] == 's'
      jogar = true
    else
      jogar = false
    end

    return jogar
  end
end

🔝 Ir para menu de dicas


Dica 3 [diff]

Remova variáveis caso o valor atribuído seja o último a ser retornado. (Mudança: Foi removido a variável jogar do método prosseguir_para_o_jogo).

class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    imprime_pergunta

    resposta = gets

    return prosseguir_para_o_jogo(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo(resposta)
    if resposta.downcase[0] == 's'
      true
    else
      false
    end
  end
end

🔝 Ir para menu de dicas


Dica 4 [diff]

Defina métodos predicativos (terminam com ? - interrogação) quando o resultado do mesmo for um boolean (true ou false).

class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    imprime_pergunta

    resposta = gets

    return prosseguir_para_o_jogo?(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    if resposta.downcase[0] == 's'
      true
    else
      false
    end
  end
end

🔝 Ir para menu de dicas


Dica 5 [diff]

Use um ternário para expressar condicionais simples/curtas.

Link para aprender mais sobre o assunto.

class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    imprime_pergunta

    resposta = gets

    return prosseguir_para_o_jogo?(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's' ? true : false
  end
end

🔝 Ir para menu de dicas


Dica 6 [diff]

Elimine o ternário/expressão condicional quando o retorno for um boolean.

class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    imprime_pergunta

    resposta = gets

    return prosseguir_para_o_jogo?(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's'
  end
end

🔝 Ir para menu de dicas


Dica 7 [diff]

Métodos sempre retornam o resultado da última linha, logo o uso de return se torna opcional/desnecessário.

class User
  attr_accessor :nome, :idade, :cidade

  def boasvindas
    imprime_pergunta

    resposta = gets

    prosseguir_para_o_jogo?(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's'
  end
end

🔝 Ir para menu de dicas


Dica 8 [diff]

Faç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.

class User
  attr_reader :nome, :idade, :cidade

  def initialize(nome, idade, cidade)
    @nome = nome
    @idade = idade
    @cidade = cidade
  end

  def boasvindas
    imprime_pergunta

    resposta = gets

    prosseguir_para_o_jogo?(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's'
  end
end

# Uso:

user = User.new('André', '30', 'São José do Rio Preto')

if user.boasvindas
  puts 'Iniciando jogo...'
end

🔝 Ir para menu de dicas


Dica 9 [diff]

Faça uso de keywords arguments para tornar os argumentos/dependências de seus métodos mais expressivos.

class User
  attr_reader :nome, :idade, :cidade

  def initialize(nome:, idade:, cidade:)
    @nome = nome
    @idade = idade
    @cidade = cidade
  end

  def boasvindas
    imprime_pergunta

    resposta = gets

    prosseguir_para_o_jogo?(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's'
  end
end

# Uso:
user = User.new(nome: 'André', idade: '30', cidade: 'São José do Rio Preto')

if user.boasvindas
  puts 'Iniciando jogo...'
end

🔝 Ir para menu de dicas


Dica 10 [diff]

Por 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.

class User
  attr_reader :nome, :idade, :cidade

  def initialize(nome:, idade:, cidade:)
    @nome = nome
    @idade = idade
    @cidade = cidade
  end

  def boas_vindas
    imprime_pergunta

    resposta = gets

    prosseguir_para_o_jogo?(resposta)
  end

  private

  def imprime_pergunta
    puts "Seja bem-vindo #{nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's'
  end
end

🔝 Ir para menu de dicas


Dica 11 [diff]

Separe suas classes de acordo com suas responsabilidades (que conceito elas expressam?). Isso poderá facilitar a manutenção e entendimento do código.

PS: Responsabilidade única/pouca tem haver com o que chamamos de coesão.

class User
  attr_reader :nome, :idade, :cidade

  def initialize(nome:, idade:, cidade:)
    @nome = nome
    @idade = idade
    @cidade = cidade
  end
end

class Game
  attr_reader :user

  def initialize(user)
    @user = user
  end

  def start
    boas_vindas
    # Poderá receber mais métodos que venham fazer sentindo ao jogo/projeto...
  end

  private

  def boas_vindas
    imprime_pergunta

    resposta = gets

    prosseguir_para_o_jogo?(resposta)
  end

  def imprime_pergunta
    puts "Seja bem-vindo #{user.nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's'
  end
end

user = User.new(nome: 'André', idade: '30', cidade: 'São José do Rio Preto')
game = Game.new(user)

if game.start
  puts 'Iniciando jogo...'
end

🔝 Ir para menu de dicas


Dica 12 [diff]

Organize os métodos de acordo com suas responsabilidades. Assim como as classes isso poderá facilitar a manutenção e entendimento do código.

PS: Essa prática também tem haver com o que chamamos de coesão.

Mudança:

Perceba que na versão anterior, o método boas_vindas tem diversas responsabilidades. Além disso, ele retorna um boolean e não aplica a convenção de predicado (nem sempre isso será necessário).

O que fizemos para melhorar?

Nessa versão o início do jogo (start), tem duas etapas:

  1. Começa com uma pergunta
  2. Processa a resposta para resolver se o mesmo será ou não iniciado.

Dada essa estrutura, criamos métodos para representar cada uma dessas etapas.

class User
  attr_reader :nome, :idade, :cidade

  def initialize(nome:, idade:, cidade:)
    @nome = nome
    @idade = idade
    @cidade = cidade
  end
end

class Game
  attr_reader :user

  def initialize(user)
    @user = user
  end

  def start
    resposta = pergunta_se_deseja_jogar

    prosseguir_para_o_jogo?(resposta)
  end

  private

  def pergunta_se_deseja_jogar
    imprime_pergunta

    gets
  end

  def imprime_pergunta
    puts "Seja bem-vindo #{user.nome}!"
    puts 'Você quer jogar?'
    puts 'Digite S ou N'
  end

  def prosseguir_para_o_jogo?(resposta)
    resposta.downcase[0] == 's'
  end
end

🔝 Ir para menu de dicas


Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].