{"id":22468083,"url":"https://github.com/isaacalves7/ruby-studies","last_synced_at":"2025-03-27T15:43:28.207Z","repository":{"id":37256334,"uuid":"388546759","full_name":"IsaacAlves7/ruby-studies","owner":"IsaacAlves7","description":"💎 It's a repository of Ruby programming language and his content.","archived":false,"fork":false,"pushed_at":"2023-12-15T20:53:49.000Z","size":279,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-01T19:28:00.915Z","etag":null,"topics":["asdf","asdf-plugin","cocoapods","gem","gems","puma","rake","ruby","ruby-gem","ruby-on-rails","rvm"],"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/IsaacAlves7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-22T17:35:50.000Z","updated_at":"2024-06-18T13:54:25.000Z","dependencies_parsed_at":"2024-12-06T11:14:49.380Z","dependency_job_id":"95f6a08b-b15f-476f-a05b-b6dfb0115940","html_url":"https://github.com/IsaacAlves7/ruby-studies","commit_stats":null,"previous_names":["isaacalves7/ruby-studies","isaacalves7/ruby"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IsaacAlves7%2Fruby-studies","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IsaacAlves7%2Fruby-studies/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IsaacAlves7%2Fruby-studies/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IsaacAlves7%2Fruby-studies/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IsaacAlves7","download_url":"https://codeload.github.com/IsaacAlves7/ruby-studies/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245873798,"owners_count":20686654,"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":["asdf","asdf-plugin","cocoapods","gem","gems","puma","rake","ruby","ruby-gem","ruby-on-rails","rvm"],"created_at":"2024-12-06T11:15:00.551Z","updated_at":"2025-03-27T15:43:28.187Z","avatar_url":"https://github.com/IsaacAlves7.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming/\"\u003e\u003cimg src=\"https://www.bacancytechnology.com/blog/wp-content/uploads/2017/05/Banner.jpg\"\u003e\u003c/a\u003e\u003c/div\u003e\n\n# It's a repository of Ruby language 💎\n\n\u003e 💎 **Preparação**: Para este conteúdo, o aluno deverá dispor de um computador com acesso à internet, um web browser com suporte a HTML 5 (Google Chrome, Mozilla Firefox, Microsoft Edge, Safari, Opera etc.), um editor de texto ou IDE (VSCode etc.) e o software Ruby, com a versão mais recente, instalado na sua máquina local.\n\n\u003c!--\n- https://exercism.org/tracks/ruby\n- https://guides.rubyonrails.org/v3.2/getting_started.html#getting-up-and-running-quickly-with-scaffolding\n- https://gorails.com/\n- https://www.ruby-toolbox.com/\n- https://rspec.info/\n--\u003e\n\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://sd.keepcalms.com/i/keep-calm-and-code-with-ruby-1.png\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\n\n\u003c!-- \n[![.RB](https://img.shields.io/badge/-script.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n[![.RAKE](https://img.shields.io/badge/-script.rake-fff?style=social\u0026logo=Ruby\u0026logoColor=CC342D)](#)\n[![Rakefile](https://img.shields.io/badge/-Rakefile-fff?style=social\u0026logo=Ruby\u0026logoColor=F80000)](#)\n[![.ERB](https://img.shields.io/badge/-script.erb-fff?style=social\u0026logo=Ruby\u0026logoColor=ED1C24)](#)\n[![Rails](https://img.shields.io/badge/-controller-fff?style=social\u0026logo=RubyOnRails\u0026logoColor=CC0000)](#)\n[![RubyGems](https://img.shields.io/badge/-Gemfile-fff?style=social\u0026logo=RubyGems\u0026logoColor=E9573F)](#) \n--\u003e\n\n# 💎 Linguagem Ruby\n\u003ca href=\"https://www.ruby-lang.org/pt/\"\u003e\u003cimg src=\"https://cdn.worldvectorlogo.com/logos/ruby.svg\" height=\"77\" align=\"right\"\u003e\u003c/a\u003e\n\nO **Ruby** foi uma linguagem de programação criada em 1995 por Matz, no Japão. É uma linguagem de programação interpretada e multi-paradigma com foco em simplicidade. Possui uma popularidade em 2001 após o livro \"Programming Ruby\". É uma linguagem **dinâmica**, **open source**, com foco na simplicidade e na **produtividade**. Tem uma sintaxe elegante de leitura natural e fácil escrita. Além disso, tudo no Ruby é tratado como **objeto** da mesma forma como é na linguagem JavaScript, diferente da linguagem Java e C# que possui classes, métodos e atributos.\n\n[![.RB](https://img.shields.io/badge/-Hello.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n~~~ruby\nclass Hello\n  def initialize (nome):\n    @nome = nome.capitalize\n  end\n  \n  def falar\n    puts \"Olá #{@nome}\"\n  end\n end\n \n # Criar um objeto\n h = Hello.new(\"mundo\")\n \n # saída: \"Olá, mundo!\"\n g.falar\n~~~~\n\nPossui uma **tipagem dinâmica** e **forte**, se assemelhando a linguagem de programação Python.\n\n## Hello, World! - Ruby\n[![.RB](https://img.shields.io/badge/-HelloWorld.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n```ruby\nputs \"Hello World!\" # mais comum\nputs (\"Hello World!\")\np \"Hello, World!\"\nprint \"Hello, World!\"\nprintf \"Hello, World!\"\n```\n\n# 🗃️ Gerenciadores de versões\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/2589612?s=280\u0026v=4\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n\nO **gerenciamento de versão** se refere ao processo de planejamento, desenvolvimento, agendamento, testes, implantação e controle de versões de software. Ele garante que as equipes de versão entreguem com eficiência os aplicativos e os upgrades exigidos pelas empresas e preservem, ao mesmo tempo, a integridade do ambiente de produção existente. Vamos utiliza-lo no ambiente de desenvolvimento para gerenciar as versões do Ruby.\n\nNo mundo competitivo, dinâmico e fluído dos negócios e da TI, as versões prematuras são a última coisa de que você precisa. A empresa moderna é um ambiente verdadeiramente dinâmico, e nem todas essas alterações ocorrem no mesmo ritmo. As organizações de TI precisam de um jeito para orquestrar essa grande quantidade de alterações. É aí que as soluções **Release Control** e **Deployment Automation** entram em cena. Elas ajudam a facilitar a transição para a entrega contínua, e trabalham com a transformação digital, uma versão de cada vez. Essa é a nova normalidade da TI.\n\nExiste alguns tipos de gerenciadores de versão indicados:\n\n- **RVM** (Mais popular)\n- rbenv\n- [asdf](https://asdf-vm.com/) (Mais recomendável)\n\nVou usar o **asdf**, você pode usar ele nos sistemas operacionais Linux ou no macOS, além dos interpretadores de comando UNIX, como Bash, ZSH ou Fish.\n\n### Comandos utilizados para iniciar o asdf:\n```\nasdf version\nasdf plugin-add ruby\nasdf install ruby 2.7.1\nruby -v\nasdf list ruby\nasdf local ruby 2.7.1\nasdf list nodejs\n```\n\n# 📦 `gem` - RubyGems\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://rubygems.org/\"\u003e\u003cimg src=\"https://cdn.worldvectorlogo.com/logos/rubygems.svg\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n\nSão bibliotecas de código escritas em Ruby compartilhadas entre a comunidade, então basicamente o `gem` é um gerenciador de pacotes (package manager) imbutido na linguagem Ruby. Você consegue fazer o download de uma biblioteca Ruby fazendo: `gem install nomeDaBiblioteca`, um exemplo de gem é o próprio **Rails**. Existe um site em que você pode encontrar essas gems: https://rubygems.org/?locale=pt-BR\n\n### Comando para listar todas as gems locais\n```sh\ngem list\n```\n\n# 💎 `irb` - Interactive Ruby\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://freesvg.org/img/karthikeyan-ruby-flatmix.png\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n\nTraduzido do inglês-O _Interactive Ruby Shell_ é um **REPL** (Um loop read-eval-print ( REPL ), também chamado de toplevel interativo ou shell de linguagem , é um ambiente de programação de computador interativo simples que recebe entradas de um único usuário, as executa e retorna o resultado para o usuário; um programa escrito em um ambiente REPL é executado por partes. O termo geralmente se refere a interfaces de programação semelhantes ao ambiente interativo clássico de máquina **Lisp** . Exemplos comuns incluem shells de linha de comando e ambientes semelhantes para linguagens de programação , e a técnica é muito característica de linguagens de script).\n\nEsse REPL serve para programação na linguagem de script orientada a objetos Ruby. A abreviação **irb** é um portmanteau da palavra \"interativo\" e a extensão do nome de arquivo para arquivos Ruby, `.rb`.\n\nO programa é iniciado a partir de uma **linha de comando** ( CLI - Command Line Interface ) e permite a execução de comandos Ruby com resposta imediata, experimentando em tempo real. Possui histórico de comandos , recursos de edição de linha e controle de tarefas , e é capaz de se comunicar diretamente como um script de shell pela Internet e interagir com um servidor ativo. Foi desenvolvido por Keiju Ishitsuka .\n\n**(Input) Entrada:**\n```ruby\nirb\n7.times { puts \"Hello, World!\" }\nexit()\n```\n\u003e A saída será o \"Hello, World!\" impresso 7 vezes em cada linha.\n\n**(Output) Saída:**\n\u003cpre\u003e\nHello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\n\u003c/pre\u003e\n\n**(Input) Entrada:**\n```ruby\nnome = Isaac\nnome\n```\n\n**(Output) Saída:**\n\u003cpre\u003e\nIsaac\n\u003c/pre\u003e\n\n\u003e Linguagem de tipagem dinâmica que pode trocar a tipagem a qualquer momento. Como é de costume e padrão, sempre o último valor atribuído é o que conta!\n\n**(Input) Entrada:**\n```ruby\nnome = 7\nnome\n```\n\n**(Output) Saída:**\n\u003cpre\u003e\n7\n\u003c/pre\u003e\n\n\u003e Verificando objetos\n\n**(Input) Entrada:**\n```ruby\nnome.object_id\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\n21\n\u003c/pre\u003e\n\n**(Input) Entrada:**\n```ruby\nnome.class\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nInteger\n\u003c/pre\u003e\n\n\n**(Input) Entrada:**\n```ruby\nnil.object_id\n```\n\n\u003e nil = valor nulo\n\n**(Output) Saída:**\n\n\u003cpre\u003e\n8\n\u003c/pre\u003e\n\n\n**(Input) Entrada:**\n```ruby\nnil.class\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nNilClass\n\u003c/pre\u003e\n\n\n**(Input) Entrada:**\n```ruby\nNilClass.object_id\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\n40\n\u003c/pre\u003e\n\n**(Input) Entrada:**\n```ruby\nNilClass.superclass\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nObject\n\u003c/pre\u003e\n\n\u003e Definindo funções:\n\n**(Input) Entrada:**\n```ruby\ndef somar (x,y)\n  puts \"Outra coisa...\"\n  x+y\nend\n\nsomar (1, 2)\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nOutra coisa...\n3\n\u003c/pre\u003e\n\n\u003e Atribuição de uma função\n\n**(Input) Entrada:**\n```ruby\nsoma = somar (10, 5)\n\nsoma\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\n15\n\u003c/pre\u003e\n\n\u003e Array (Listas)\n\n**(Input) Entrada:**\n```ruby\nlista = [\"Isaac\", 7, \"DevOps\", true, nil, 7.77, \"Ruby\"]\n\nlista\n\nlista.class\n\nlista.length\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\n[\"Isaac\", 7, \"DevOps\", true, nil, 7.77, \"Ruby\"]\nArray\n7\n\u003c/pre\u003e\n\n\u003e Executando o Ruby pelo interpretador no terminal\n\n**(Input) Entrada:**\n```ruby\nruby main.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nHello World\n\u003c/pre\u003e\n\n# 💎 RSpec\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://rspec.info/images/logo.png\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n\n# Ruby + Cucumber + Capybara\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://i.pinimg.com/564x/5f/34/32/5f3432f3d53c217eebcd22121235ac3a.jpg\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n  \n# 💎 Paradigma de Programação Imperativo em Ruby\n\n## Executando um código-fonte\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://www.ruby-toolbox.com/assets/startpage/box-fa44e6399af516d2641d0f88ee7d18760a7973181b568f40e86a1e441e03a83a.png\" height=\"277\"\u003e\u003c/a\u003e\u003c/div\u003e\n\n## Comentário\n```ruby\n# comentário de uma linha\n```\n\n## Strings\nSão tipos de dados tratados como escrita ou texto, podem ser definidas entre aspas duplas `(\"\")` ou apóstrofos, também conhecida como aspas simples `('')`.\n\n**Exemplo:**\n```ruby\nnome = \"Isaac\"\nnome = 'Isaac'\nnome = %q(meu texto)\n```\n\n### Caracteres de escape com Aspas `(\"\")`\n\n#### Nova linha\n```ruby\n\\n\n```\n\n#### Tab\n```ruby\n\\t\n```\n\n#### Aspas\n```ruby\n\\\"\n```\n\n### Evento\n```ruby\nnome = \"Isaac\"\nmensagem = \"Bem vindo #{nome}\"\n\nputs mensagem\n```\n\n### Heredoc\n```ruby\nmensagem = \u003c\u003c~TXT\n  Essa é minha mensagem\nTXT\n```\n\n**Código-fonte `main.rb`:**\n~~~ruby\nnome = \"Isaac\"\nmensagem = \"Bem vindo #{nome}\"\nmensagemErrada = 'Bem vindo #{nome}'\nsoma = \"O valor da soma de 1 + 2 = #{1 + 2}\"\noutraMensagem = \"Bem vindo\" + nome\n\nputs nome\nputs mensagem\nputs mensagemErrada\nputs soma\nputs outraMensagem\n~~~\n\n\u003e `#{}` não serve somente para strings, mas sim para interpolação de código. Os apóstrofos se inseridos em conjunto com o delimitador de manipulação de variável retornarão o mesmo código inserido.\n\n**(Input) Entrada:**\n```ruby\nruby main.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nIsaac\nBem vindo Isaac\nBem vindo #{nome}\nO valor da soma de 1 + 2 = 3\nBem vindo Isaac\n\u003c/pre\u003e\n\n**Código-fonte `mensagem.rb`:**\n~~~ruby\nnome = \"Isaac\"\nmensagem = \u003c\u003c-MENSAGEM\n  Olá #{nome}\n  \n  Bem vindo(a) ao meu programa!\n  \n  Obrigado\nMENSAGEM\n\nputs mensagem\n~~~\n\n**(Input) Entrada:**\n```ruby\nruby mensagem.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nOlá Isaac\n\nBem vindo(a) ao meu programa!\n\nObrigado\n\u003c/pre\u003e\n\n**Código-fonte `mensagem.rb`:**\n~~~ruby\nmensagem = %q(Bem vindo ao meu programa)\nmensagemErrada = %q(Bem vindo ao meu programa #{nome})\n\nputs mensagem\nputs mensagemErrada\n~~~\n\n**(Input) Entrada:**\n```ruby\nruby mensagem.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nBem vindo ao meu programa\nBem vindo ao meu programa #{nome}\n\u003c/pre\u003e\n\n\u003e Caso queira interpolar com o delimitador de manipulação de variável `%q`, é necessário usar o `%Q`.\n\n**Código-fonte `mensagem.rb`:**\n~~~ruby\nnome = \"Isaac\"\nmensagem = %Q(Bem vindo ao meu programa #{nome})\nputs mensagem\n~~~\n\n**(Input) Entrada:**\n```ruby\nruby mensagem.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nBem vindo ao meu programa Isaac\n\u003c/pre\u003e\n\n**Código-fonte `public-methods.rb`:**\n~~~ruby\nnome = \"Isaac\"\nmensagem = %Q(Bem vindo ao meu programa #{nome})\nputs mensagem.public_methods\nputs mensagem\n~~~\n\n\u003e Esse comando, atributo `public_methods`, vai imprimir os métodos públicos do Ruby que possui nessa string para ser utilizado.\n\n**(Input) Entrada:**\n```ruby\nruby public-methods.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nunicode_normalized?\nencode!\nunicode_normalize\nascii_only?\nunicode_normalize!\nto_r\nto_c\nencode\ninclude?\n%\n*\n+\nunpack\nunpack1\ncount\npartition\n+@\n-@\n\u003c=\u003e\n\u003c\u003c\nsum\n==\n===\nnext\n=~\n[]\n[]=\nempty?\ncasecmp\neql?\ninsert\ncasecmp?\nmatch?\nbytesize\nmatch\nnext!\nsucc!\nindex\nupto\nreplace\nrindex\nchr\nclear\nbyteslice\ngetbyte\nsetbyte\nfreeze\nscrub\nscrub!\ndump\ninspect\nintern\nupcase\ndowncase\ncapitalize\nswapcase\nupcase!\nundump\nlength\nsize\ndowncase!\nsucc\nswapcase!\nhex\ncapitalize!\nsplit\nchars\noct\ngrapheme_clusters\nconcat\ncodepoints\nlines\nbytes\nto_str\nend_with?\nstart_with?\nreverse\nreverse!\nsub\nto_s\nto_i\nto_f\nrjust\ncenter\nprepend\ncrypt\nord\nchomp\nstrip\nto_sym\nljust\ndelete_prefix\ndelete_suffix\nlstrip\ngsub\nscan\nchomp!\nsub!\ngsub!\nrstrip\ndelete_prefix!\nchop\nlstrip!\nrstrip!\nchop!\ndelete_suffix!\nstrip!\ntr_s\ndelete\nsqueeze\ntr!\ntr\ndelete!\nsqueeze!\neach_line\neach_byte\ntr_s!\neach_codepoint\neach_grapheme_cluster\nslice\nslice!\neach_char\nencoding\nforce_encoding\nb\nvalid_encoding?\nrpartition\nhash\nbetween?\nclamp\n\u003c=\n\u003e=\n\u003c\n\u003e\nsingleton_class\ndup\nitself\ntaint\ntainted?\nuntaint\nuntrust\nuntrusted?\ntrust\nmethods\nsingleton_methods\nprotected_methods\nprivate_methods\npublic_methods\ninstance_variables\ninstance_variable_get\ninstance_variable_set\ninstance_variable_defined?\nremove_instance_variable\ninstance_of?\nkind_of?\nis_a?\ndisplay\nclass\nfrozen?\ntap\nthen\nyield_self\npublic_send\nextend\nclone\nmethod\npublic_method\nsingleton_method\ndefine_singleton_method\n!~\nnil?\nrespond_to?\nobject_id\nsend\nto_enum\nenum_for\n__send__\n!\ninstance_eval\ninstance_exec\n!=\nequal?\n__id__\nBem vindo ao meu programa Isaac\n\u003c/pre\u003e\n----\n\n**Código-fonte `mensagem.rb`:**\n~~~ruby\nnome = \"Isaac\"\nmensagem = %Q(Bem vindo ao meu programa #{nome})\n\nputs \"O tamanho da minha string é: #{mensagem.length()}\"\n~~~\n\n**(Input) Entrada:**\n```ruby\nruby mensagem.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nO tamanho da minha string é: 30\n\u003c/pre\u003e\n\n### Operações com Strings\n#### Pegar um caracter da String\n\n```ruby\n# 01234\n\"Isaac\"[0] # \"I\"\n```\n\n#### Todos os caracteres da string como array\n```ruby\n\"Isaac\".chars # [\"I\", \"s\", \"a\", \"a\", \"c\"]\n```\n\n#### Substring\n```ruby\n\"Isaac\"[0,3] # \"Isa\"\n```\n\n#### Multiplicação de Strings\n```ruby\n\"-\" * 10 #  \"----------\"\n```\n\n#### Multiplicação de Strings\n```ruby\n\"   mensagem   \".strip #  \"mensagem\"\n```\n\n#### Maiúsculo/Minúsculo\n```ruby\n\"isaac\".upcase # upcase\n\"ISAAC\".downcase # downcase\n```\n\n#### Primeira letra maíuscula\n```ruby\n\"isaac\".capitalize\n```\n\n#### Dividir\n```ruby\n\"cadu teste outra_nome\".split\n\"cadu-teste-outro_nome\".split(\"-\")\n```\n\n### Brincando com manipulação de variáveis e operações de Strings\n\u003e o comando `p` imprime a string da sua forma natural inserida pelo programador, diferente do comando `print` que imprime com valor nulo.\n\n```ruby\nnome = \"Isaac\"\nnomes = \"isaac matheus janaina alexandre jurema fábio cauã gabriela jade nemo marlim fanny jajá azul\".split(\",\")\nnumero = 7\nmensagem = \"minha mensagem\"\n\nputs [\"A\", \"B\", \"C\"]\nprint [\"A\", \"B\", \"C\"]\np [\"A\", \"B\", \"C\"]\np \"quebra automaticamente\\\"\" # quebra de linha\np nome\np nome[0]\np nome[nome.length - 1]\np nome[-1]\np nome.chars\np nome.chars.length\np nome[0,3]\n# multiplicação de strings\nputs \"Cabeçalho\"\nputs \"---------\"\nputs \"texto de informação\"\nputs \"-\" * 10\nputs \"O número é %05d\" % numero\nputs \"*\" * 10\nputs mensagem.capitalize\n# gsub\nputs mensagem.gsub(\"mensagem\",\"mulher\")\np nomes\n```\n\n**(Input) Entrada:**\n```ruby\nruby main.rb\n```\n\n**(Output) Saída:**\n\n\u003cpre\u003e\nA\nB\nC\n[\"A\", \"B\", \"C\"][\"A\", \"B\", \"C\"]\n\"quebra automaticamente\\\"\"\n\"Isaac\"\n\"I\"\n\"c\"\n[\"I\",\"s\",\"a\",\"a\",\"c\"]\n5\n\"Isa\"\nCabeçalho\n---------\ntexto de informação\n---------\nO número é 00007\nMinha mulher\n\u003c/pre\u003e\n\n# Tipos numéricos\n**(Input) Entrada**\n```ruby\nirb\n7.class\n7.7.class\n```\n\n**(Output) Saída**\n\u003cpre\u003e\nInteger\nFloat\n\u003c/pre\u003e\n\n## `Int` - Inteiros\n**(Input) Entrada**\n```ruby\nputs 123_500\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n123500\n\u003c/pre\u003e\n\n## `Float` - Flutuante\n**(Input) Entrada**\n```ruby\n# soma um inteiro com um ponto flutuante\nsoma = 3 + 4.77\np soma\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n7.77\n\u003c/pre\u003e\n\n# Símbolos\nOs **símbolos** são tipos especiais de objeto que são criados com o `:` no início do identificador. Eles são únicos globalmente e imutáveis, então quando você utilizar um símbolo no Ruby ele vai usar aquele objeto na memória e vai usar o nome, `por exemplo `Isaac`, o Ruby vai usar esse objeto na memória a primeira vez e quando eu reutilizar esse símbolo ele vai reutilizar esse mesmo objeto.\n\nSão ótimos substitutos para strings quando você for usado como label / chaves.\n\n**(Input) Entrada**\n```ruby\nirb\nvariavel = \"isaac\"\nvariavel.object_id\nvariavel = \"isaac\"\nvariavel.object_id\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n\"isaac\"\n28420\n\"isaac\"\n35380\n\u003c/pre\u003e\n\n\u003e Toda vez que reutilizamos uma string, elas são imutáveis, ela vai gerar um novo objeto na memória. Então, toda vez que usar a string, o Ruby vai usar a memória do computador e vai referenciar ela, portanto vai ser criada várias posições na memória dependendo do uso.\n\n**(Input) Entrada**\n```ruby\nirb\n:\"isaac\"\n:isaac # posso fazer desse modo, sem especificar a string com aspas duplas\n:isaac.object_id\n:isaac.object_id\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n:isaac\n:isaac\n2290588\n2290588\n\u003c/pre\u003e\n\n\u003e Note que ele não muda o id do objeto, ou seja, toda vez ele vai gerar o mesmo objeto.\n\n**(Input) Entrada**\n```ruby\nirb\n1.send(\"+\", 2) # o símbolo + está sendo usado na memória, não reutilizada\n1.send(:+, 2) # o símbolo + está sendo usado na memória, sendo reutilizado\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n3\n3\n\u003c/pre\u003e\n\n### Dicionário\n\n**(Input) Entrada**\n```ruby\nirb\ndicionario = {}\ndicionario[\"isaac\"] = \"7\"\ndicionario[\"isaac\"]\ndicionario[:isaac] = \"7\"\ndicionario[:isaac]\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n\"7\"\n\"7\"\n\"7\"\n\"7\"\n\u003c/pre\u003e\n\n\u003e Entretanto, toda vez que eu acessar esse Hash, ele está criando na memória. Portanto, é muito perfomático criar símbolos do que texto na memória toda vez.\n\n## Arrays (listas)\nArrays ou listas são listas de valores separados por vírgula.\n\n```ruby\nlista = []\nlista = Array.new\n```\n\nOs arrays no Ruby, assim como na maioria das linguagens de programação de alto-nível, podem ser de diferentes tipos.\n\n**(Input) Entrada**\n```ruby\nlista = [1, 2.7, \"3\", \"isaac\", true] # elementos do tipo int, float, string e boolean (TrueClass)\nlista[1] # Acessando um item da lista no índice 1 = 2.7\np lista[1]\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n2.7\n\u003c/pre\u003e\n\n### Incluir um novo elemento na lista\n**(Input) Entrada**\n```ruby\nlista = [1, 2.7, \"3\", \"isaac\", true] # elementos do tipo int, float, string e boolean (TrueClass)\nlista \u003c\u003c \"novo item 1\"\n# ou\nlista.append(\"novo item 2\")\np lista\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n[1, 2.7, \"3\", \"isaac\", true, \"novo item 1\", \"novo item 2\"]\n\u003c/pre\u003e\n\n### Outros métodos para manipular Arrays\n```ruby\nlista.length # tamanho do array\nlista.empty? # verifica se o array está vazio\nlista.first # pegar o primeiro valor\nlista.last # pegar o último valor\nlista.include?(1) # verifica se algum item da lista inclui o valor específico\n```\n\n**Somando listas com o Ruby**:\n\n**(Input) Entrada**\n```ruby\nlista_1 = [0, 1, 2, 3]\nlista_2 = [4, 5, 6, 7]\nresultado = lista_1 + lista_2\np resultado\n```\n\n**(Output) Saída**\n\u003cpre\u003e\n[0, 1, 2, 3, 4, 5, 6, 7]\n\u003c/pre\u003e\n\n## Hashes\nEm algumas linguagens de programação o Hash é chamado de **Hash-Map** ou **dicionário** (é uma estrutura de chave-valor). O Hash permite você acessar qualquer índice diretamente na memória do computador.\n\n**Para iniciar um Hash**\n```ruby\nhash = {}\n# ou\nhash = Hash.new\n```\n\n**Sintaxe do Hash**\n```ruby\nhash = {\n  chave =\u003e valor,\n  chave =\u003e valor,\n}\n```\n\n\u003e Um hash pode ser qualquer tipo primitivo de dados, pode ser um número, uma string ou um símbolo.\n\n```ruby\ni = {} # hash i vazio\nh = {} # hash h vazio\ni.class\na.class\ni = { \"nome\" =\u003e \"Isaac\", \"idade\" =\u003e 21 } # Strings e números\nh = { :nome =\u003e \"Isaac\", :idade =\u003e 21 } # Símbolos\nh[:nome] # acessando um hash\nh[:nome] = \"Novo nome\" # Alterando um hash\nh[77] = \"New value\" # Adicionando um novo item no hash\n```\n\n\u003e Ao acessar o hash, note que é bem parecido com array, porém nele você está acessando o índice pelo próprio nome dele.\n\n**Alguns atributos e métodos para o hash**\n```ruby\nhash.keys # retorna um array com as chaves\nhash.values # retorna um array com os valores\nhash.empty? # verifica se o hash está vazio\n```\n\n## Entrada de dados\nComo faz para capturar um input da tela padrão do computador, existe um método chamado `gets`, ele possibilita fazer um prompt da entrada padrão. Assim, que a gente entrar um valor na entrada padrão, esse valor vai ser acessado pra que a gente consiga acessa-lo depois.\n\n```ruby\ngets()\n# ou\ngets\n```\n\n**Sintaxe**\n```ruby\nnome = gets\nnome\nputs nome\nnome.chomp() # Tira o último caractere social, no caso, o \\n\n# ou\nnome = nome.chomp\n# ou\nnome = gets.chomp\n```\n\n### Colocando prompt\n```ruby\nputs \"Digite o seu nome: \"\nnome = gets\nputs \"Seu nome é #(nome)\"\n```\n\n## Estruturas Condicionais\n### Sintaxe\n```ruby\nif condicao \n  faca_algo\nelse\n  faca_outra_coisa\nend\n```\n\n### Operadores relacionais\n```ruby\n== # igualdade\n!= # diferente\n\u003e # maior que\n\u003e= # maior ou igual a \n\u003c # menor que\n\u003c= # menor ou igual a \n```\n\n\n### Operadores lógicos\n```ruby\n! # Negação\n\u0026\u0026 # And\n|| # Or \n```\n\n### Estrutura condicional com operadores relacionais\n```ruby\nvalor = 20\nif valor \u003e 50\n  puts \"Eu sou maior que 50\"\nelse\n  puts \"Eu sou menor que 50\"\nend\n```\n\n### Estrutura condicional com operadores relacionais `\u0026\u0026` lógicos\n```ruby\nvalor = 65\nif valor \u003e= 50 \u0026\u0026 valor \u003c= 100\n  puts \"Estou entre 50 e 100\"\nend\n```\n\n### Estrutura condicional com `elsif` (senão se)\n```ruby\nvalor = 20\nif valor \u003e 50\n  puts \"Eu sou maior que 50\"\nelsif valor == 50\n  puts \"Eu sou igual a 50\"\nelse # nesse caso, o else sempre vem por último, depois do elsif\n  puts \"Eu sou menor que 50\"\nend\n```\n\n\u003e Apenas `nil` e `false` são avaliados como **falso**, se por acaso tiver um parênteses vazio será do valor lógico **true**.\n\n\n### Estrutura condicional com uma linha de condição\n```ruby\nvalor = 20\nputs \"Eu sou maior que 50\" if valor \u003e 50 \n```\n\n### `unless`\n\u003e Se a condição não for verdadeira, ele iá executar o bloco de código dentro dela (faca_isso).\n\n**Sintaxe**:\n```ruby\nunless condicao\n  faca_isso\nend\n```\n\n### Operador ternário\n\u003e Usado para estruturas condicionais de pequeno porte.\n\n```ruby\nvalor \u003e 50 ? puts \"Eu sou maior que 50\" : puts \"Eu sou menor que 50\"\n# if valor \u003e 50\n#   puts \"Eu sou maior que 50\"\n# else\n#   puts \"Eu sou menor que 50\"\n```\n\n### Switch case\n```ruby\nlinguagem = \"ruby\"\ncase linguagem\nwhen \"ruby\"\n  puts \"bem vindo ao curso de ruby\"\nwhen \"golang\"\n  puts \"curso não disponível\"\nelse\n  puts \"não conheço essa linguagem\"\nend\n```\n\n### Exemplo estrutura de condicional:\n**Entrada (Input)**:\n```ruby\nvalor gets.chomp.to_i # conversor para inteiro\n\np valor.class # String\n\np valor\n\nif valor \u003e 20\n  puts \"Esse valor é maior que 20\"\nelsif valor == 20\n  puts \"Esse valor é igual a 20\"\nelse\n  puts \"Esse valor é menor que 20\"\nend\n```\n\n**Saída (Output)**:\n\n\u003cpre\u003e\n50\nInteger\n50\nEsse valor é maior que 20\n\u003c/pre\u003e\n\n### Exemplo estrutura de condicional:\n**Entrada (Input)**:\n```ruby\nputs \"Digitar um valor: \"\nvalor = gets.chomp.to_i\n\nif valor \u003e= 50 \u0026\u0026 valor \u003c= 100\n  puts \"Estou entre 50 e 100\"\nelse\n  puts \"Eu não estou entre 50 e 100\"\nend\n```\n\n**Saída (Output)**:\n\n\u003cpre\u003e\n\n\u003c/pre\u003e\n\n\n### Exemplo 2 - estrutura de condicional:\n**Entrada (Input)**:\n```ruby\nvalor = \"\"\nif valor \n  puts \"Eu tenho alguma coisa\" # true = vazio\nelse\n  puts \"Eu não tenho nada\"\nend\n```\n\n**Saída (Output)**:\n\n\u003cpre\u003e\nEu tenho alguma coisa\n\u003c/pre\u003e\n\n\u003e O resultado se torna verdadeiro devido ao tipo do código inserido, para ele declarar falso, é preciso especificar uma negação na primeira condição\n\n**Entrada (Input)**:\n```ruby\nvalor = \"\"\nif !valor.empty? # se valor não é vazio\n  puts \"Eu tenho alguma coisa\" # true = vazio\nelse\n  puts \"Eu não tenho nada\"\nend\n```\n\n**Saída (Output)**:\n\n\u003cpre\u003e\nEu não tenho nada\n\u003c/pre\u003e\n\n\u003e O mesmo pode ser feito com `unless`\n\n**Entrada (Input)**:\n```ruby\nvalor = \"\"\nunless valor # se valor não é vazio\n  puts \"Eu tenho alguma coisa\"\nelse\n  puts \"Eu não tenho nada\"\nend\n```\n\n**Saída (Output)**:\n\n\u003cpre\u003e\nEu não tenho nada\n\u003c/pre\u003e\n\n## Laços de Repetição (Loops)\nOs laços ou loops, são formas de executar repetitivamente uma operação a fim de obedecer a uma estrutura condicional.\n\n### `While`\nO `while` significa **repetir enquanto a condição for verdadeira**. \n\n**Entrada (Input)**\n```ruby\nvalor = 5 # imprimindo de 5 até 1\nwhile valor \u003e 0 # true\n  puts valor\n  valor = valor - 1 # Outra forma: valor -= 1\nend # quando parar em 0, irá retornar em `false`, a execução será encerrada\n```\n\n**Saída (Output)**\n\u003cpre\u003e\n5\n4\n3\n2\n1\n\u003c/pre\u003e\n\n**Entrada (Input)**\n```ruby\nvalor = 5\nwhile valor \u003e 0\n  puts valor\n  valor = valor - 0\nend\n```\n\n**Saída (Output)**\n\u003cpre\u003e\n`looping infinito do valor`\n\u003c/pre\u003e\n\n### `For`\nFunciona semelhante ao `while`, porém você declara uma variável em uma lista de objetos.\n\n```ruby\nfor i in [1, 2, 3, 4, 5] # para i em algum array, hash ou objeto que corresponde ao `.each`\n  puts \"O número é #{i}\"\nend\n```\n\n### `Until`\nSemelhante ao `while`, a diferença está na condição, que assim quando executar a condição for falsa.\n\n```ruby\nvalor = 0\nuntil valor == 10\n  puts valor\n  valor += 1\nend  \n```\n\n### Alguns comandos usados em laços\n```ruby\nbreak # sair do laço\nreturn # sair do laço e do método onde o laço está contido\nnext # vai imediatamente para a próxima iteração\nredo # repete o laço do início (a condição não será reavaliada)\n```\n\n### Exemplo 1: Imprimir de 0 até 9\n**Entrada (Input)**:\n```ruby\nvalor = 0\nwhile (valor \u003c 10)\n  puts \"O valor é #{valor}\"\n  valor += 1\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\nO valor é 6\nO valor é 7\nO valor é 8\nO valor é 9\n\u003c/pre\u003e\n\n### Exemplo 1: Imprimir de 0 até 5\n**Entrada (Input)**:\n```ruby\nvalor = 0\nwhile (valor \u003c 10)\n  puts \"O valor é #{valor}\"\n  break if valor == 5\n  valor += 1\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\n\u003c/pre\u003e\n\n### Exemplo 1: Imprimir de 0 até 5\n**Entrada (Input)**:\n```ruby\nvalor = 0\nwhile (valor \u003c 10)\n  puts \"O valor é #{valor}\"\n  break if valor == 5\n  valor += 1\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\n\u003c/pre\u003e\n\n### Exemplo 2: For\n**Entrada (Input)**:\n```ruby\nfor meu_valor in [0,1,2,3,4,5,6,7]\n  puts \"Meu valor é #{meu_valor}\"\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\nO valor é 6\nO valor é 7\n\u003c/pre\u003e\n\n### Exemplo 2: Range For\n**Entrada (Input)**:\n```ruby\nrange = 0..7\nfor meu_valor in range\n  puts \"Meu valor é #{meu_valor}\"\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\nO valor é 6\nO valor é 7\n\u003c/pre\u003e\n\n### Exemplo 2: For Range\n**Entrada (Input)**:\n```ruby\nfor meu_valor in 0..7\n  puts \"Meu valor é #{meu_valor}\"\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\nO valor é 6\nO valor é 7\n\u003c/pre\u003e\n\n### Exemplo 2: For para Arrays\n**Entrada (Input)**:\n```ruby\nlista = [0,1,2,3,4,5,6,7]\nfor meu_valor in lista\n  puts \"Meu valor é #{meu_valor}\"\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\nO valor é 6\nO valor é 7\n\u003c/pre\u003e\n\n### Exemplo 2: Each\n**Entrada (Input)**:\n```ruby\nlista = [0,1,2,3,4,5,6,7]\nlista.each do |meu_valor|\n  puts \"O valor é #{meu_valor}\"\nend\n```\n\n\u003e Em JavaScript, podemos fazer algo parecido com o comando `for each`.\n\n**Saída (Output)**:\n\u003cpre\u003e\nO valor é 0\nO valor é 1\nO valor é 2\nO valor é 3\nO valor é 4\nO valor é 5\nO valor é 6\nO valor é 7\n\u003c/pre\u003e\n\n### Exemplo 2: Each com hash\n**Entrada (Input)**:\n```ruby\nhash = {nome: Isaac, idade: 21}\nlista.each do |chave, valor|\n  puts \"Meu nome é #{chave} e tenho #{valor} anos\"\nend\n```\n\n**Saída (Output)**:\n\u003cpre\u003e\nMeu nome é Isaac e tenho 21 anos\n\u003c/pre\u003e\n\n## Métodos (Methods)\n```ruby\ndef meu_metodo\n  puts \"meu_metodo foi executado\"\nend\n```\n\n```ruby\ndef meu_metodo(parametro1, parametro2)\n  puts \"meu_metodo foi executado com #{parametro1} e #{parametro2}\"\nend\n```\n\n\u003e a palavra `return` é opcional. O ruby sempre retorna o resultado da execução da última linha.\n\n**Exemplo**:\n```ruby\ndef soma (a, b)\n  return a + b\nend\n\n# é igual\n\ndef soma(a, b)\n  a + b\nend\n```\n\n**Exemplo 2**:\n\n**Entrada (Input)**:\n```ruby\ndef soma (valor1, valor2 = 0) # valor1 = 10 e valor2 = 0\n  puts \"Estou somando #{valor1} e #{valor2}\"\n  valor1 + valor2\nend\n\nputs \"Vou executar a soma\"\nputs soma(10) # valor1\n```\n\n**Saída (Output)**:\n\n\u003cpre\u003e\nVou executar a soma\nEstou somando 10 e 0\n10\n\u003c/pre\u003e\n\n**Exemplo 3**:\n\n**Entrada (Input)**:\n```ruby\ndef soma (valor1, valor2 = 0) # valor1 = 10 e valor2 = 0\n  puts \"Estou somando #{valor1} e #{valor2}\"\n  valor1 + valor2\nend\n\ndef soma_com_parametros_nomeados(valor1:,valor2:)\n  soma(valor1, valor2)\nend\n\nputs \"Vou executar a soma\"\nputs soma_com_parametros_nomeados(valor1: 5)\n```\n\n**Saída (Output)**:\n\n\u003cpre\u003e\nVou executar a soma\nEstou somando 5 e 0\n5\n\u003c/pre\u003e\n\n## Atribuição condicional de variável (Attributes)\n```ruby\nvariavel = nil\nvariavel = \"Algum valor\" if variavel.nil?\n```\n\n```ruby\nvariavel = nil\nvariavel = \"Algum valor\" unless variavel\n```\n\n```ruby\nvariavel ||= \"Valor\"\n```\n\n**Exemplo**:\n```ruby\nvariavel = 10\nvariavel ||= 20\nvariavel\nvariavel = nil\nvariavel\nvariavel ||= 20\nvariavel\nnova_variavel ||= 100\nnova_variavel\n```\n\n## Exercício 01: Análise de Palíndromo\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"https://c.tadst.com/gfx/1200x630/palindrome-bob.png?1\" height=\"177\"\u003e\u003c/div\u003e\u003cbr \\\u003e\n\n\u003e **Palíndromo**: São palavras que são iguais quando lidas de frente para trás e de trás para frente.\n\n**Exemplos**:\n\n\u003cpre\u003e\nOvo\nOsso\nRadar\nPop\nBob\n...\n\u003c/pre\u003e\n\n\u003e **Objetivo**: \n\u003e - Definir um método que verifica se é palíndromo\n\u003e - Usar gets para pedir input de dados e chamar o método\n\u003e - Imprimir se é palíndromo ou não\n\n**Resolução**:\n\n**Entrada (Input)**\n```ruby\nputs \"Digite alguma palavra ou número:\"\npalavra = gets.chomp\ndef palindromo?(palavra)\n    palavra.downcase == palavra.downcase.reverse\nend\n\nputs palindromo?(palavra)\n```\n\n**Saída (Output)**\n\u003cpre\u003e\nDigite alguma palavra ou número:\nIsaac\nfalse\n\nDigite alguma palavra ou número:\nPop\ntrue\n\nDigite alguma palavra ou número:\n7\ntrue\n\u003c/pre\u003e\n\n# 💎 Paradigma de Programação Orientada a Objetos em Ruby\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://static.wikia.nocookie.net/battlefordreamisland/images/5/5a/Garnet.png/revision/latest?cb=20210222161103\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n\nAgora, iremos aprender sobre o paradigma orientado a objetos em Ruby, se você tiver o mesmo conhecimento em teorias e lógicas sobre este paradigma é bem mais fácil, basta somente usar com a semântica do Ruby.\n\n## A diferença entre Classes x Objetos\n![Classes e Objetos - Poo](https://user-images.githubusercontent.com/61624336/156935818-8e6ee659-f443-4afc-afbc-8e89c51b0715.png)\n\nNa imagem acima, conseguimos ter uma boa ideia do que seria uma classe e objetos. A **classe**, ou _class_, é como se fosse uma **planta** ou **esboço** de um objeto ou partes de um objeto. \n\nUm **objeto**, ou _object_, é a construção daquela _classe_ (planta ou esboço) na memória do computador, portanto, chamamos essa construção de **instância**.\n\n\u003e Então, podemos obter vários objetos na memória do computador a partir dessa **classe** (desenho técnico) como referência (como esboço).\n\n### Sintaxe para classe:\n\n[![.RB](https://img.shields.io/badge/NomeDaClasse.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass NomeDaClasse\nend\n```\n\n### Sintaxe para objeto:\n\n[![.RB](https://img.shields.io/badge/NomeDaClasse.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nobj NomeDaClasse.new\n```\n\n### Instanciando uma classe pelo objeto\n \n[![.RB](https://img.shields.io/badge/hello_world.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass MinhaClasse\nend\n\nobjeto = MinhaClasse.new\n\np objeto.object_id\n```\n\n[![irb](https://img.shields.io/badge/irb-fff?style=social\u0026logo=Ruby\u0026logoColor=red)](#)\n\n```sh\nirb\nnome = \"isaac\"\nnome.object_id\noutra_variável = \"outro_nome\"\noutra_variável.object_id\noutro_nome = nome\nnome\noutro_nome\nnome.object_id\noutro_nome.object_id\nnome.upcase\nnome\nnome.upcase!\nnome\noutro_nome\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\n=\u003e \"isaac\"\n=\u003e 180\n=\u003e \"outro_nome\"\n=\u003e 200\n=\u003e \"isaac\"\n=\u003e \"isaac\"\n=\u003e \"isaac\"\n=\u003e 180\n=\u003e 180\n=\u003e \"ISAAC\"\n=\u003e \"isaac\"\n=\u003e \"ISAAC\"\n=\u003e \"ISAAC\"\n=\u003e \"ISAAC\"\n\u003c/pre\u003e\n\n## Métodos e atributos para as instâncias de um objeto\nFoi feita uma **classe** chamada `NomeDaClasse`, porém essa está em branco (BLANK).\n\n### Sintaxe de uma classe em Ruby\n\n```ruby\nclass NomeDaClasse\nend\n```\n\nVamos criar um comportamento pra ela:\n\n```ruby\nclass NomeDaClasse\n  def imprimir_ola(nome)\n    puts \"Olá #{nome}\"\n  end\nend\n\nobjeto = NomeDaClasse.new # instância para o objeto NomeDaClasse\nobjeto.imprimir_ola(\"isaac\")\n```\n\nCujo o **método** (verbo) é `imprimir_ola` com um **argumento** (parâmetro) que se chama `nome`. \n\n\u003e Portanto, estamos instanciando essa classe (cujo é o esboço do objeto) com a instância de classe `.new`, e assim criando esse objeto chamado `NomeDaClasse`.\n\nNa última linha, estamos imprimindo o nome desse objeto com o argumento `\"isaac\"`.\n\n```ruby\nclass NomeDaClasse\n  def imprimir_ola(nome)\n    @nome = nome\n    puts \"Olá #{@nome}\"\n  end\nend\n```\n\nO diferencial dessa estrutura é o `@nome`, isso, pois a nossa variável `nome` irá ficar disponível durante todo o ciclo de vida enquanto estiver na memória. Só que não podemos acessar essa variável antes da classe. \n\n\u003e Nós somente podemos corrigir essa variável dentro da classe.\n\nSe eu criar outro método, chamado `imprimir_tchau()`, logo eu não preciso receber como argumento mais, pois eu consigo pegar essa variável `nome` que está dentro do objeto. Então, a gente cria um método e essa variável retorna pra gente no mundo exterior.\n\n\u003e Na parte de `Olá #{@nome}` o `Olá #` não será exibido na saída do código, apena o `@nome`.\n\n```ruby\nclass NomeDaClasse\n  def imprimir_ola(nome)\n    @nome = nome\n    puts \"Olá #{@nome}\"\n  end\n  \n  def nome\n    @nome\n  end\nend\n\nisaac = NomeDaClasse.new\nisaac.imprimir_ola(\"isaac\")\nisaac.nome\n```\n\nQuando o **método é público** a gente só pega e delega a palavra, ou seja, esse método só vai retornar a palavra de instância. Portanto, essa variável vai ficar disponível durante todo o ciclo de vida do objeto na memória e possuímos um método que retorna essa variável.\n\n[![.RB](https://img.shields.io/badge/hello_world.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass NomeDaClasse\n  def initialize(nome)\n    @nome = nome\n  end\n  \n  def imprimir_ola(nome)\n    puts \"Olá #{@nome}\"\n  end\n  \n  def nome\n    @nome\n  end\nend\n\npessoa = NomeDaClasse.new(\"isaac\")\npessoa.nome = \"Foo\"\npessoa.nome\n```\n\nNo entanto, somente estamos imprimindo o nome no `imprimir_ola`, então para a gente alterar o nome, precisamos `imprimir_ola` novamente. Então, eu quero passar o **estado inicial** para o **método inicial** e a partir desse conceito entra o **método construtor**. Em Ruby, o método construtor se chama `initialize`, então para inicializar um método, você precisa utiliza-lo e passamos o `@nome` como argumento.\n\nPodemos criar um objeto a partir da classe, no nosso `initialize` podemos usar o `nome` como parâmetro. Então, no nosso `new` devemos passar um nome, então nas 3 últimas linhas, estamos criando um **objeto** `pessoa` e passo o nome `\"isaac\"`, então essa variável vai ser inserida no `@nome` e quando eu quiser o `nome`.\n\nEntretanto, e se eu quiser alterar o nome dessa variável? Eu posso criar um método que altera o nome dessa variável.\n\n[![.RB](https://img.shields.io/badge/hello_world.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass NomeDaClasse\n  def initialize(nome)\n    @nome = nome\n  end\n  \n  def imprimir_ola(nome)\n    puts \"Olá #{@nome}\"\n  end\n  \n  def nome # retorna a variável de instância\n    @nome\n  end\n  \n  def nome=(novo_nome) # troca o valor da instância\n    @nome = novo_nome\n  end\nend\n\npessoa = NomeDaClasse.new(\"isaac\")\npessoa.nome = \"Foo\"\npessoa.nome\n```\n\n### Getters e Setters em Ruby\nPara **getters** e **setters** em Ruby, utilizamos o método `attr_accessor` para uma variável `:nome`. Dessa forma, faz o objeto se comportar da mesma forma como anteriormente, ou seja, a gente cria um objeto e a gente troca esse objeto com o atributo (variável) `:nome` e a gente retorna esse objeto.\n\n[![.RB](https://img.shields.io/badge/exemplo.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass NomeDaClasse\n  attr_accessor  :nome # getter e setter\n  # attr_reader  :nome # apenas getter\n  # attr_writter :nome # apenas setter\n  \n  def initialize(nome)\n    @nome = nome\n  end\n  \n  def imprimir_ola(nome)\n    puts \"Olá #{@nome}\"\n  end\nend\n\npessoa = NomeDaClasse.new(\"isaac\")\npessoa.nome = Foo\npessoa.nome\n```\n\nSe for o caso de criar **somente um getter** podemos usar o `attr_reader` e se for o caso de **apenas um setter** podemos usar o `att_writter`.\n\n## Colocando a mão na massa em Poo Ruby\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n  def initialize(nome)\n    @nome = nome\n  end\nend\n\npessoa = Pessoa.new(\"isaac\")\np pessoa\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_Pessoa.rb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n```\n#\u003cPessoa:0x000000000304c2e0 @nome=\"isaac\"\u003e\n```\n\n\u003e Analisando o código com o método `p`, esse método retorna a inspeção do método `pessoa`, ou seja, daria o mesmo resultado se fizessemos da seguinte forma:\n\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n  def initialize(nome)\n    @nome = nome\n  end\nend\n\npessoa = Pessoa.new(\"isaac\")\np pessoa.inspect # o inspect é um parâmetro de inspeção cujo podemos ver todas as variáveis na memória do objeto, que no caso é @nome=\"isaac\"\n```\n\nE se fizermos outro objeto para uma nova pessoa?\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n    def initialize(nome)\n      @nome = nome\n    end\nend\n\npessoa = Pessoa.new(\"isaac\")\npessoa2 = Pessoa.new(\"matheus\")\n\np pessoa, pessoa2\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_Pessoa.rb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n```sh\n#\u003cPessoa:0x000000000313c2b8 @nome=\"isaac\"\u003e\n#\u003cPessoa:0x000000000313c268 @nome=\"matheus\"\u003e\n```\n\nEntão, todo objeto tem a sua entidade na memória e cada um tem um nome diferente.\n\nEm seguida, criamos um método chamado `imprimir_ola`:\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n    def initialize(nome)\n      @nome = nome\n    end\n    \n    def imprimir_ola\n      puts \"Olá, #{@nome}\"\n    end\nend\n\npessoa = Pessoa.new(\"isaac\")\npessoa2 = Pessoa.new(\"matheus\")\n\npessoa.imprimir_ola\npessoa2.imprimir_ola\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_Pessoa.rb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nOlá, isaac\nOlá, matheus\n\u003c/pre\u003e\n\nE se eu colocar um novo nome:\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n    def initialize(nome)\n      @nome = nome\n    end\n    \n    def imprimir_ola\n      puts \"Olá, #{@nome}\"\n    end\n    \n    def nome(novo_nome)\n      @nome = novo_nome\n    end\nend\n\npessoa = Pessoa.new(\"isaac\")\npessoa.imprimir_ola\n\npessoa.nome('Foo')\npessoa.imprimir_ola\n```\n\n\u003e Dessa forma, podemos trocar os valores de objetos no Ruby.\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_Pessoa.rb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nOlá, isaac\nOlá, Foo\n\u003c/pre\u003e\n\nPodemos também fazer o mesmo com uma linha só utilizando _getters_ e _setters_:\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n    attr_writer :nome\n    \n    def initialize(nome)\n      @nome = nome\n    end\n    \n    def imprimir_ola\n      puts \"Olá, #{@nome}\"\n    end\nend\n\npessoa = Pessoa.new(\"isaac\")\npessoa.imprimir_ola\n\npessoa.nome='Foo'\npessoa.imprimir_ola\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_Pessoa.rb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nOlá, isaac\nOlá, Foo\n\u003c/pre\u003e\n\nPodemos fazer o Poo Ruby também com o `irb`:\n\n[![irb](https://img.shields.io/badge/irb-fff?style=social\u0026logo=Ruby\u0026logoColor=red)](#)\n\n```sh\nirb\nclass MinhaClasse\n  def initialize(nome)\n    @nome = nome\n  end\nend\n\nobjeto = MinhaClasse.new(\"isaac\")\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_irb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=red)](#)\n\n```\n:initialize\n=\u003e #\u003cMinhaClasse:0x000000000351e020 @nome=\"isaac\"\u003e\n```\n\nPodemos pegar a variável de instância pelo `irb`, da seguinte forma:\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_irb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=red)](#)\n\n```\nobjeto.instance_variable_get(:@nome)\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_irb-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=red)](#)\n\n```\n=\u003e \"isaac\" \n```\n\n## Importando outros arquivos\nImagine a seguinte estrutura de diretórios:\n\n\u003cpre\u003e\n├── classes\n|   ├── carro.rb\n|   └── pessoa.rb\n└── principal.rb\n\u003c/pre\u003e\n\nNa seguinte hierarquia, possuimos o nosso código principal, onde chamará as suas classes pelos arquivos localizados na pasta chamada `classes`.\n\n[![.RB](https://img.shields.io/badge/classes/pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\n# arquivo: classes/pessoa.rb\nclass Pessoa\n  def initialize(nome)\n    @nome = nome\n  end\nend\n```\n\n[![.RB](https://img.shields.io/badge/classes/carro.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\n# arquivo: classes/carro.rb\nclass Carro\n  def initialize(modelo,dono)\n    @modelo = modelo\n    @dono = dono\n  end\nend\n```\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\n# arquivo: principal.rb\n\nrequire \"./classes/pessoa\"\nrequire \"./classes/carro\"\n\nfoo = Pessoa.new(\"Foo\")\ncarro = Carro.new(\"carro\", foo)\n```\n\nChamamos outro arquivo ruby pelo método de importação `require` juntamente com o caminho do diretório.\n\nAgora, vamos instalar uma biblioteca do Ruby chamada `awesome_print`.\n\n[![RubyGems](https://img.shields.io/badge/-gem_install-fff?style=social\u0026logo=RubyGems\u0026logoColor=E9573F)](#)\n\n```sh\ngem install awesome_print\n```\n\nDepois que instalamos essa biblioteca, também devemos importá-la no arquivo utilizando o `require`.\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\n# arquivo: principal.rb\n\nrequire \"awesome_print\" # importando a biblioteca\nrequire \"./classes/pessoa\"\nrequire \"./classes/carro\"\n\nfoo = Pessoa.new(\"Foo\")\ncarro = Carro.new(\"carro\", foo)\n\nap foo # método da biblioteca importada\n```\n\n## Herança\nO conceito de herança é quando uma classe precisa herdar as funcionalidades de outra classe.\n\n![Herança (Poo Ruby)](https://user-images.githubusercontent.com/61624336/174844671-6f1021e0-c634-4d29-8efe-46d04b5c315d.png)\n\nEm Ruby, o conceito de herança **somente pode uma classe herdar de uma outra classe**, portanto, **heranças múltiplas não serão permitidas**, como é o caso das outras linguagens de programação. \n\n\u003e **Exemplo**: A **classe Filho** herda os comportamentos da **classe Pai**.\n\n![Exemplo de Herança (Poo Ruby)](https://user-images.githubusercontent.com/61624336/174856317-51a70fda-2f7d-4464-8008-c6059c175d76.png)\n\nOutro exemplo é a **classe Cachorro** herdar o comportamento da **classe Animal**, o comportamento no caso é o método, como por exemplo: `Respirar()`, então isso será passado para a _classe Cachorro_.\n\n![Herança com Object (Poo Ruby)](https://user-images.githubusercontent.com/61624336/174901912-45bd9892-6ee7-4e8d-acc9-cb367991f35b.png)\n\nSe a gente não especifica qual a classe a gente deve herdar, essa classe herdará da **classe object** (não confunda com o objeto) que é uma classe trazida pelo próprio Ruby.\n\nQuando chamamos um método, o Ruby vai avisar se esse método existe na classe do objeto, senão ele começa a analisar a hierarquia de classes procurando um método com aquele nome, senão ele vai avisar que esse método não existe.\n\nExemplo:\n\n[![.RB](https://img.shields.io/badge/Sensor.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Sensor\n  def iniciar\n    # iniciar o sensor\n  end\n  \n  def coletar\n    # fazer uma coleta genérica\n  end\nend\n\nclass SensorSolo \u003c Sensor\n  def coletar\n    # coletar métricas no solo\n  end\nend\n\nclass SensorTemperatura \u003c Sensor\n  def coletar\n    # coletar métricas de temperatura\n  end\nend\n```\n\n\u003e Podemos também fazer o mesmo em arquivos separados e importando a `classe Sensor` para cada um deles, onde o arquivo principal conterá toda a manipulação dessas classes dos sensores.\n\n\u003e Você pode utilizar também um método que foi sobrescrito na super classe base chamada `super`. Então, vamos supor que você escreve todo o comportamento para o sensor genérico, então ele irá fazer umas coisas antes que o sensor de solo irá coletar e fazer isso em passos (passo 1, passo 2 e passo 3, cujo o passo 3 é o sensor regular, onde será chamado o `super`). \n\n[![.RB](https://img.shields.io/badge/Sensor.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nsuper # executa o método sobrescrito da super classe\n```\n\n\u003e Herança é para **reuso** de funcionalidades.\n\nExemplo em somente um arquivo com todas as classes: \n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Sensor\n  def instalar\n    # instala o sensor\n    puts \"Sensor instalado\"\n  end\n  \n  def iniciar\n    # inicia o sensor\n    puts \"Sensor iniciado\"\n  end\n    \n  def coletar_metricas\n    # coleta as métricas\n    puts \"Métricas analisadas e coletadas\"\n    puts \"Métricas analisadas e coletadas novamente\"\n  end\n  \nend\n\nclass SensorTemperatura \u003c Sensor\n  # Sem nada dentro pode inicializar o SensorTemperatura herdando todos os métodos da classe Sensor\n  # Com algo dentro, podemos fazer algo mais exótico, como abaixo:\n \n  def coletar_metricas\n  # inicializar componentes de temperatura\n    puts \"Métricas de temperatura coletadas\"\n    super # Logo, ao rodar a aplicação ela irá rodar a mensagem acima na impressão de sensor.coletar_metricas primeiro e posteriormente os da classe Sensor\n  end\n  \n  # Logo, ao rodar a aplicação ela irá rodar a mensagem acima na impressão de sensor.coletar_metricas\nend\n\nsensor = SensorTemperatura.new # Sensor.new # Sensor.new = imprimir apenas os métodos da classe Sensor\nsensor.instalar\nsensor.iniciar\nsensor.coletar_metricas\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:_principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nSensor instalado\nSensor iniciado\nMétricas de temperatura coletadas\nMétricas analisadas e coletadas\nMétricas analisadas e coletadas novamente\n\u003c/pre\u003e\n\n## Métodos e atributos de classe\n\nAté então foram feitos métodos de classe como `Pessoa.new` que gerava uma nova classe a ser usada, mas também podemos definir as nossas próprias classes e esses métodos são chamados na classe, bem diferente daqueles que eram instâncias da classe para criação de um objeto específico.\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nPessoa.gerar\n```\n\n\u003e Os métodos de classe são úteis quando possuímos uma funcionalidade que não é tão dependente do estado do objeto.\n\n### Sintaxe dos métodos de classe\nPara definirmos os métodos de classe basta somente inserir o prefixo `self.nome_do_método`, isso é claro depois de ser inserido o `def` da função do nosso método. \n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n  def self.gerar\n    puts \"Estou gerando uma nova pessoa partir do método de classe\"\n  end\nend\n```\n\n\u003e Com isso, esse _método de classe_ vai se tornar disponível **apenas para a classe** e não para as instâncias do objeto. Se você tentar executar esse método de classe em um objeto vai ocorrer um erro. Os métodos de classe não usam o estado inicial de um objeto, mas você pode abordar um estado se você quiser. \n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n  @@variavel_da_classe_pessoa = 100\n  \n  def self.valor_da_variável\n    @@variavel_da_classe_pessoa\n  end\n  \n  def self.incrementar_valor_variavel\n    @@variavel_da_classe_pessoa += 1\n  end\nend\n```\n\n\u003e Quando definimos `@@` estamos definindo variáveis (atributos) de classe e os métodos definidos com `self` conseguem acessar e gravar nessas variáveis, onde possuímos dois métodos, cujo o primeiro funciona como um _getter_ e o outro é um _incremento_ dessa variável.\n\n[![.RB](https://img.shields.io/badge/Pessoa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass Pessoa\n  @@numero_de_pessoas = 0\n  \n  def self.gerar\n    @@numero_de_pessoas += 1\n    puts \"vou fazer antes\"\n    Pessoa.new\n  end\nend\n\npessoa = Pessoa.new # instânciando o objeto Pessoa\npessoa = Pessoa.gerar # instânciando a classe com o método de classe gerar\n\np pessoa \n```\n\n## Visibilidade dos métodos\nAté agora, todos os métodos que utilizamos na classe são públicos, porque é o padrão, isso quer dizer que eles são acessíveis em qualquer outro lugar no nosso código.\n\n[![.RB](https://img.shields.io/badge/MinhaClasse.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass MinhaClasse\n  def m1\n    puts \"Método 1\"\n    m2\n    m3\n  end\n  \n  def m2\n    puts \"Método 2\"\n  end\n  \n  def m3\n    puts \"Método 3\"\n  end\nend\n```\n\n\u003e O método `m1` imprime: `Método 1`, `m2` e `m3`. Portanto, esses métodos são públicos.\n\nVamos supor que não queremos o `m2` e o `m3` acessíveis a qualquer método, então podemos deixar eles `private` (privado). Para isso basta inseri-lo da seguinte forma:\n\n[![.RB](https://img.shields.io/badge/MinhaClasse.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass MinhaClasse\n  def m1\n    puts \"Método 1\"\n    m2\n    m3\n  end\n  \n  private\n  \n  def m2\n    puts \"Método 2\"\n  end\n  \n  def m3\n    puts \"Método 3\"\n  end\nend\n```\n\n\u003e Tudo abaixo da palavra `private` fica privado, portanto o `m2` e o `m3` estão privados.\n\nOs métodos privados podem também serem chamados por uma subclasse.\n\n[![.RB](https://img.shields.io/badge/MinhaSubClasse.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass MinhaSubClasse \u003c MinhaClasse\n  def m4\n    puts \"Método m4 - subclass\"\n    m3\n  end\nend\n```\n\nExistem 3 tipos de acessibilidade de métodos no Ruby:\n- `public` (padrão) podem ser acessados por qualquer método em qualquer objeto.\n- `private` só podem ser chamados dentro de sua própria instância. Não é possível acessar Métodos privados de outras instâncias, apenas pode ser chamada por uma subclasse.\n- `protected` podem ser chamados por qualquer instância se for da mesma Classe/SuperClasse.\n\n\u003e Somente os métodos públicos podem ser ações para os controllers!\n\nVamos testar esses modos de acessibilidade de métodos!\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n\u003e Todos os métodos ficaram públicos.\n\n```ruby\nclass MinhaClasse\n  def m1\n    puts \"Método 1\"\n    m2\n    m3\n  end\n  \n  def m2\n    puts \"Método 2\"\n  end\n  \n  def m3\n    puts \"Método 3\"\n  end\nend\n\n### a partir daqui, é um outro contexto\n\nobj = MinhaClasse.new\nobj.m1\nobj.m2\nobj.m3\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nMétodo 1\nMétodo 2\nMétodo 3\n\u003c/pre\u003e\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n\u003e Todos os métodos ficaram privados.\n\n```ruby\nclass MinhaClasse\n\n  private \n  \n  def m1\n    puts \"Método 1\"\n    m2\n    m3\n  end\n  \n  def m2\n    puts \"Método 2\"\n  end\n  \n  def m3\n    puts \"Método 3\"\n  end\nend\n\n### a partir daqui, é um outro contexto\n\nobj = MinhaClasse.new\nobj.m1\nobj.m2\nobj.m3\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nc:/Users/ipinheiro/Desktop/MinhaClasse.rb:23:in `\u003cmain\u003e': private method `m1' called for \n#\u003cMinhaClasse:0x00000000030e2998\u003e (NoMethodError)\n\u003c/pre\u003e\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n\u003e Como privatizar um método específico: `m1` será o único método privado da Classe.\n\n```ruby\nclass MinhaClasse\n  \n  private def m1\n    puts \"Método 1\"\n    m2\n    m3\n  end\n  \n  def m2\n    puts \"Método 2\"\n  end\n  \n  def m3\n    puts \"Método 3\"\n  end\n  \nend\n\n### a partir daqui, é um outro contexto\n\nobj = MinhaClasse.new\nobj.m1\nobj.m2\nobj.m3\n```\n\n\u003e Todavia, na saída do código, o `m1` será o primeiro a ser executado, gerando a finalização dele por ser privado.\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nc:/Users/ipinheiro/Desktop/MinhaClasse.rb:23:in `\u003cmain\u003e': private method `m1' called for \n#\u003cMinhaClasse:0x00000000030e2998\u003e (NoMethodError)\n\u003c/pre\u003e\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n\u003e A diferença entre o `private` e o `protected`, o `protected` não funciona inline com o método e, além disso, o `protected` serve para poder chamar outros métodos dentro de outros objetos, diferente do `private` que é para privatizar o nosso objeto principal.\n\n```ruby\nclass MinhaClasse  \n  def m1\n    puts \"Método 1\"\n    m2\n    m3\n  end\n  \n  private\n  \n  def m2\n    puts \"Método 2\"\n  end\n  \n  def m3\n    puts \"Método 3 privado\"\n  end\n  \n  protected # Tudo aqui em baixo é PROTECTED!\n  \n  def m5\n    puts \"Método 5\"\n  end\nend\n\nclass MinhaSubClasse \u003c MinhaClasse\n  def m4\n    m3\n    outro_obj = MinhaClasse.new\n    puts \"Método 4\"\n    outro_obj.m5\n  end\nend\n\n### a partir daqui, é um outro contexto\n\nobj = MinhaSubClasse.new\nobj.m4\nobj.m5\n```\n\n[![.RB](https://img.shields.io/badge/(OUTPUT)_Saída:-fff?style=social\u0026logo=GNU-Bash\u0026logoColor=990000)](#)\n\n\u003cpre\u003e\nc:/Users/ipinheiro/Desktop/MinhaClasse.rb:38:in `\u003cmain\u003e': protected method `m5' called for \n#\u003cMinhaSubClasse:0x0000000002f0bf70\u003e (NoMethodError)\nMétodo 3 privado\nMétodo 4\nMétodo 5\n\u003c/pre\u003e\n\n[![irb](https://img.shields.io/badge/irb-fff?style=social\u0026logo=Ruby\u0026logoColor=red)](#)\n\n\u003e No Ruby, possuímos algumas propriedades que podem acessar os métodos privados, como por exemplo o método `send(:método da classe)`. \n\n```ruby\nirb\nclass Pessoa\n  private def falar\n    puts \"Estou falando\"\n  end\nend\npessoa = Pessoa.new\npessoa.send(:falar)\n```\n\n## Exercício 02: Conta bancária\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/325/bank_1f3e6.png\" height=\"177\"\u003e\u003c/div\u003e\n\n### Desafio:\n- Criar uma classe responsável para representar Contas Bancárias.\n- Criar um método que me permita transferir valor entre contas usando: \"conta1.transferir(conta2,100)\" onde 100 é o valor que eu desejo transferir.\n- Plus: Criar um tipo de conta em que existe uma tarifa para se transferir dinheiro\n\n### Solução:\n\n**Estrutura de arquivos**\n\n\u003cpre\u003e\n├── classes\n|   └── conta_bancaria.rb\n└── principal.rb\n\u003c/pre\u003e\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\n# principal.rb\n\nrequire \"./classes/conta_bancaria\"\n\nconta_cadu = ContaBancaria.new(\"cadu\", 100)\nconta_pessoa2 = ContaBancaria.new(\"pessoa2\", 200)\n\nconta_cadu.transferir(conta_pessoa2, 50)\n\np \"Conta Cadu\"\np conta_cadu.saldo # 50\n\np \"Conta Pessoa 2\"\np conta_cadu.saldo # 250\n\n# caso de teste de conta sem saldo\n\nconta_cadu.transferir(conta_pessoa2, 60) # falhar\n\np \"Conta Cadu\"\np conta_cadu.saldo # 50\n\np \"Conta Pessoa 2\"\np conta_pessoa2.saldo # 250\n```\n\n[![.RB](https://img.shields.io/badge/classes/conta_bancaria.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nclass ContaBancaria\n  def initialize(proprietario, valor_inicial)\n    @proprietario = proprietario\n    @valor        = valor_inicial\n  end\n  \n  def transferir(outra_conta, valor)\n    # logica de transferência\n    if saldo \u003e= valor\n      # consigo\n      debitar(valor)\n      outra_conta.depositar(valor)\n    else\n      # não consigo (não faço nada)\n      raise \"Não consegui transferir! Saldo insuficiente.\"\n    end\n  end\n  \n  def saldo\n    @valor\n  end\n  \n  private \n  \n  def debitar(valor_para_debitar)\n    @valor -= valor\n    @valor = valor_para_debitar\n  end\n  \n  protected\n  \n  def depositar(valor_para_depositar)\n    @valor += valor_para_depositar\n  end\n  \nend\n```\n\n### Plus: Taxa na transferência\n\n**Estrutura de arquivos**\n\n\u003cpre\u003e\n├── classes\n|   ├── \u003cb\u003econta_com_taxa.rb\u003c/b\u003e\n|   └── conta_bancaria.rb\n└── principal.rb\n\u003c/pre\u003e\n\n[![.RB](https://img.shields.io/badge/classes/conta_com_taxa.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\n# conta_com_taxa.rb\n\nclass ContaComTaxa \u003c ContaBancaria\n   def transferir(outra_conta, valor)\n     if saldo \u003e= valor\n       debitar(2)\n       super\n     end\n   end\nend\n```\n\n[![.RB](https://img.shields.io/badge/principal.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\n# principal.rb\n\nrequire \"./classes/conta_bancaria\"\nrequire \"./classes/conta_com_taxa\"\n\nconta_cadu = ContaComTaxa.new(\"cadu\", 100)\nconta_pessoa2 = ContaBancaria.new(\"pessoa2\", 200)\n\nconta_cadu.transferir(conta_pessoa2, 50)\n\np \"Conta Cadu\"\np conta_cadu.saldo # 50\n\np \"Conta Pessoa 2\"\np conta_cadu.saldo # 250\n\n# caso de teste de conta sem saldo\nbegin \n  conta_cadu.transferir()\n\n\nconta_cadu.transferir(conta_pessoa2, 60) # falhar\n\n# o codigo abaixo não foi executado, pois a linha acima gerou um erro.\n\np \"Conta Cadu\"\np conta_cadu.saldo # 50\n\np \"Conta Pessoa 2\"\np conta_pessoa2.saldo # 250\n```\n\n# 🛤️ RoR - RubyOnRails\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/6/62/Ruby_On_Rails_Logo.svg\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n\nO **Rails** é um framework/biblioteca para fazer aplicações web escritas na linguagem Ruby, ele foi criado em 2004 por David Heinemeier Hanson (DHH) e foi extraído pelo software **Basecamp**, da empresa do DHH, cujo era um software de gerenciamento de tarefas.\n\n\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/c/c3/Ruby_on_Rails_logo.svg\" height=\"177\" align=\"right\"\u003e\n\nA biblioteca **Rails** trabalha mais especificamente com um padrão de arquitetura de software chamado MVC (Model View Controller) que separa a representação da informação da interação do usuário.\n\nExistem várias maneiras de instalar o Rails, a mais famosa consiste na instalação a partir da `gem` oficial liberada pelo RubyGems.\n\n```sh\ngem install rails\n```\n\nO comando abaixo mostra as seguintes opções que temos para criar um projeto RubyOnRails:\n\n```sh\nrails new -h\n```\n\nLogo, podemos criar o nosso primeiro projeto utilizando o Rails:\n\n```sh\nrails new meu_projeto\n```\n\nApós isso, vai ser criado o seguinte diretório do projeto com os seguintes arquivos:\n\n\u003cpre\u003e\n/meu_projeto\n├── \u003cb\u003eapp\u003c/b\u003e\n│   ├── assets\n│   │   ├── config\n│   │   ├── images\n│   │   └── stylesheets\n│   ├── channels\n│   ├── controllers\n│   └── views\n├── \u003cb\u003ebin\u003c/b\u003e\n├── \u003cb\u003econfig\u003c/b\u003e\n├── \u003cb\u003edb\u003c/b\u003e\n|   ├── \n│   └── seeds.rb\n├── \u003cb\u003elib\u003c/b\u003e\n│   ├── assets\n│   └── tasks\n├── \u003cb\u003elog\u003c/b\u003e\n│   ├── .keep\n│   └── development.log\n├── \u003cb\u003epublic\u003c/b\u003e\n├── \u003cb\u003estorage\u003c/b\u003e\n├── \u003cb\u003etest\u003c/b\u003e\n├── \u003cb\u003etmp\u003c/b\u003e\n├── \u003cb\u003evendor\u003c/b\u003e\n│   ├── javascript\n|   |   └── .keep\n│   └── .keep\n├── \u003cb\u003e.gitattributes\u003c/b\u003e\n├── \u003cb\u003e.gitattributes\u003c/b\u003e\n├── \u003cb\u003e.gitignore\u003c/b\u003e\n├── \u003cb\u003e.ruby.version\u003c/b\u003e\n├── \u003cb\u003econfig.ru\u003c/b\u003e\n├── \u003cb\u003eGemfile\u003c/b\u003e\n├── \u003cb\u003eGemfile.lock\u003c/b\u003e\n├── \u003cb\u003eRakefile\u003c/b\u003e\n└── \u003cb\u003eREADME.md\u003c/b\u003e\n\u003c/pre\u003e\n\nO **Gemfile** é um arquivo onde instalamos todas as gems que iremos usar no projeto, se você for incluir alguma, é só copiar e colar o nome e a versão da gem, disponibilizada no RubyGems, no arquivo e após salvá-lo basta somente rodar o comando `bundle install` que ele irá instalar essa nova gem.\n\nJá o arquivo **Gemfile.lock** é um arquivo que nem deve ser alterado, pois é gerado após a instalação do bundle.\n\n\u003e **O Gemfile** é similar ao **package.json**.\n\nResumidamente, o conjunto de comandos para iniciar uma aplicação em RubyOnRails é:\n\n```sh\n# rails new -h\nrails new meu_projeto\ncd meu_projeto\nbundle install\n# bundle update\nrails server # rails s\n```\n\n## SQLite\n\u003cdiv align=\"center\"\u003e\u003ca href=\"https://github.com/IsaacAlves7/ruby-programming\"\u003e\u003cimg src=\"https://cdn.worldvectorlogo.com/logos/sqlite.svg\" height=\"177\"\u003e\u003c/a\u003e\u003c/div\u003e\u003cbr \\\u003e\n\nO banco de dados padrão para o desenvolvimento em Rails é o SQLite. No entanto, geralmente, em alguns ambientes esse banco funciona apenas para a etapa de desenvolvimento e testes, não servindo para produção. Portanto, utilize outro banco de dados para produção como o MySQL ou PostgreSQL.\n\nO comando abaixo permite você definir, no início do seu projeto, o banco de dados necessário:\n\n```sh\nrails new meu_projeto -d postgresql\n```\n\n\u003e Caso se não for especificado, você irá utilizar o SQLite.\n\nVocê pode editar essas configurações instalando uma gem e configurando em `config/database.yml`. E, também vale ressaltar, que ao criar e migrar o banco de dados do PostgreSQL, o arquivo do banco de dados não irá aparecer no diretório `db`, como é o caso do SQLite. Então é necessário a instalação do banco de dados PostgreSQL (com acesso ao pgAdmin ou psql). \n\nCom isso, a sua aplicação RoR irá se conectar ao banco de dados do PostgreSQL no endereço: `http://localhost:5432`\n\n\u003e Além disso, você pode consultar os dados pelo console do Rails ou pelo próprio banco utilizando uma ferramenta como o **DBeaver**, na qual é só definir o caminho do banco de dados e gerenciar o banco de dados pela ferramenta.\n\n## Criando um CRUD com scaffold\n\u003cimg src=\"https://user-images.githubusercontent.com/61624336/178826186-57a9bd56-5e14-4abf-9472-1c57848e2784.png\" height=\"377\" align=\"right\"\u003e\n\nCom o projeto criado, projeto `mvc_test`, iremos utilizar o `scaffold` (traduzido no inglês como \"andaime\"), ele é uma extensão do Rails que permite criar um CRUD rapidamente somente a partir dos comandos de declaração do Model.\n\n```sh\nrails g scaffold User name:string email:string\n```\n\nO comando acima serve para gerar (`g` = `generate`) um `scaffold` com `User` onde `name` e `email` recebem o valor `string`.\n\n\u003e A partir da versão 5 do Rails não é preciso inserir o tipo `string`. Portanto o comando ficará dessa forma: `rails g scaffold User name email`\n\n### Comando para desfazer o CRUD\nO comando abaixo serve para excluir as tabelas criadas para fazer o CRUD, com isso o CRUD será desfeito.\n\n```sh\nrails db:rollback\n```\n\n### Comando para deletar o scaffold\nO comando abaixo deleta tudo relacionado ao scaffold criado.\n\n```sh\nrails d scaffold Product\n```\n\n### Criando um banco de dados e migrando para o banco\n\nApós o diretório da aplicação Rails funcionar, no diretório `./db/` foi criado uma pasta `./migrate/` onde possui um model para a criação da tabela proposta.\n\n```sh\nrails db:migrate db:create\n```\n\nPortanto, rodar o comando acima: `rails db:create` irá instanciar a ação do model em criar um banco de dados e o outro comando: `db:migrate` para criação daquela tabela.\n\n## Criando um CRUD sem scaffold\n\n### Controller\nUm **controller** é simplesmente uma classe que é definida para herdar do `ApplicationController`. É dentro dessa classe que você vai definir as ações por este controller. Aquelas ações vão performar as operações do CRUD nos posts.\n\n### Gerando um model com Rails\n```sh\nrails generate model Post title:string body:text\n```\n\n\u003e Dessa forma, ele vai gerar um model com título e corpo automaticamente, sem precisarmos escrever isso no código.\n\n### Criando as tabelas no banco de dados com o Rails\n```sh\nrails db:migrate\n```\n\nDessa forma, serão criadas as tabelas no banco de dados juntamente com os models e uma pasta chamada **migrate** onde está o model de criação da tabela, como mostrado abaixo:\n\n```ruby\nclass CreatePosts \u003c ActiveRecord::Migration[7.0]\n  def change\n    create_table :posts do |t|\n      t.string :title, null: false\n      t.text :body, null: false\n\n      t.timestamps\n    end\n  end\nend\n```\n\n\u003e O comando `null: false` significa que o dado não será aceito ser ele conter o valor `null` (nulo).\n\n### Comando para acessar o console do Rails\n\n```sh\nrails console\n```\n\nVamos dizer que eu queira acessar a classe Posts:\n\n\u003cpre\u003e\nirb(main):003:0\u003e Post\n=\u003e Post (call 'Post.connection' to establish a connection)\nirb(main):004:0\u003e\n\u003c/pre\u003e\n\nPara contar quantos posts tem na tabela:\n\n\u003cpre\u003e\nirb(main):004:0\u003e Post.count()\n   (2.4ms)  SELECT sqlite_version(*)\n  Post Count (0.3ms)  SELECT COUNT(*) FROM \"posts\"\n=\u003e 0\nirb(main):005:0\u003e\n\u003c/pre\u003e\n\nPara criar um post na tabela diretamente pelo console: \n\n\u003cpre\u003e\nirb(main):005:0\u003e post = Post.create(title: \"Isaac\", body: \"lindo\")\n  TRANSACTION (0.1ms)  begin transaction\n  Post Create (1.4ms)  INSERT INTO \"posts\" (\"title\", \"body\", \"created_at\", \"updated_at\") VALUES (?, ?, ?, ?)  [[\"title\", \"Isaac\"], [\"body\", \"lindo\"], [\"created_at\", \"2022-07-12 18:56:22.030795\"], [\"updated_at\", \"2022-07-12 18:56:22.030795\"]]\n  TRANSACTION (4.0ms)  commit transaction\n=\u003e \n\u003c/pre\u003e\n\nPara contar todos os itens da tabela do maior ao menor:\n\n\u003cpre\u003e\nirb(main):021:0\u003e Post.last\n  Post Load (0.3ms)  SELECT \"posts\".* FROM \"posts\" ORDER BY \"posts\".\"id\" DESC LIMIT ?  [[\"LIMIT\", 1]]\n=\u003e \n#\u003cPost:0x0000026fa3120bc8\n id: 1,\n title: \"Isaac\", \n body: \"lindo\",  \n created_at: Tue, 12 Jul 2022 18:56:22.030795000 UTC +00:00,    \n updated_at: Tue, 12 Jul 2022 18:56:22.030795000 UTC +00:00\u003e    \nirb(main):022:0\u003e\n\u003c/pre\u003e\n\nPara consultar o post:\n\n```\nirb(main):022:0\u003e post\n=\u003e\n#\u003cPost:0x0000026fa2a5bd60\n id: 1,\n title: \"Isaac\",\n body: \"lindo\",\n created_at: Tue, 12 Jul 2022 18:56:22.030795000 UTC +00:00,\n updated_at: Tue, 12 Jul 2022 18:56:22.030795000 UTC +00:00\u003e\nirb(main):023:0\u003e\n```\n\n### Definindo rotas no Rails\n\u003cimg src=\"https://user-images.githubusercontent.com/61624336/184158311-91091297-dd40-478f-8f0b-f7d3b619c224.png\" align=\"right\" height=\"377\"\u003e\n\nDepois que fizemos todo aquele processo anterior, o Rails gera todo o MVC com as rotas prontas pra criação do CRUD com o seguinte resource: `resources :users`.\n\n- Endereço para saber informações sobre as rotas da aplicação: http://localhost:3000/rails/info/routes\n\nE agora, vamos aprender a criar as nossas rotas para um projeto RoR:\n\n[![.RB](https://img.shields.io/badge/config/routes.rb-fff?style=social\u0026logo=Ruby\u0026logoColor=990000)](#)\n\n```ruby\nRails.application.routes.draw do\n  resources :users\n  \n  get 'usuarios', to: 'users#index'\n  \n  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html\n\n  # Defines the root path route (\"/\")\n  # root \"articles#index\"\nend\n```\n\nDessa forma, com o método HTTP `get` mirando em `'usuarios'`, onde `to: 'users#index'` que irá criar uma nova rota e nela conter as mesmas funcionalidades da rota `users`, o que é interessante caso o cliente queira acessar essa rota e insire errado, então ele irá acessar rota certa já que foi configurado na aplicação. \n\n# Construindo um blog com RoR\nPara mais detalhes de como inserir o bootstrap numa aplicação RoR: https://gorails.com/forum/install-bootstrap-with-webpack-with-rails-6-beta\n\n# 🐋 Deploying: Rails + PostgreSQL\n\nPara saber mais acesse: https://docs.docker.com/samples/rails/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisaacalves7%2Fruby-studies","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fisaacalves7%2Fruby-studies","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisaacalves7%2Fruby-studies/lists"}