Skip to content

💎 It's a repository of Ruby programming language and his content.

Notifications You must be signed in to change notification settings

IsaacAlves7/ruby-studies

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

It's a repository of Ruby language 💎

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

💎 Linguagem Ruby

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

.RB

class Hello
  def initialize (nome):
    @nome = nome.capitalize
  end
  
  def falar
    puts "OlĂĄ #{@nome}"
  end
 end
 
 # Criar um objeto
 h = Hello.new("mundo")
 
 # saĂ­da: "OlĂĄ, mundo!"
 g.falar

Possui uma tipagem dinùmica e forte, se assemelhando a linguagem de programação Python.

Hello, World! - Ruby

.RB

puts "Hello World!" # mais comum
puts ("Hello World!")
p "Hello, World!"
print "Hello, World!"
printf "Hello, World!"

đŸ—ƒïž Gerenciadores de versĂ”es


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

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

Existe alguns tipos de gerenciadores de versĂŁo indicados:

  • RVM (Mais popular)
  • rbenv
  • asdf (Mais recomendĂĄvel)

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

Comandos utilizados para iniciar o asdf:

asdf version
asdf plugin-add ruby
asdf install ruby 2.7.1
ruby -v
asdf list ruby
asdf local ruby 2.7.1
asdf list nodejs

📩 gem - RubyGems


SĂŁ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

Comando para listar todas as gems locais

gem list

💎 irb - Interactive Ruby


Traduzido 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).

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

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

(Input) Entrada:

irb
7.times { puts "Hello, World!" }
exit()

A saĂ­da serĂĄ o "Hello, World!" impresso 7 vezes em cada linha.

(Output) SaĂ­da:

Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!

(Input) Entrada:

nome = Isaac
nome

(Output) SaĂ­da:

Isaac

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!

(Input) Entrada:

nome = 7
nome

(Output) SaĂ­da:

7

Verificando objetos

(Input) Entrada:

nome.object_id

(Output) SaĂ­da:

21

(Input) Entrada:

nome.class

(Output) SaĂ­da:

Integer

(Input) Entrada:

nil.object_id

nil = valor nulo

(Output) SaĂ­da:

8

(Input) Entrada:

nil.class

(Output) SaĂ­da:

NilClass

(Input) Entrada:

NilClass.object_id

(Output) SaĂ­da:

40

(Input) Entrada:

NilClass.superclass

(Output) SaĂ­da:

Object

Definindo funçÔes:

(Input) Entrada:

def somar (x,y)
  puts "Outra coisa..."
  x+y
end

somar (1, 2)

(Output) SaĂ­da:

Outra coisa...
3

Atribuição de uma função

(Input) Entrada:

soma = somar (10, 5)

soma

(Output) SaĂ­da:

15

Array (Listas)

(Input) Entrada:

lista = ["Isaac", 7, "DevOps", true, nil, 7.77, "Ruby"]

lista

lista.class

lista.length

(Output) SaĂ­da:

["Isaac", 7, "DevOps", true, nil, 7.77, "Ruby"]
Array
7

Executando o Ruby pelo interpretador no terminal

(Input) Entrada:

ruby main.rb

(Output) SaĂ­da:

Hello World

💎 RSpec


Ruby + Cucumber + Capybara


💎 Paradigma de Programação Imperativo em Ruby

Executando um cĂłdigo-fonte

ComentĂĄrio

# comentĂĄrio de uma linha

Strings

São tipos de dados tratados como escrita ou texto, podem ser definidas entre aspas duplas ("") ou apóstrofos, também conhecida como aspas simples ('').

Exemplo:

nome = "Isaac"
nome = 'Isaac'
nome = %q(meu texto)

Caracteres de escape com Aspas ("")

Nova linha

\n

Tab

\t

Aspas

\"

Evento

nome = "Isaac"
mensagem = "Bem vindo #{nome}"

puts mensagem

Heredoc

mensagem = <<~TXT
  Essa Ă© minha mensagem
TXT

CĂłdigo-fonte main.rb:

nome = "Isaac"
mensagem = "Bem vindo #{nome}"
mensagemErrada = 'Bem vindo #{nome}'
soma = "O valor da soma de 1 + 2 = #{1 + 2}"
outraMensagem = "Bem vindo" + nome

puts nome
puts mensagem
puts mensagemErrada
puts soma
puts outraMensagem

#{} 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.

(Input) Entrada:

ruby main.rb

(Output) SaĂ­da:

Isaac
Bem vindo Isaac
Bem vindo #{nome}
O valor da soma de 1 + 2 = 3
Bem vindo Isaac

CĂłdigo-fonte mensagem.rb:

nome = "Isaac"
mensagem = <<-MENSAGEM
  OlĂĄ #{nome}
  
  Bem vindo(a) ao meu programa!
  
  Obrigado
MENSAGEM

puts mensagem

(Input) Entrada:

ruby mensagem.rb

(Output) SaĂ­da:

OlĂĄ Isaac

Bem vindo(a) ao meu programa!

Obrigado

CĂłdigo-fonte mensagem.rb:

mensagem = %q(Bem vindo ao meu programa)
mensagemErrada = %q(Bem vindo ao meu programa #{nome})

puts mensagem
puts mensagemErrada

(Input) Entrada:

ruby mensagem.rb

(Output) SaĂ­da:

Bem vindo ao meu programa
Bem vindo ao meu programa #{nome}

Caso queira interpolar com o delimitador de manipulação de variåvel %q, é necessårio usar o %Q.

CĂłdigo-fonte mensagem.rb:

nome = "Isaac"
mensagem = %Q(Bem vindo ao meu programa #{nome})
puts mensagem

(Input) Entrada:

ruby mensagem.rb

(Output) SaĂ­da:

Bem vindo ao meu programa Isaac

CĂłdigo-fonte public-methods.rb:

nome = "Isaac"
mensagem = %Q(Bem vindo ao meu programa #{nome})
puts mensagem.public_methods
puts mensagem

Esse comando, atributo public_methods, vai imprimir os mĂ©todos pĂșblicos do Ruby que possui nessa string para ser utilizado.

(Input) Entrada:

ruby public-methods.rb

(Output) SaĂ­da:

unicode_normalized?
encode!
unicode_normalize
ascii_only?
unicode_normalize!
to_r
to_c
encode
include?
%
*
+
unpack
unpack1
count
partition
+@
-@
<=>
<<
sum
==
===
next
=~
[]
[]=
empty?
casecmp
eql?
insert
casecmp?
match?
bytesize
match
next!
succ!
index
upto
replace
rindex
chr
clear
byteslice
getbyte
setbyte
freeze
scrub
scrub!
dump
inspect
intern
upcase
downcase
capitalize
swapcase
upcase!
undump
length
size
downcase!
succ
swapcase!
hex
capitalize!
split
chars
oct
grapheme_clusters
concat
codepoints
lines
bytes
to_str
end_with?
start_with?
reverse
reverse!
sub
to_s
to_i
to_f
rjust
center
prepend
crypt
ord
chomp
strip
to_sym
ljust
delete_prefix
delete_suffix
lstrip
gsub
scan
chomp!
sub!
gsub!
rstrip
delete_prefix!
chop
lstrip!
rstrip!
chop!
delete_suffix!
strip!
tr_s
delete
squeeze
tr!
tr
delete!
squeeze!
each_line
each_byte
tr_s!
each_codepoint
each_grapheme_cluster
slice
slice!
each_char
encoding
force_encoding
b
valid_encoding?
rpartition
hash
between?
clamp
<=
>=
<
>
singleton_class
dup
itself
taint
tainted?
untaint
untrust
untrusted?
trust
methods
singleton_methods
protected_methods
private_methods
public_methods
instance_variables
instance_variable_get
instance_variable_set
instance_variable_defined?
remove_instance_variable
instance_of?
kind_of?
is_a?
display
class
frozen?
tap
then
yield_self
public_send
extend
clone
method
public_method
singleton_method
define_singleton_method
!~
nil?
respond_to?
object_id
send
to_enum
enum_for
__send__
!
instance_eval
instance_exec
!=
equal?
__id__
Bem vindo ao meu programa Isaac

CĂłdigo-fonte mensagem.rb:

nome = "Isaac"
mensagem = %Q(Bem vindo ao meu programa #{nome})

puts "O tamanho da minha string Ă©: #{mensagem.length()}"

(Input) Entrada:

ruby mensagem.rb

(Output) SaĂ­da:

O tamanho da minha string Ă©: 30

OperaçÔes com Strings

Pegar um caracter da String

# 01234
"Isaac"[0] # "I"

Todos os caracteres da string como array

"Isaac".chars # ["I", "s", "a", "a", "c"]

Substring

"Isaac"[0,3] # "Isa"

Multiplicação de Strings

"-" * 10 #  "----------"

Multiplicação de Strings

"   mensagem   ".strip #  "mensagem"

MaiĂșsculo/MinĂșsculo

"isaac".upcase # upcase
"ISAAC".downcase # downcase

Primeira letra maĂ­uscula

"isaac".capitalize

Dividir

"cadu teste outra_nome".split
"cadu-teste-outro_nome".split("-")

Brincando com manipulação de variåveis e operaçÔes de Strings

o comando p imprime a string da sua forma natural inserida pelo programador, diferente do comando print que imprime com valor nulo.

nome = "Isaac"
nomes = "isaac matheus janaina alexandre jurema fĂĄbio cauĂŁ gabriela jade nemo marlim fanny jajĂĄ azul".split(",")
numero = 7
mensagem = "minha mensagem"

puts ["A", "B", "C"]
print ["A", "B", "C"]
p ["A", "B", "C"]
p "quebra automaticamente\"" # quebra de linha
p nome
p nome[0]
p nome[nome.length - 1]
p nome[-1]
p nome.chars
p nome.chars.length
p nome[0,3]
# multiplicação de strings
puts "Cabeçalho"
puts "---------"
puts "texto de informação"
puts "-" * 10
puts "O nĂșmero Ă© %05d" % numero
puts "*" * 10
puts mensagem.capitalize
# gsub
puts mensagem.gsub("mensagem","mulher")
p nomes

(Input) Entrada:

ruby main.rb

(Output) SaĂ­da:

A
B
C
["A", "B", "C"]["A", "B", "C"]
"quebra automaticamente\""
"Isaac"
"I"
"c"
["I","s","a","a","c"]
5
"Isa"
Cabeçalho
---------
texto de informação
---------
O nĂșmero Ă© 00007
Minha mulher

Tipos numéricos

(Input) Entrada

irb
7.class
7.7.class

(Output) SaĂ­da

Integer
Float

Int - Inteiros

(Input) Entrada

puts 123_500

(Output) SaĂ­da

123500

Float - Flutuante

(Input) Entrada

# soma um inteiro com um ponto flutuante
soma = 3 + 4.77
p soma

(Output) SaĂ­da

7.77

SĂ­mbolos

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

SĂŁo Ăłtimos substitutos para strings quando vocĂȘ for usado como label / chaves.

(Input) Entrada

irb
variavel = "isaac"
variavel.object_id
variavel = "isaac"
variavel.object_id

(Output) SaĂ­da

"isaac"
28420
"isaac"
35380

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.

(Input) Entrada

irb
:"isaac"
:isaac # posso fazer desse modo, sem especificar a string com aspas duplas
:isaac.object_id
:isaac.object_id

(Output) SaĂ­da

:isaac
:isaac
2290588
2290588

Note que ele nĂŁo muda o id do objeto, ou seja, toda vez ele vai gerar o mesmo objeto.

(Input) Entrada

irb
1.send("+", 2) # o sĂ­mbolo + estĂĄ sendo usado na memĂłria, nĂŁo reutilizada
1.send(:+, 2) # o sĂ­mbolo + estĂĄ sendo usado na memĂłria, sendo reutilizado

(Output) SaĂ­da

3
3

DicionĂĄrio

(Input) Entrada

irb
dicionario = {}
dicionario["isaac"] = "7"
dicionario["isaac"]
dicionario[:isaac] = "7"
dicionario[:isaac]

(Output) SaĂ­da

"7"
"7"
"7"
"7"

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.

Arrays (listas)

Arrays ou listas sĂŁo listas de valores separados por vĂ­rgula.

lista = []
lista = Array.new

Os arrays no Ruby, assim como na maioria das linguagens de programação de alto-nível, podem ser de diferentes tipos.

(Input) Entrada

lista = [1, 2.7, "3", "isaac", true] # elementos do tipo int, float, string e boolean (TrueClass)
lista[1] # Acessando um item da lista no Ă­ndice 1 = 2.7
p lista[1]

(Output) SaĂ­da

2.7

Incluir um novo elemento na lista

(Input) Entrada

lista = [1, 2.7, "3", "isaac", true] # elementos do tipo int, float, string e boolean (TrueClass)
lista << "novo item 1"
# ou
lista.append("novo item 2")
p lista

(Output) SaĂ­da

[1, 2.7, "3", "isaac", true, "novo item 1", "novo item 2"]

Outros métodos para manipular Arrays

lista.length # tamanho do array
lista.empty? # verifica se o array estĂĄ vazio
lista.first # pegar o primeiro valor
lista.last # pegar o Ășltimo valor
lista.include?(1) # verifica se algum item da lista inclui o valor especĂ­fico

Somando listas com o Ruby:

(Input) Entrada

lista_1 = [0, 1, 2, 3]
lista_2 = [4, 5, 6, 7]
resultado = lista_1 + lista_2
p resultado

(Output) SaĂ­da

[0, 1, 2, 3, 4, 5, 6, 7]

Hashes

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

Para iniciar um Hash

hash = {}
# ou
hash = Hash.new

Sintaxe do Hash

hash = {
  chave => valor,
  chave => valor,
}

Um hash pode ser qualquer tipo primitivo de dados, pode ser um nĂșmero, uma string ou um sĂ­mbolo.

i = {} # hash i vazio
h = {} # hash h vazio
i.class
a.class
i = { "nome" => "Isaac", "idade" => 21 } # Strings e nĂșmeros
h = { :nome => "Isaac", :idade => 21 } # SĂ­mbolos
h[:nome] # acessando um hash
h[:nome] = "Novo nome" # Alterando um hash
h[77] = "New value" # Adicionando um novo item no hash

Ao acessar o hash, note que Ă© bem parecido com array, porĂ©m nele vocĂȘ estĂĄ acessando o Ă­ndice pelo prĂłprio nome dele.

Alguns atributos e métodos para o hash

hash.keys # retorna um array com as chaves
hash.values # retorna um array com os valores
hash.empty? # verifica se o hash estĂĄ vazio

Entrada de dados

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

gets()
# ou
gets

Sintaxe

nome = gets
nome
puts nome
nome.chomp() # Tira o Ășltimo caractere social, no caso, o \n
# ou
nome = nome.chomp
# ou
nome = gets.chomp

Colocando prompt

puts "Digite o seu nome: "
nome = gets
puts "Seu nome Ă© #(nome)"

Estruturas Condicionais

Sintaxe

if condicao 
  faca_algo
else
  faca_outra_coisa
end

Operadores relacionais

== # igualdade
!= # diferente
> # maior que
>= # maior ou igual a 
< # menor que
<= # menor ou igual a 

Operadores lĂłgicos

! # Negação
&& # And
|| # Or 

Estrutura condicional com operadores relacionais

valor = 20
if valor > 50
  puts "Eu sou maior que 50"
else
  puts "Eu sou menor que 50"
end

Estrutura condicional com operadores relacionais && lĂłgicos

valor = 65
if valor >= 50 && valor <= 100
  puts "Estou entre 50 e 100"
end

Estrutura condicional com elsif (senĂŁo se)

valor = 20
if valor > 50
  puts "Eu sou maior que 50"
elsif valor == 50
  puts "Eu sou igual a 50"
else # nesse caso, o else sempre vem por Ășltimo, depois do elsif
  puts "Eu sou menor que 50"
end

Apenas nil e false sĂŁo avaliados como falso, se por acaso tiver um parĂȘnteses vazio serĂĄ do valor lĂłgico true.

Estrutura condicional com uma linha de condição

valor = 20
puts "Eu sou maior que 50" if valor > 50 

unless

Se a condição não for verdadeira, ele iå executar o bloco de código dentro dela (faca_isso).

Sintaxe:

unless condicao
  faca_isso
end

Operador ternĂĄrio

Usado para estruturas condicionais de pequeno porte.

valor > 50 ? puts "Eu sou maior que 50" : puts "Eu sou menor que 50"
# if valor > 50
#   puts "Eu sou maior que 50"
# else
#   puts "Eu sou menor que 50"

Switch case

linguagem = "ruby"
case linguagem
when "ruby"
  puts "bem vindo ao curso de ruby"
when "golang"
  puts "curso nĂŁo disponĂ­vel"
else
  puts "não conheço essa linguagem"
end

Exemplo estrutura de condicional:

Entrada (Input):

valor gets.chomp.to_i # conversor para inteiro

p valor.class # String

p valor

if valor > 20
  puts "Esse valor Ă© maior que 20"
elsif valor == 20
  puts "Esse valor Ă© igual a 20"
else
  puts "Esse valor Ă© menor que 20"
end

SaĂ­da (Output):

50
Integer
50
Esse valor Ă© maior que 20

Exemplo estrutura de condicional:

Entrada (Input):

puts "Digitar um valor: "
valor = gets.chomp.to_i

if valor >= 50 && valor <= 100
  puts "Estou entre 50 e 100"
else
  puts "Eu nĂŁo estou entre 50 e 100"
end

SaĂ­da (Output):


Exemplo 2 - estrutura de condicional:

Entrada (Input):

valor = ""
if valor 
  puts "Eu tenho alguma coisa" # true = vazio
else
  puts "Eu nĂŁo tenho nada"
end

SaĂ­da (Output):

Eu tenho alguma coisa

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

Entrada (Input):

valor = ""
if !valor.empty? # se valor nĂŁo Ă© vazio
  puts "Eu tenho alguma coisa" # true = vazio
else
  puts "Eu nĂŁo tenho nada"
end

SaĂ­da (Output):

Eu nĂŁo tenho nada

O mesmo pode ser feito com unless

Entrada (Input):

valor = ""
unless valor # se valor nĂŁo Ă© vazio
  puts "Eu tenho alguma coisa"
else
  puts "Eu nĂŁo tenho nada"
end

SaĂ­da (Output):

Eu nĂŁo tenho nada

Laços de Repetição (Loops)

Os laços ou loops, são formas de executar repetitivamente uma operação a fim de obedecer a uma estrutura condicional.

While

O while significa repetir enquanto a condição for verdadeira.

Entrada (Input)

valor = 5 # imprimindo de 5 até 1
while valor > 0 # true
  puts valor
  valor = valor - 1 # Outra forma: valor -= 1
end # quando parar em 0, irå retornar em `false`, a execução serå encerrada

SaĂ­da (Output)

5
4
3
2
1

Entrada (Input)

valor = 5
while valor > 0
  puts valor
  valor = valor - 0
end

SaĂ­da (Output)

`looping infinito do valor`

For

Funciona semelhante ao while, porĂ©m vocĂȘ declara uma variĂĄvel em uma lista de objetos.

for i in [1, 2, 3, 4, 5] # para i em algum array, hash ou objeto que corresponde ao `.each`
  puts "O nĂșmero Ă© #{i}"
end

Until

Semelhante ao while, a diferença estå na condição, que assim quando executar a condição for falsa.

valor = 0
until valor == 10
  puts valor
  valor += 1
end  

Alguns comandos usados em laços

break # sair do laço
return # sair do laço e do método onde o laço estå contido
next # vai imediatamente para a próxima iteração
redo # repete o laço do início (a condição não serå reavaliada)

Exemplo 1: Imprimir de 0 até 9

Entrada (Input):

valor = 0
while (valor < 10)
  puts "O valor Ă© #{valor}"
  valor += 1
end

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5
O valor Ă© 6
O valor Ă© 7
O valor Ă© 8
O valor Ă© 9

Exemplo 1: Imprimir de 0 até 5

Entrada (Input):

valor = 0
while (valor < 10)
  puts "O valor Ă© #{valor}"
  break if valor == 5
  valor += 1
end

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5

Exemplo 1: Imprimir de 0 até 5

Entrada (Input):

valor = 0
while (valor < 10)
  puts "O valor Ă© #{valor}"
  break if valor == 5
  valor += 1
end

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5

Exemplo 2: For

Entrada (Input):

for meu_valor in [0,1,2,3,4,5,6,7]
  puts "Meu valor Ă© #{meu_valor}"
end

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5
O valor Ă© 6
O valor Ă© 7

Exemplo 2: Range For

Entrada (Input):

range = 0..7
for meu_valor in range
  puts "Meu valor Ă© #{meu_valor}"
end

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5
O valor Ă© 6
O valor Ă© 7

Exemplo 2: For Range

Entrada (Input):

for meu_valor in 0..7
  puts "Meu valor Ă© #{meu_valor}"
end

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5
O valor Ă© 6
O valor Ă© 7

Exemplo 2: For para Arrays

Entrada (Input):

lista = [0,1,2,3,4,5,6,7]
for meu_valor in lista
  puts "Meu valor Ă© #{meu_valor}"
end

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5
O valor Ă© 6
O valor Ă© 7

Exemplo 2: Each

Entrada (Input):

lista = [0,1,2,3,4,5,6,7]
lista.each do |meu_valor|
  puts "O valor Ă© #{meu_valor}"
end

Em JavaScript, podemos fazer algo parecido com o comando for each.

SaĂ­da (Output):

O valor Ă© 0
O valor Ă© 1
O valor Ă© 2
O valor Ă© 3
O valor Ă© 4
O valor Ă© 5
O valor Ă© 6
O valor Ă© 7

Exemplo 2: Each com hash

Entrada (Input):

hash = {nome: Isaac, idade: 21}
lista.each do |chave, valor|
  puts "Meu nome Ă© #{chave} e tenho #{valor} anos"
end

SaĂ­da (Output):

Meu nome Ă© Isaac e tenho 21 anos

MĂ©todos (Methods)

def meu_metodo
  puts "meu_metodo foi executado"
end
def meu_metodo(parametro1, parametro2)
  puts "meu_metodo foi executado com #{parametro1} e #{parametro2}"
end

a palavra return Ă© opcional. O ruby sempre retorna o resultado da execução da Ășltima linha.

Exemplo:

def soma (a, b)
  return a + b
end

# Ă© igual

def soma(a, b)
  a + b
end

Exemplo 2:

Entrada (Input):

def soma (valor1, valor2 = 0) # valor1 = 10 e valor2 = 0
  puts "Estou somando #{valor1} e #{valor2}"
  valor1 + valor2
end

puts "Vou executar a soma"
puts soma(10) # valor1

SaĂ­da (Output):

Vou executar a soma
Estou somando 10 e 0
10

Exemplo 3:

Entrada (Input):

def soma (valor1, valor2 = 0) # valor1 = 10 e valor2 = 0
  puts "Estou somando #{valor1} e #{valor2}"
  valor1 + valor2
end

def soma_com_parametros_nomeados(valor1:,valor2:)
  soma(valor1, valor2)
end

puts "Vou executar a soma"
puts soma_com_parametros_nomeados(valor1: 5)

SaĂ­da (Output):

Vou executar a soma
Estou somando 5 e 0
5

Atribuição condicional de variåvel (Attributes)

variavel = nil
variavel = "Algum valor" if variavel.nil?
variavel = nil
variavel = "Algum valor" unless variavel
variavel ||= "Valor"

Exemplo:

variavel = 10
variavel ||= 20
variavel
variavel = nil
variavel
variavel ||= 20
variavel
nova_variavel ||= 100
nova_variavel

ExercĂ­cio 01: AnĂĄlise de PalĂ­ndromo


PalĂ­ndromo: SĂŁo palavras que sĂŁo iguais quando lidas de frente para trĂĄs e de trĂĄs para frente.

Exemplos:

Ovo
Osso
Radar
Pop
Bob
...

Objetivo:

  • Definir um mĂ©todo que verifica se Ă© palĂ­ndromo
  • Usar gets para pedir input de dados e chamar o mĂ©todo
  • Imprimir se Ă© palĂ­ndromo ou nĂŁo

Resolução:

Entrada (Input)

puts "Digite alguma palavra ou nĂșmero:"
palavra = gets.chomp
def palindromo?(palavra)
    palavra.downcase == palavra.downcase.reverse
end

puts palindromo?(palavra)

SaĂ­da (Output)

Digite alguma palavra ou nĂșmero:
Isaac
false

Digite alguma palavra ou nĂșmero:
Pop
true

Digite alguma palavra ou nĂșmero:
7
true

💎 Paradigma de Programação Orientada a Objetos em Ruby


Agora, 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.

A diferença entre Classes x Objetos

Classes e Objetos - Poo

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

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

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

Sintaxe para classe:

.RB

class NomeDaClasse
end

Sintaxe para objeto:

.RB

obj NomeDaClasse.new

Instanciando uma classe pelo objeto

.RB

class MinhaClasse
end

objeto = MinhaClasse.new

p objeto.object_id

irb

irb
nome = "isaac"
nome.object_id
outra_variĂĄvel = "outro_nome"
outra_variĂĄvel.object_id
outro_nome = nome
nome
outro_nome
nome.object_id
outro_nome.object_id
nome.upcase
nome
nome.upcase!
nome
outro_nome

.RB

=> "isaac"
=> 180
=> "outro_nome"
=> 200
=> "isaac"
=> "isaac"
=> "isaac"
=> 180
=> 180
=> "ISAAC"
=> "isaac"
=> "ISAAC"
=> "ISAAC"
=> "ISAAC"

MĂ©todos e atributos para as instĂąncias de um objeto

Foi feita uma classe chamada NomeDaClasse, porém essa estå em branco (BLANK).

Sintaxe de uma classe em Ruby

class NomeDaClasse
end

Vamos criar um comportamento pra ela:

class NomeDaClasse
  def imprimir_ola(nome)
    puts "OlĂĄ #{nome}"
  end
end

objeto = NomeDaClasse.new # instĂąncia para o objeto NomeDaClasse
objeto.imprimir_ola("isaac")

Cujo o método (verbo) é imprimir_ola com um argumento (parùmetro) que se chama nome.

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.

Na Ășltima linha, estamos imprimindo o nome desse objeto com o argumento "isaac".

class NomeDaClasse
  def imprimir_ola(nome)
    @nome = nome
    puts "OlĂĄ #{@nome}"
  end
end

O 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Ăłs somente podemos corrigir essa variĂĄvel dentro da classe.

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

Na parte de OlĂĄ #{@nome} o OlĂĄ # nĂŁo serĂĄ exibido na saĂ­da do cĂłdigo, apena o @nome.

class NomeDaClasse
  def imprimir_ola(nome)
    @nome = nome
    puts "OlĂĄ #{@nome}"
  end
  
  def nome
    @nome
  end
end

isaac = NomeDaClasse.new
isaac.imprimir_ola("isaac")
isaac.nome

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

.RB

class NomeDaClasse
  def initialize(nome)
    @nome = nome
  end
  
  def imprimir_ola(nome)
    puts "OlĂĄ #{@nome}"
  end
  
  def nome
    @nome
  end
end

pessoa = NomeDaClasse.new("isaac")
pessoa.nome = "Foo"
pessoa.nome

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

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

Entretanto, e se eu quiser alterar o nome dessa variåvel? Eu posso criar um método que altera o nome dessa variåvel.

.RB

class NomeDaClasse
  def initialize(nome)
    @nome = nome
  end
  
  def imprimir_ola(nome)
    puts "OlĂĄ #{@nome}"
  end
  
  def nome # retorna a variĂĄvel de instĂąncia
    @nome
  end
  
  def nome=(novo_nome) # troca o valor da instĂąncia
    @nome = novo_nome
  end
end

pessoa = NomeDaClasse.new("isaac")
pessoa.nome = "Foo"
pessoa.nome

Getters e Setters em Ruby

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

.RB

class NomeDaClasse
  attr_accessor  :nome # getter e setter
  # attr_reader  :nome # apenas getter
  # attr_writter :nome # apenas setter
  
  def initialize(nome)
    @nome = nome
  end
  
  def imprimir_ola(nome)
    puts "OlĂĄ #{@nome}"
  end
end

pessoa = NomeDaClasse.new("isaac")
pessoa.nome = Foo
pessoa.nome

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

Colocando a mĂŁo na massa em Poo Ruby

.RB

class Pessoa
  def initialize(nome)
    @nome = nome
  end
end

pessoa = Pessoa.new("isaac")
p pessoa

.RB

#<Pessoa:0x000000000304c2e0 @nome="isaac">

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:

.RB

class Pessoa
  def initialize(nome)
    @nome = nome
  end
end

pessoa = Pessoa.new("isaac")
p 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"

E se fizermos outro objeto para uma nova pessoa?

.RB

class Pessoa
    def initialize(nome)
      @nome = nome
    end
end

pessoa = Pessoa.new("isaac")
pessoa2 = Pessoa.new("matheus")

p pessoa, pessoa2

.RB

#<Pessoa:0x000000000313c2b8 @nome="isaac">
#<Pessoa:0x000000000313c268 @nome="matheus">

EntĂŁo, todo objeto tem a sua entidade na memĂłria e cada um tem um nome diferente.

Em seguida, criamos um método chamado imprimir_ola:

.RB

class Pessoa
    def initialize(nome)
      @nome = nome
    end
    
    def imprimir_ola
      puts "OlĂĄ, #{@nome}"
    end
end

pessoa = Pessoa.new("isaac")
pessoa2 = Pessoa.new("matheus")

pessoa.imprimir_ola
pessoa2.imprimir_ola

.RB

OlĂĄ, isaac
OlĂĄ, matheus

E se eu colocar um novo nome:

.RB

class Pessoa
    def initialize(nome)
      @nome = nome
    end
    
    def imprimir_ola
      puts "OlĂĄ, #{@nome}"
    end
    
    def nome(novo_nome)
      @nome = novo_nome
    end
end

pessoa = Pessoa.new("isaac")
pessoa.imprimir_ola

pessoa.nome('Foo')
pessoa.imprimir_ola

Dessa forma, podemos trocar os valores de objetos no Ruby.

.RB

OlĂĄ, isaac
OlĂĄ, Foo

Podemos também fazer o mesmo com uma linha só utilizando getters e setters:

.RB

class Pessoa
    attr_writer :nome
    
    def initialize(nome)
      @nome = nome
    end
    
    def imprimir_ola
      puts "OlĂĄ, #{@nome}"
    end
end

pessoa = Pessoa.new("isaac")
pessoa.imprimir_ola

pessoa.nome='Foo'
pessoa.imprimir_ola

.RB

OlĂĄ, isaac
OlĂĄ, Foo

Podemos fazer o Poo Ruby também com o irb:

irb

irb
class MinhaClasse
  def initialize(nome)
    @nome = nome
  end
end

objeto = MinhaClasse.new("isaac")

.RB

:initialize
=> #<MinhaClasse:0x000000000351e020 @nome="isaac">

Podemos pegar a variĂĄvel de instĂąncia pelo irb, da seguinte forma:

.RB

objeto.instance_variable_get(:@nome)

.RB

=> "isaac" 

Importando outros arquivos

Imagine a seguinte estrutura de diretĂłrios:

├── classes
|   ├── carro.rb
|   └── pessoa.rb
└── principal.rb

Na seguinte hierarquia, possuimos o nosso cĂłdigo principal, onde chamarĂĄ as suas classes pelos arquivos localizados na pasta chamada classes.

.RB

# arquivo: classes/pessoa.rb
class Pessoa
  def initialize(nome)
    @nome = nome
  end
end

.RB

# arquivo: classes/carro.rb
class Carro
  def initialize(modelo,dono)
    @modelo = modelo
    @dono = dono
  end
end

.RB

# arquivo: principal.rb

require "./classes/pessoa"
require "./classes/carro"

foo = Pessoa.new("Foo")
carro = Carro.new("carro", foo)

Chamamos outro arquivo ruby pelo método de importação require juntamente com o caminho do diretório.

Agora, vamos instalar uma biblioteca do Ruby chamada awesome_print.

RubyGems

gem install awesome_print

Depois que instalamos essa biblioteca, também devemos importå-la no arquivo utilizando o require.

.RB

# arquivo: principal.rb

require "awesome_print" # importando a biblioteca
require "./classes/pessoa"
require "./classes/carro"

foo = Pessoa.new("Foo")
carro = Carro.new("carro", foo)

ap foo # método da biblioteca importada

Herança

O conceito de herança é quando uma classe precisa herdar as funcionalidades de outra classe.

Herança (Poo Ruby)

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

Exemplo: A classe Filho herda os comportamentos da classe Pai.

Exemplo de Herança (Poo Ruby)

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

Herança com Object (Poo Ruby)

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

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

Exemplo:

.RB

class Sensor
  def iniciar
    # iniciar o sensor
  end
  
  def coletar
    # fazer uma coleta genérica
  end
end

class SensorSolo < Sensor
  def coletar
    # coletar métricas no solo
  end
end

class SensorTemperatura < Sensor
  def coletar
    # coletar métricas de temperatura
  end
end

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.

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

.RB

super # executa o método sobrescrito da super classe

Herança é para reuso de funcionalidades.

Exemplo em somente um arquivo com todas as classes:

.RB

class Sensor
  def instalar
    # instala o sensor
    puts "Sensor instalado"
  end
  
  def iniciar
    # inicia o sensor
    puts "Sensor iniciado"
  end
    
  def coletar_metricas
    # coleta as métricas
    puts "MĂ©tricas analisadas e coletadas"
    puts "MĂ©tricas analisadas e coletadas novamente"
  end
  
end

class SensorTemperatura < Sensor
  # Sem nada dentro pode inicializar o SensorTemperatura herdando todos os métodos da classe Sensor
  # Com algo dentro, podemos fazer algo mais exĂłtico, como abaixo:
 
  def coletar_metricas
  # inicializar componentes de temperatura
    puts "MĂ©tricas de temperatura coletadas"
    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
  end
  
  # Logo, ao rodar a aplicação ela irå rodar a mensagem acima na impressão de sensor.coletar_metricas
end

sensor = SensorTemperatura.new # Sensor.new # Sensor.new = imprimir apenas os métodos da classe Sensor
sensor.instalar
sensor.iniciar
sensor.coletar_metricas

.RB

Sensor instalado
Sensor iniciado
MĂ©tricas de temperatura coletadas
MĂ©tricas analisadas e coletadas
MĂ©tricas analisadas e coletadas novamente

MĂ©todos e atributos de classe

Até 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.

.RB

Pessoa.gerar

Os mĂ©todos de classe sĂŁo Ășteis quando possuĂ­mos uma funcionalidade que nĂŁo Ă© tĂŁo dependente do estado do objeto.

Sintaxe dos métodos de classe

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

.RB

class Pessoa
  def self.gerar
    puts "Estou gerando uma nova pessoa partir do método de classe"
  end
end

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.

.RB

class Pessoa
  @@variavel_da_classe_pessoa = 100
  
  def self.valor_da_variĂĄvel
    @@variavel_da_classe_pessoa
  end
  
  def self.incrementar_valor_variavel
    @@variavel_da_classe_pessoa += 1
  end
end

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.

.RB

class Pessoa
  @@numero_de_pessoas = 0
  
  def self.gerar
    @@numero_de_pessoas += 1
    puts "vou fazer antes"
    Pessoa.new
  end
end

pessoa = Pessoa.new # instĂąnciando o objeto Pessoa
pessoa = Pessoa.gerar # instùnciando a classe com o método de classe gerar

p pessoa 

Visibilidade dos métodos

AtĂ© 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.

.RB

class MinhaClasse
  def m1
    puts "MĂ©todo 1"
    m2
    m3
  end
  
  def m2
    puts "MĂ©todo 2"
  end
  
  def m3
    puts "MĂ©todo 3"
  end
end

O mĂ©todo m1 imprime: MĂ©todo 1, m2 e m3. Portanto, esses mĂ©todos sĂŁo pĂșblicos.

Vamos 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:

.RB

class MinhaClasse
  def m1
    puts "MĂ©todo 1"
    m2
    m3
  end
  
  private
  
  def m2
    puts "MĂ©todo 2"
  end
  
  def m3
    puts "MĂ©todo 3"
  end
end

Tudo abaixo da palavra private fica privado, portanto o m2 e o m3 estĂŁo privados.

Os métodos privados podem também serem chamados por uma subclasse.

.RB

class MinhaSubClasse < MinhaClasse
  def m4
    puts "MĂ©todo m4 - subclass"
    m3
  end
end

Existem 3 tipos de acessibilidade de métodos no Ruby:

  • public (padrĂŁo) podem ser acessados por qualquer mĂ©todo em qualquer objeto.
  • 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.
  • protected podem ser chamados por qualquer instĂąncia se for da mesma Classe/SuperClasse.

Somente os mĂ©todos pĂșblicos podem ser açÔes para os controllers!

Vamos testar esses modos de acessibilidade de métodos!

.RB

Todos os mĂ©todos ficaram pĂșblicos.

class MinhaClasse
  def m1
    puts "MĂ©todo 1"
    m2
    m3
  end
  
  def m2
    puts "MĂ©todo 2"
  end
  
  def m3
    puts "MĂ©todo 3"
  end
end

### a partir daqui, Ă© um outro contexto

obj = MinhaClasse.new
obj.m1
obj.m2
obj.m3

.RB

MĂ©todo 1
MĂ©todo 2
MĂ©todo 3

.RB

Todos os métodos ficaram privados.

class MinhaClasse

  private 
  
  def m1
    puts "MĂ©todo 1"
    m2
    m3
  end
  
  def m2
    puts "MĂ©todo 2"
  end
  
  def m3
    puts "MĂ©todo 3"
  end
end

### a partir daqui, Ă© um outro contexto

obj = MinhaClasse.new
obj.m1
obj.m2
obj.m3

.RB

c:/Users/ipinheiro/Desktop/MinhaClasse.rb:23:in `': private method `m1' called for 
# (NoMethodError)

.RB

Como privatizar um mĂ©todo especĂ­fico: m1 serĂĄ o Ășnico mĂ©todo privado da Classe.

class MinhaClasse
  
  private def m1
    puts "MĂ©todo 1"
    m2
    m3
  end
  
  def m2
    puts "MĂ©todo 2"
  end
  
  def m3
    puts "MĂ©todo 3"
  end
  
end

### a partir daqui, Ă© um outro contexto

obj = MinhaClasse.new
obj.m1
obj.m2
obj.m3

Todavia, na saída do código, o m1 serå o primeiro a ser executado, gerando a finalização dele por ser privado.

.RB

c:/Users/ipinheiro/Desktop/MinhaClasse.rb:23:in `': private method `m1' called for 
# (NoMethodError)

.RB

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.

class MinhaClasse  
  def m1
    puts "MĂ©todo 1"
    m2
    m3
  end
  
  private
  
  def m2
    puts "MĂ©todo 2"
  end
  
  def m3
    puts "MĂ©todo 3 privado"
  end
  
  protected # Tudo aqui em baixo Ă© PROTECTED!
  
  def m5
    puts "MĂ©todo 5"
  end
end

class MinhaSubClasse < MinhaClasse
  def m4
    m3
    outro_obj = MinhaClasse.new
    puts "MĂ©todo 4"
    outro_obj.m5
  end
end

### a partir daqui, Ă© um outro contexto

obj = MinhaSubClasse.new
obj.m4
obj.m5

.RB

c:/Users/ipinheiro/Desktop/MinhaClasse.rb:38:in `': protected method `m5' called for 
# (NoMethodError)
MĂ©todo 3 privado
MĂ©todo 4
MĂ©todo 5

irb

No Ruby, possuímos algumas propriedades que podem acessar os métodos privados, como por exemplo o método send(:método da classe).

irb
class Pessoa
  private def falar
    puts "Estou falando"
  end
end
pessoa = Pessoa.new
pessoa.send(:falar)

ExercĂ­cio 02: Conta bancĂĄria

Desafio:

  • Criar uma classe responsĂĄvel para representar Contas BancĂĄrias.
  • Criar um mĂ©todo que me permita transferir valor entre contas usando: "conta1.transferir(conta2,100)" onde 100 Ă© o valor que eu desejo transferir.
  • Plus: Criar um tipo de conta em que existe uma tarifa para se transferir dinheiro

Solução:

Estrutura de arquivos

├── classes
|   └── conta_bancaria.rb
└── principal.rb

.RB

# principal.rb

require "./classes/conta_bancaria"

conta_cadu = ContaBancaria.new("cadu", 100)
conta_pessoa2 = ContaBancaria.new("pessoa2", 200)

conta_cadu.transferir(conta_pessoa2, 50)

p "Conta Cadu"
p conta_cadu.saldo # 50

p "Conta Pessoa 2"
p conta_cadu.saldo # 250

# caso de teste de conta sem saldo

conta_cadu.transferir(conta_pessoa2, 60) # falhar

p "Conta Cadu"
p conta_cadu.saldo # 50

p "Conta Pessoa 2"
p conta_pessoa2.saldo # 250

.RB

class ContaBancaria
  def initialize(proprietario, valor_inicial)
    @proprietario = proprietario
    @valor        = valor_inicial
  end
  
  def transferir(outra_conta, valor)
    # logica de transferĂȘncia
    if saldo >= valor
      # consigo
      debitar(valor)
      outra_conta.depositar(valor)
    else
      # não consigo (não faço nada)
      raise "NĂŁo consegui transferir! Saldo insuficiente."
    end
  end
  
  def saldo
    @valor
  end
  
  private 
  
  def debitar(valor_para_debitar)
    @valor -= valor
    @valor = valor_para_debitar
  end
  
  protected
  
  def depositar(valor_para_depositar)
    @valor += valor_para_depositar
  end
  
end

Plus: Taxa na transferĂȘncia

Estrutura de arquivos

├── classes
|   ├── conta_com_taxa.rb
|   └── conta_bancaria.rb
└── principal.rb

.RB

# conta_com_taxa.rb

class ContaComTaxa < ContaBancaria
   def transferir(outra_conta, valor)
     if saldo >= valor
       debitar(2)
       super
     end
   end
end

.RB

# principal.rb

require "./classes/conta_bancaria"
require "./classes/conta_com_taxa"

conta_cadu = ContaComTaxa.new("cadu", 100)
conta_pessoa2 = ContaBancaria.new("pessoa2", 200)

conta_cadu.transferir(conta_pessoa2, 50)

p "Conta Cadu"
p conta_cadu.saldo # 50

p "Conta Pessoa 2"
p conta_cadu.saldo # 250

# caso de teste de conta sem saldo
begin 
  conta_cadu.transferir()


conta_cadu.transferir(conta_pessoa2, 60) # falhar

# o codigo abaixo nĂŁo foi executado, pois a linha acima gerou um erro.

p "Conta Cadu"
p conta_cadu.saldo # 50

p "Conta Pessoa 2"
p conta_pessoa2.saldo # 250

đŸ›€ïž RoR - RubyOnRails


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

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

Existem vårias maneiras de instalar o Rails, a mais famosa consiste na instalação a partir da gem oficial liberada pelo RubyGems.

gem install rails

O comando abaixo mostra as seguintes opçÔes que temos para criar um projeto RubyOnRails:

rails new -h

Logo, podemos criar o nosso primeiro projeto utilizando o Rails:

rails new meu_projeto

ApĂłs isso, vai ser criado o seguinte diretĂłrio do projeto com os seguintes arquivos:

/meu_projeto
├── app
│   ├── assets
│   │   ├── config
│   │   ├── images
│   │   └── stylesheets
│   ├── channels
│   ├── controllers
│   └── views
├── bin
├── config
├── db
|   ├── 
│   └── seeds.rb
├── lib
│   ├── assets
│   └── tasks
├── log
│   ├── .keep
│   └── development.log
├── public
├── storage
├── test
├── tmp
├── vendor
│   ├── javascript
|   |   └── .keep
│   └── .keep
├── .gitattributes
├── .gitattributes
├── .gitignore
├── .ruby.version
├── config.ru
├── Gemfile
├── Gemfile.lock
├── Rakefile
└── README.md

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

Jå o arquivo Gemfile.lock é um arquivo que nem deve ser alterado, pois é gerado após a instalação do bundle.

O Gemfile Ă© similar ao package.json.

Resumidamente, o conjunto de comandos para iniciar uma aplicação em RubyOnRails é:

# rails new -h
rails new meu_projeto
cd meu_projeto
bundle install
# bundle update
rails server # rails s

SQLite


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

O comando abaixo permite vocĂȘ definir, no inĂ­cio do seu projeto, o banco de dados necessĂĄrio:

rails new meu_projeto -d postgresql

Caso se nĂŁo for especificado, vocĂȘ irĂĄ utilizar o SQLite.

VocĂȘ 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).

Com isso, a sua aplicação RoR irå se conectar ao banco de dados do PostgreSQL no endereço: http://localhost:5432

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.

Criando um CRUD com scaffold

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

rails g scaffold User name:string email:string

O comando acima serve para gerar (g = generate) um scaffold com User onde name e email recebem o valor string.

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

Comando para desfazer o CRUD

O comando abaixo serve para excluir as tabelas criadas para fazer o CRUD, com isso o CRUD serĂĄ desfeito.

rails db:rollback

Comando para deletar o scaffold

O comando abaixo deleta tudo relacionado ao scaffold criado.

rails d scaffold Product

Criando um banco de dados e migrando para o banco

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

rails db:migrate db:create

Portanto, 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.

Criando um CRUD sem scaffold

Controller

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

Gerando um model com Rails

rails generate model Post title:string body:text

Dessa forma, ele vai gerar um model com tĂ­tulo e corpo automaticamente, sem precisarmos escrever isso no cĂłdigo.

Criando as tabelas no banco de dados com o Rails

rails db:migrate

Dessa 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:

class CreatePosts < ActiveRecord::Migration[7.0]
  def change
    create_table :posts do |t|
      t.string :title, null: false
      t.text :body, null: false

      t.timestamps
    end
  end
end

O comando null: false significa que o dado nĂŁo serĂĄ aceito ser ele conter o valor null (nulo).

Comando para acessar o console do Rails

rails console

Vamos dizer que eu queira acessar a classe Posts:

irb(main):003:0> Post
=> Post (call 'Post.connection' to establish a connection)
irb(main):004:0>

Para contar quantos posts tem na tabela:

irb(main):004:0> Post.count()
   (2.4ms)  SELECT sqlite_version(*)
  Post Count (0.3ms)  SELECT COUNT(*) FROM "posts"
=> 0
irb(main):005:0>

Para criar um post na tabela diretamente pelo console:

irb(main):005:0> post = Post.create(title: "Isaac", body: "lindo")
  TRANSACTION (0.1ms)  begin transaction
  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"]]
  TRANSACTION (4.0ms)  commit transaction
=> 

Para contar todos os itens da tabela do maior ao menor:

irb(main):021:0> Post.last
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."id" DESC LIMIT ?  [["LIMIT", 1]]
=> 
#    
irb(main):022:0>

Para consultar o post:

irb(main):022:0> post
=>
#<Post:0x0000026fa2a5bd60
 id: 1,
 title: "Isaac",
 body: "lindo",
 created_at: Tue, 12 Jul 2022 18:56:22.030795000 UTC +00:00,
 updated_at: Tue, 12 Jul 2022 18:56:22.030795000 UTC +00:00>
irb(main):023:0>

Definindo rotas no Rails

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

E agora, vamos aprender a criar as nossas rotas para um projeto RoR:

.RB

Rails.application.routes.draw do
  resources :users
  
  get 'usuarios', to: 'users#index'
  
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  # root "articles#index"
end

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

Construindo um blog com RoR

Para mais detalhes de como inserir o bootstrap numa aplicação RoR: https://gorails.com/forum/install-bootstrap-with-webpack-with-rails-6-beta

🐋 Deploying: Rails + PostgreSQL

Para saber mais acesse: https://docs.docker.com/samples/rails/

Releases

No releases published

Packages

 
 
 

Languages