Esta apresentação aborda os tópicos introdutórios da Linguagem de Programação Ruby, considerando que o leitor já possui conhecimentos de técnicas de programação. Ruby é uma linguagem de programação dinâmica, de tipagem forte e implícita, orientada a objetos, que tem ganho cada vez mais espaço dentro da comunidade de desenvolvedores, principalmente por conta do projeto mais famoso desenvolvido nela: o framework de desenvolvimento Web Ruby on Rails.
3. Instalação do Ruby
Linux (Ubuntu):
$> sudo apt-get
Windows:
http://www.ruby-lang.org/en/downloads (Ruby One-Click Installer)
(instale em um diretório sem espaços no nome e inclua o subdiretório <$RUBY>
bin ao path do sistema operacional)
Mac:
$> port install
5. Primeiros Passos
irb: Interactive Ruby - Funciona como um console/terminal,
avaliando cada linha inserida e mostrando o resultado
imediatamente
Outra forma de executar os comandos é colocá-los em um
arquivo “.rb” e chamar o comando “ruby”, passando o
arquivo como parâmetro da linha de comando
6. Primeiros Passos
$> irb
Syntax Sugar: Estão disponíveis os operadores
>> 1+1
equivalente a 1.+(1) tradicionais: +, -, /, * e ** (potência)
=> 2
equivalente a:
>> def soma a, b
>> def soma(a, b)
>> a+b
>> a+b;
>> end ?> end
=> nil => nil
>> soma 1, 2 >> soma(1,2)
=> 3 => 3
7. Primeiros Passos
>> resultado = 4 ** 2
puts é o método usado
=> 16
para imprimir valores no
>> puts(resultado)
stdout e nil é o objeto
16
nulo do Ruby
=> nil
Ruby possui tipagem:
- implícita (não precisa de declaração)
- forte (não se pode misturar tipos
diferentes)
- dinâmica (pode-se inserir/alterar
métodos/comportamentos em objetos)
8. Primeiros Passos
>> 1.class
=> Fixnum
>> self.class
=> Object - Tudo é objeto, todo objeto
>> [].class pertence a uma classe e todas
=> Array as classes descendem de
>> {}.class Object
=> Hash - self indica o objeto atual
>> "a".class
=> String
>> 1.1.class
=> Float
>> 99999999999999999.class
=> Bignum
10. Primeiros Passos
>> class Fixnum
>> def +(other)
>> self - other Open Classes: podemos
>> end abrir todas as classes e
>> end alterar seus
=> nil comportamentos! Isto é
>> 1+5 bastante útil, mas é
=> -4
bastante perigoso também!
11. Variáveis de escopo
>> 1 + "2"
TypeError: String can't be coerced into Fixnum
from (irb):22:in `-'
Em Ruby não é preciso declarar
from (irb):22:in `+'
uma variável, pois ele usa
from (irb):22
tipagem implícita, mas não
tipagem fraca!
O escopo de Símbolo Descrição
variáveis não é nome Variável local
definido por @nome Variável de instância
palavras-chave e @@nome Variável de classe
sim por símbolos: $nome Variável global
13. Blocos de código
>> arr = [1,2,3,4]
=> [1, 2, 3, 4] Usados para iterar em
>> arr.each { |val| coleções, personificar
?> print "#{val}n" } comportamento de métodos e
1 definir DSLs
2
3 Podem ser definidos pelos
4 símbolos “{“ e “}” ou por “do”
=> [1, 2, 3, 4] e “end” e podem receber
parâmetros logo depois de
abertos usando “|” para
demarcar o início e fim da
lista de parâmetros
14. Blocos de código
>> arr.each_with_index do |val, idx|
?> print "Posicao #{idx} valor #{val}n";
?> end
Posicao 0 valor 1
Posicao 1 valor 2
Posicao 2 valor 3 Usando “do” e “end”
Posicao 3 valor 4
=> [1, 2, 3, 4]
15. Blocos de código
>> valor = 1
=> 1
>> arr.each do |val|
?> valor += val;
?> end
=> [1, 2, 3, 4]
Closure: bloco de
>> valor
código com variáveis
=> 11
visíveis do seu
contexto
16. Blocos de código
>> valor = 1
=> 1
>> def iterar Se for utilizado um método,
>> arr = [1,2,3,4] teremos um erro, pois ele não
>> arr.each do |val| “aponta” para as variáveis do
?> valor += val;
contexto em que foi definido,
?> end
como o faz a closure
>> end
=> nil
>> iterar
NoMethodError: undefined method `+' for nil:NilClass
from (irb):25:in `iterar'
from (irb):24:in `each'
from (irb):24:in `iterar'
from (irb):28
17. Blocos de código
>> def recebe_proc_e_passa_parametro
>> if block_given?
>> yield
>> else
?> puts "Voce precisa passar um bloco para este metodon"
>> end
Blocos de código podem
>> end
=> nil
ser passados como
>> recebe_proc_e_passa_parametro parâmetros para métodos
Voce precisa passar um bloco para este metodo
=> nil
>> recebe_proc_e_passa_parametro { print "dentro do blocon" }
dentro do bloco
=> nil
18. Blocos de código
>> def recebe_proc_e_passa_parametro
>> if block_given?
>> yield(23)
>> else
?> puts "Voce precisa passar um bloco para este metodon"
>> end
>> end
=> nil Pode-se passar
>> recebe_proc_e_passa_parametro do |par| parâmetros
?> puts "Recebi #{par} dentro desse blocon" para blocos
>> end recebidos nos
Recebi 23 dentro desse bloco métodos
=> nil
19. Procs
>> def recebe_proc(&block)
Procs se parecem com
>> if block
blocos e com closures,
>> block.call
>> end
mas podem ser
>> end armazenados em uma
=> nil variável. No entanto,
>> recebe_proc são mais “caros”.
=> nil
>> recebe_proc { print "este bloco vai se tornar uma proc,
pois vai ser atribuido a uma variavel no metodo"}
=> este bloco vai se tornar uma proc, pois vai ser atribuido a
uma variavel no metodo
=> nil
20. Procs
>> p = Proc.new { print "este bloco vai se tornar uma proc,
pois estah sendo atribuido a uma variaveln"}
=> #<Proc:0x00551d4c@(irb):11>
>> p.call
este bloco vai se tornar uma proc, pois estah sendo atribuido
a uma variavel
=> nil Criação de Proc utilizando
construtor da classe Proc
>> p1 = lambda do
?> print "este bloco vai se tornar uma proc, pois estah sendo
atribuido a uma variaveln"
>> end Criação de Proc utilizando
=> #<Proc:0x00543904@(irb):13> a palavra-chave lambda
>> p1.call
este bloco vai se tornar uma proc, pois estah sendo atribuido a uma
variavel
=> nil
21. Procs
>> p = Proc.new { print "a" } Proc é uma classe,
=> #<Proc:0x0053ad90@(irb):17> descendente de Object, e
possui vários métodos
>> p.methods.sort
=> ["==", "===", "=~", "[]", "__id__", "__send__", "arity",
"binding", "call", "class", "clone", "display", "dup", "eql?",
"equal?", "extend", "freeze", "frozen?", "hash", "id", "inspect",
"instance_eval", "instance_of?", "instance_variable_defined?",
"instance_variable_get", "instance_variable_set",
"instance_variables", "is_a?", "kind_of?", "method", "methods",
"nil?", "object_id", "private_methods", "protected_methods",
"public_methods", "recebe_proc", "respond_to?", "send",
"singleton_methods", "taguri", "taguri=", "taint", "tainted?",
"to_a", "to_proc", "to_s", "to_yaml", "to_yaml_properties",
"to_yaml_style", "type", "untaint"]
22. Procs
Método Descrição
Utilizado para executar o proc, os parâmetros que forem
call
definidos no bloco são passados como parâmetros para call
Alias para o método call, ou seja, pode-se executar um proc com
[]
a sintaxe: p[parâmetros]
arity Informa o número de parâmetros definidos nesse proc
Retorna a Binding correspondente ao local onde foi definido o
binding
bloco de código que deu origem a esse proc
23. Números
Classe Descrição
Fixnum Representa inteiros de -1073741824 a 1073741823
Bignum Representa inteiros fora do intervalo da classe Fixnum
Float Representa números em ponto flutuante
25. Valores Booleanos
Operadores booleanos:
>> def testa_valor(val) ==, >, <, >= e <=
>> if val
>> print "#{val} eh considerado verdadeiro pelo Rubyn"
>> else
?> print "#{val} eh considerado falso pelo Rubyn"
>> end
>> end Expressões booleanas podem
=> nil ainda ser combinadas com os
operadores:
&& (and) e || (or)
26. Valores Booleanos
“false” e “nil” são falsos
>> testa_valor true
“true” e tudo mais é verdadeiro
true eh considerado verdadeiro pelo Ruby
=> nil
>> testa_valor false
false eh considerado falso pelo Ruby
=> nil
>> testa_valor "asdf"
asdf eh considerado verdadeiro pelo Ruby
=> nil
>> testa_valor nil
eh considerado falso pelo Ruby
=> nil
27. Strings
Símbolo Descrição
aspas String simples com expansão de variáveis
apóstrofes String simples sem expansão de variáveis
<<MARCADOR String multilinha com expansão de variáveis
%Q{ } String multilinha com expansão de variáveis
%q{ } String multilinha sem expansão de variáveis
28. Strings
>> a = "texto"
=> "texto"
>> b = 'texto'
=> "texto"
>> c = "textonsegunda linha"
=> "textonsegunda linha"
>> d = 'textonmesma linha'
=> "textonmesma linha"
>> e = "a = #{a} - eh assim que se utiliza expansao de variaveis"
=> "a = texto - eh assim que se utiliza expansao de variaveis"
>> f = <<__ATEH_O_FINAL
esta eh
uma String
bem grande e soh termina
quando encontrar o marcador __ATEH_O_FINAL
no inicio de uma linha
__ATEH_O_FINAL
=> "esta ehnuma Stringnbem grande e soh terminanquando encontrar o
marcador __ATEH_O_FINALnno inicio de uma linhan"
29. Strings
>> g = %Q{Esta tambem
eh uma String
com mais de uma linha
e tambem suporta #{a}
expansao de variaveis
}
=> "Esta tambemneh uma Stringncom mais de uma linhane tambem
g
suporta textonexpansao de variaveisn"
>> h = %q{Jah
esta
que tambem eh multi-linha
nao suporta #{a}
expansao de variaveis}
=> "Jahnestanque tambem eh multi-linhannao suporta #{a}
nexpansao de variaveis"
31. Constantes
>> variavel = 1
=> 1 Não existem, mas existe um
>> variavel = "asdf" padrão que diz que variáveis
=> "asdf" com primeira letra maíuscula
são constantes
>> CONSTANTE = "asdf"
=> "asdf"
>> CONSTANTE = 1
(irb):62: warning: already initialized constant CONSTANTE
=> 1
>> Constante = 2
=> 2
>> Constante = 5
(irb):64: warning: already initialized constant Constante
=> 5
32. Intervalos Numéricos
>> a = 1..10
=> 1..10 Dois tipos:
>> b = 1...10 - inclusivo: ..
=> 1...10
- exclusivo: ...
>> a.each do |v|
?> print "#{v} "
>> end
1 2 3 4 5 6 7 8 9 10 => 1..10
>> b.each do |v|
?> print "#{v} "
>> end
1 2 3 4 5 6 7 8 9 => 1...10
33. Arrays
>> arr = [ ] No Ruby, não são tipados!
=> [] Mas além das 2 formas de
declarar arrays genéricos,
>> arr = Array.new existe uma forma especial para
=> [] declarar arrays que contêm
apenas strings
>> arr = %w{ a b c }
=> ["a", "b", "c"]
35. Arrays
Método Descrição
select Recebe um bloco e retorna um array contendo todos os
elementos para os quais o bloco retornou true
[]= Define o valor de uma posição do array
[] Retorna o valor da posição passada como parâmetro
last Retorna o último item do array
empty? Retorna verdadeiro se o array estiver vazio
equal? Compara com outro array
36. Arrays
Método Descrição
each_index Recebe um bloco e passa apenas os índices do array para o
bloco
sort Retorna um novo array contendo os itens deste ordenados
sort! Similar ao sort, mas altera o array de origem
+ Concatena 2 arrays, criando um novo com os itens de ambos
- Cria um novo array com os itens do primeiro não contidos no
segundo
push ou << Adiciona um item no final do array (append)
37. Arrays
Método Descrição
pop Retorna o último item e o remove do array
find Recebe um bloco com um parâmetro e retorna o primeiro
item para o qual o bloco retornar verdadeiro
clear Remove todos os itens do array
shift Retorna o primeiro item e o remove do array
first Retorna o primeiro item do array
Recebe um valor inicial e um bloco com dois parâmetros: o
inject valor atual e o item atual do array, retornando o resultado
da operação realizada no bloco
38. Arrays
>> arr = %w{ a b c }
=> ["a", "b", "c"]
Exemplos
>> arr << “d”
=> ["a", "b", "c", "d"]
>> arr.select {|x| x!='a'}
=> ["b", "c", "d"]
>> arr = [1, 2, 3, 4, 5, 6]
=> [1, 2, 3, 4, 5, 6]
>> arr.inject(0) do |val, it|
?> val + it
>> end
=> 21
39. Arrays
>> lista = ["4", "um", "cinco", "bla"]
=> ["4", "um", "cinco", "bla"]
>> lista.each do |item|
?> puts item each: chama o bloco
>> end associado para cada um
4
dos itens, passando o
um
cinco
item como parâmetro
bla
=> ["4", "um", "cinco", "bla"] map (ou collect):
>> novo = lista.map do |item| coleta os retornos de
?> item.upcase todas as chamadas do
>> end bloco associado
=> ["4", "UM", "CINCO", "BLA"]
>> novo.inspect
=> "["4", "UM", "CINCO", "BLA"]"
40. Arrays
>> def parametros_variaveis(param1, param2, *arr)
>> if arr
>> arr.each do |v|
?> print "#{v.class} - #{v}n"
>> end
>> end Em Ruby, é possível criar
>> end métodos com uma lista
=> nil variável de parâmetros
>> parametros_variaveis 1, 2 usando-se arrays
=> []
>> parametros_variaveis 1, 2, 3, "asdf", :simb, :a => "teste", :arr
=> %w{a b c}
Fixnum - 3
O operador *, neste caso,
String - asdf
Symbol - simb
é chamado de splat
Hash - arrabcateste
=> [3, "asdf", :simb, {:arr=>["a", "b", "c"], :a=>"teste"}]
41. Hashes
>> h = { 1 => "asdf", "b" => 123 }
=> {"b"=>123, 1=>"asdf"}
Hashes são coleções do
>> h1 = { }
tipo chave => valor
=> {}
>> h2 = Hash.new Símbolo “=>”
=> {}
Duas formas de
declaração: atalho { } e
o construtor da classe
Hash
43. Hashes
Método Descrição
[] Retorna o valor da chave passada como parâmetro
[]= Atribui o valor da chave
each Executa um bloco com dois argumentos para cada posição
do mapa
each_key Executa um bloco com um argumento (a chave) para cada
posição do mapa
has_key? Retorna verdadeiro se a chave existe no mapa
44. Hashes
Método Descrição
has_value? Retorna verdadeiro se o valor corresponde a alguma dos
valores do mapa
default= Possibilita configurar qual valor o mapa vai retornar quando
for buscado o valor para uma chave inexistente
default_proc Idem a default=, mas executa um bloco para criar o valor
para as novas chaves
delete Remove o item correspondente à chave indicada do mapa,
retornando o valor da classe
45. Símbolos
São nomes iniciados com “:”
São muito utilizados como chaves em hashes ou como
rótulos para alguma coisa
São como strings, mas consomem menos recursos do que
elas
“to_sym” : transforma strings em símbolos
46. Expressões Regulares
Expressões regulares fazem parte da linguagem no Ruby
Existem 3 formas de declarar expressões regulares em Ruby:
>> er = /(.*?) .*/
=> /(.*?) .*/
>> er = %r{(.*?) .*}
=> /(.*?) .*/
>> er = Regexp.new "(.*?) .*"
=> /(.*?) .*/
47. Expressões Regulares
>> er = /^[0-9]/
=> /^[0-9]/
>> "123" =~ er A classe Regexp
=> 0
disponibiliza diversos
>> er =~ "123"
=> 0
métodos e operadores
>> er =~ "abc" para facilitar a
=> nil operação com ERs
>> er !~ "123"
=> false
>> er !~ "abc"
=> true
>> mt = /(..)/(..)/(....)/.match("08/04/2010")
=> #<MatchData:0x53d5cc>
>> mt.length
=> 4
48. Expressões Regulares
>> mt[0]
=> "08/04/2010"
>> mt[1]
=> "08"
>> mt[2]
=> "04"
>> mt[3]
=> "2010"
>> todo, dia, mes, ano = *(/(..)/(..)/(....)/.match("08/04/2010"))
=> ["08/04/2010", "08", "04", "2010"]
>> todo
=> "08/04/2010"
>> dia
=> "08"
>> mes
=> "04"
>> ano
=> "2010"
50. Expressões Regulares
Método Descrição
=~ Procura pela expressão regular no texto e retorna o índice
em que ela foi encontrada
!~ Informa se existe uma ocorrência da expressão regular no
texto
Retorna um objeto do tipo MatchData, que contém ponteiros
match para os locais onde cada grupo da expressão regular foi
encontrado
51. Mundo Orientado a Objetos
>> pessoa = Object.new()
=> #<Object:0x553c14>
>> def pessoa.fala() Tudo em Ruby é objeto!
>> puts "Sei falar"
E Ruby é uma linguagem
>> end
=> nil
dinâmica!
>> pessoa.fala()
Sei falar
=> nil
>> def pessoa.troca(roupa, lugar='banheiro')
>> puts "trocando de #{roupa} no #{lugar}"
>> end
=> nil Os últimos argumentos
>> pessoa.troca("camiseta") podem ter um valor padrão,
trocando de camiseta no banheiro tornando-se opcionais
=> nil
52. Classes
>> class Pessoa
>> def fala Classes servem para que se
>> puts "Sei Falar" crie objetos com alguns
>> end métodos já inclusos
>>
?> def troca(roupa, lugar="banheiro")
>> puts "trocando de #{roupa} no #{lugar}"
>> end
>> end
=> nil
>> p = Pessoa.new
=> #<Pessoa:0x50ef88>
>> p.class
=> Pessoa
Classes são também objetos!
>> p.class.class
=> Class
53. Classes
Um método pode chamar outro
método do próprio objeto via
“self” (equivalente ao this)
>> class Conta
>> def transfere_para(destino, quantia)
>> debita quantia # mesmo que self.debita(quantia)
>> destino.deposita quantia
>> end
>> end
=> nil Toda chamada de método
é sempre uma mensagem
enviada a algum objeto
54. Classes
>> class Professor
>> def ensina(aluno)
>> def aluno.escreve Dinamismo ao extremo:
>> "Sei escrever!" métodos que definem métodos
>> end em outros objetos
>> end
>> end
=> nil
>> juca = Aluno.new
=> #<Aluno:0x31cb80>
>> juca.respond_to? :escreve
=> false
>> zagari = Professor.new
=> #<Professor:0x3007f0>
>> zagari.ensina juca
=> nil
>> juca.escreve
=> "Sei escrever!"
55. Atributos
>> class Pessoa
>> def muda_nome(novo_nome)
>> @nome = novo_nome
>> end
>> def diz_nome
>> "meu nome eh #{@nome}"
>> end
>> end
=> nil Variáveis
de instância: são
sempre privadas
>> p = Pessoa.new (encapsulamento) começam com @
=> #<Pessoa:0x58ad18>
>> p.muda_nome "Joao"
=> "Joao"
>> p.diz_nome
=> "meu nome eh Joao"
56. Construtor
>> class Pessoa
>> def initialize
>> puts "Criando nova Pessoa"
>> end
>> end
Método “initialize”: código
=> nil
>> Pessoa.new
executado na criação de um
Criando nova Pessoa objeto
=> #<Pessoa:0x567f84>
>> class Pessoa
>> def initialize(nome) Os “initialize” são métodos
>> @nome = nome privados e podem receber
>> end parâmetros
>> end
=> nil
>> joao = Pessoa.new("Joao”)
=> #<Pessoa:0x57515c @nome="Joao">
57. Acessores e Modificadores
>> class Pessoa
>> def nome #acessor
>> @nome
>> end
Método acessor
>> def nome=(novo_nome)
>> @nome = novo_nome
>> end
Método modificador
>> end
=> nil
>> pessoa = Pessoa.new
Criando nova Pessoa
=> #<Pessoa:0x54cc48>
>> pessoa.nome=("Jose")
=> "Jose"
>> puts pessoa.nome
Jose
=> nil Syntax Sugar
>> pessoa.nome = "Maria" não é uma simples atribuição
=> "Maria"
58. Métodos de Classe
>> class Pessoa
>> # ...
>> end Se classes são
=> nil objetos, podemos
>> def Pessoa.pessoas_no_mundo definir métodos de
>> 100
>> end
classe como em
=> nil qualquer outro
>> Pessoa.pessoas_no_mundo objeto
=> 100
>> class Pessoa
>> def self.pessoa_no_mundo “Idiomismo” para se definir
>> 100 os métodos de classe dentro
>> end da própria definição da
>> # ...
?> end
classe, onde self aponta para
=> nil o próprio objeto classe
59. Métodos de Classe
>> class Pessoa Existem métodos de
>> attr_accessor :nome classe que auxiliam
>> end
=> nil
na criação de
métodos
>> p = Pessoa.new (metaprogramação)
=> #<Pessoa:0x58fc00> acessores e
modificadores:
>> p.nome = "Joaquim"
=> "Joaquim"
attr_accessor
>> puts p.nome attr_reader
Joaquim attr_writer
=> nil
60. Mais OO
>> class Animal
>> def come
>> "comendo"
>> end
>> end
=> nil
>> class Pato < Animal Ruby tem suporte à
>> def quack herança simples de
>> "Quack!" classes
>> end
>> end
=> nil
>> pato = Pato.new
=> #<Pato:0x555dac>
>> pato.come
=> "comendo"
61. Mais OO
>> class PatoNormal
>> def faz_quack
>> "Quack!"
>> end
>> end
=> nil Como a tipagem em
>> class PatoEstranho Ruby não é
>> def faz_quack explícita, não
>> "Queeeeck!" precisamos declarar
>> end
>> end
quais são os tipos
=> nil dos atributos e/ou
>> class CriadorDePatos parâmetros
>> def castiga(pato)
>> pato.faz_quack
>> end
>> end
=> nil
62. Mais OO
>> pato1 = PatoNormal.new
=> #<PatoNormal:0x5332e8> Duck Typing:
>> pato2 = PatoEstranho.new Para o criador de
=> #<PatoEstranho:0x52ed10> patos, não interessa
>> c = CriadorDePatos.new
que objeto será passado
=> #<CriadorDePatos:0x529cfc>
>> c.castiga(pato1) como parâmetro, basta
=> "Quack!" que ele saiba grasnar.
>> c.castiga(pato2)
=> "Queeeeck!"
“If it walks like a duck and quacks like a
duck, I would call it a duck.”
63. Módulos
>> module Util
>> module Validadores
>>
>> class ValidadorDeCpf
Módulos podem ser
>> # ... usados como
?> end namespaces
>> (organizadores de
>> class ValidadorDeRg
classes)
>> # ...
?> end
>> end
>> end
=> nil
>> validador = Util::Validadores::ValidadorDeCpf
=> Util::Validadores::ValidadorDeCpf
64. Módulos
>> module Comentavel
>> def comentarios
>> @comentarios ||= []
>> end
>> def recebe_comentario(comentario)
>> self.comentario << comentario Ou como mixins,
>> end conjunto de métodos a
>> end
=> nil
ser incluso em outras
>> class Revista classes.
>> include Comentavel
>> # ...
?> end Se o método extend for
=> Revista utilizado, os métodos
>> revista = Revista.new
=> #<Revista:0x31d3a0>
do módulo estarão
>> revista.recebe_comentario("muito ruim!") disponíveis para a
=> ["muito ruim!"] classe e não para suas
>> puts revista.comentarios
muito ruim!
instâncias
=> nil
66. Operadores condicionais
>> a = 0
=> 0 If / elsif / else / end
>> if a == 0
>> print "zero"
>> elsif a == 1 Não é necessário o uso do “then”
>> print "um"
>> else
?> print "nao sei que numero eh este"
>> end
zero=> nil
>> b = 5 if a != 1 O “if” pode também ser utilizado no
=> 5 final de uma instrução
67. Operadores condicionais
>> a = 1
=> 1 unless / else / end
>> unless a == 0
>> print "nao eh zeron"
>> else O unless é um “facilitador” para um “if not”
?> print "a eh zeron"
>> end
nao eh zero Também pode ser utilizado no final de uma instrução
=> nil
>> b = 6 unless b
=> nil
Deve-se tomar cuidado com o uso do unless na definição de valores
>> b = 7 unless b
de variáveis se o valor esperado delas for um valor booleano
=> nil
68. Operadores condicionais
>> a = 5
=> 5 case / when / else / end
>> case a
>> when 1..3
>> puts "a entre 1 e 3n"
>> when 4
case é um “facilitador” para uma
>> puts "a = 4n"
sequência de elsif
>> else
?> puts "nenhuma das anterioresn"
>> end
nenhuma das anteriores
=> nil
69. Operadores condicionais
>> a = "b"
=> "b"
>> case a Pode ser utilizado com qualquer tipo de objeto e não
>> when "a" apenas com números
>> puts "an"
>> when "b"
>> puts "bn"
>> else
?> puts "outra letran"
>> end
b
=> nil Só não é possível misturar objetos
71. Operadores de loop
Operador Descrição
break Sai do loop atual
next Executa o próximo passo do loop
return Sai do loop e do método atual
redo Reinicia o loop atual
72. Loops
>> i = %w{a b c d e f}
=> ["a", "b", "c", "d", "e", "f"]
>> while b = i.pop
>> puts b while
>> end
f
e
d Permite o controle da condição do loop, podendo ser utilizado
c com qualquer condição booleana, derivada da comparação de
b qualquer tipo de objeto
a
=> nil
# Isto é apenas um exemplo (use “each”!)
73. Loops
>> for i in 1..5
>> puts i for
>> end
1
2
3 Usado para repetir um bloco por um número conhecido de vezes.
4 Pouco usado em Ruby, pois, para se iterar sobre coleções, usam-
5 se os métodos aproriados, como, por exemplo, each.
=> 1..5
# Experimente: 5.times { |i| puts i+1 }
74. Loops
>> for a in %w{a b c d}
>> puts a
>> end for
a
b
c
d
=> ["a", "b", "c", "d"]
# Experimente: %w{a b c d}.each {|item| puts item}
75. Loops
>> i = 5
=> 5
>> until i==0 until
>> puts i
>> i -= 1
>> end
5
4 O until é o contrário do while: ele repete o bloco de código até
3 que a condição seja verdadeira
2
1
=> nil
76. Loops
>> i = 0
=> 0
>> begin begin
?> puts i
>> i += 1
>> end while i < 0
0
=> nil Utlizado em conjunto com o while ou until quando se deseja que
o bloco seja executado pelo menos uma vez
77. Loops
>> loop do
?> puts "a" loop
>> break if true
>> end
a
=> nil
É o laço mais flexível. Ele será executado até que encontre um
comando break ou return no bloco
78. Padrões/Convenções
Métodos que retornam booleanos costumam terminar com ?,
para que pareçam perguntas aos objetos:
aluno.respond_to? :aprende
texto.empty?
Métodos que têm efeito colateral geralmente terminam com !
(bang)
conta.cancela!
79. Padrões/Convenções
A comparação entre objetos é feita através do método ==
(sim, é um método!). A versão original apenas verifica se as
referências apontam para os mesmos objetos. Pode-se
reescrever este comportamento:
>> class Pessoa
>> def ==(outra)
>> self.cpf == outra.cpf
>> end
>> end
=> nil
80. Padrões/Convenções
Na definição de métodos, procure usar os parênteses. Para a
chamada, prefira o que lhe for mais legível.
Nomes de variáveis, métodos e nomes de arquivos
(terminados com .rb) em Ruby são sempre minúsculos e
separados por “_”.
Variáveis com nomes maiúsculos são sempre constantes.
Para nomes de classes, utilize as regras de CamelCase
81. Padrões/Convenções
Módulos seguem o padrão de nomenclatura de classes
Métodos de leitura de uma variável de instância têm o
mesmo nome da variável, sem o caracter @ no início, e
métodos de escrita têm o mesmo nome terminado em =
Métodos que transformam um objeto em outro tem o nome
iniciado por “to_”, p.ex., to_s, to_i, to_a, to_sym
82. Arquivos Ruby
Todos arquivos fonte contendo código Ruby devem ter a extensão .rb.
Para carregar o código Ruby de outro arquivo, basta usar o método
require:
require ‘meu_outro_fonte’
puts ObjetoDefinidoFora.new.algum_metodo
O Ruby procura pelo arquivo em alguns diretórios pré-defindos (Ruby
Load Path), incluindo o diretório atual. Caminhos relativos ou
absolutos podem ser udados para incluir arquivos em outros diretórios:
require ‘modulo/funcionalidades/coisa_importante’
require ‘/usr/local/lib/my/libs/ultra_parser
83. Arquivos Ruby
A constante $:, ou $LOAD_PATH, contém diretórios do Load
Path:
$:
=> ["/Library/Ruby/Site/1.8", "/Library/Ruby/
Site/1.8/powerpc-darwin9.0", ..., “.”]
O comando require carrega o arquivo apenas uma
vez. Para executar o conteúdo do arquivo diversas vezes, use
load ‘meu_outro_arquivo.rb’
load ‘meu_outro_arquivo.rb’
# executado 2 vezes!
84. Referência
Urubatan, Rodrigo. “Ruby on Rails: desenvolvimento fácil e
rápido de aplicação Web”. Novatec Editora. 2009.
Apostila do Curso de Ruby. Empresa Caelum. 2008.