Introdução à Linguagem Ruby

7,344 views

Published on

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.

Published in: Technology

Introdução à Linguagem Ruby

  1. 1. Introdução ao Ruby Eduardo Nicola F. Zagari
  2. 2. Sumário Instalação, Primeiros Passos, Variáveis e Escopo Tipos Básicos Constantes Módulos Operadores Condicionais e Loops Operadores de Loop
  3. 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
  4. 4. Documentação do Ruby http://apidock.com/ruby http://www.ruby-doc.org/core/
  5. 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. 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. 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. 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
  9. 9. Primeiros Passos Object tem o método methods, que retorna um array com todos os métodos disponíveis da classe: >> 1.methods => ["inspect", "%", "<<", "singleton_method_added", "&", "clone", "method", ">>", "round", "public_methods", "rdiv", "instance_variable_defined?", "divmod", "equal?", "freeze", "integer?", "chr", "*", "+", "to_i", "methods", "respond_to?", "numerator", "-", "upto", "between?", "prec", "truncate", "/", "dup", "instance_variables", "rpower", "taguri", "__id__", "modulo", "object_id", "succ", "|", "eql?", "zero?", "id", "~", "taguri=", "to_f", "singleton_methods", "send", "prec_i", "taint", "step", "to_int", "frozen?", "instance_variable_get", "__send__", "instance_of?", "^", "remainder", "to_yaml_style", "to_a", "+@", "nonzero?", "-@", "type", "**", "floor", "<", "protected_methods", "instance_eval", "<=>", "lcm", "==", "prec_f", "power!", "quo", ">", "display", "===", "downto", "id2name", "size", "instance_variable_set", "kind_of?", "extend", "abs", ">=", "next", "to_s", "<=", "denominator", "coerce", "hash", "ceil", "class", "to_yaml", "tainted?", "=~", "private_methods", "gcdlcm", "div", "to_yaml_properties", "nil?", "untaint", "gcd", "times", "to_sym", "soma", "[]", "to_r", "is_a?"]
  10. 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. 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
  12. 12. Tipos Básicos Blocos de código Procs Números Valores booleanos Strings
  13. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  24. 24. Números >> i = 1 => 1 >> i.class => Fixnum >> i1 = 1.1 => 1.1 >> i1.class => Float >> i2 = 111_222_333 => 111222333 >> i2.class => Fixnum >> i3=999999999999999999999 => 999999999999999999999 >> i3.class => Bignum
  25. 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. 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. 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. 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. 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"
  30. 30. Constantes Intervalos numéricos Arrays Hashes Símbolos Expressões regulares Classes e métodos Métodos de classe
  31. 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. 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. 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"]
  34. 34. Arrays >> arr.methods => ["select", "[]=", "inspect", "compact", "<<", "&", "clone", "method", "last", "public_methods", "partition", "empty?", "delete_if", "instance_variable_defined?", "equal?", "freeze", "each_index", "*", "grep", "+", "sort!", "assoc", "to_ary", "methods", "respond_to?", "-", "reject", "push", "insert", "reverse!", "dup", "delete", "instance_variables", "taguri", "concat", "member?", "__id__", "object_id", "pack", "reverse_each", "|", "find", "eql?", "join", "collect!", "rassoc", "each_with_index", "id", "at", "compact!", "taguri=", "singleton_methods", "index", "collect", "send", "reject!", "flatten", "all?", "slice", "taint", "pop", "length", "entries", "instance_variable_get", "transpose", "frozen?", "include?", "__send__", "instance_of?", "to_yaml_style", "detect", "to_a", "indexes", "uniq", "zip", "map!", "type", "fetch", "protected_methods", "instance_eval", "map", "<=>", "values_at", "rindex", "any?", "==", "display", "===", "shift", "size", "sort", "instance_variable_set", "clear", "min", "kind_of?", "extend", "indices", "find_all", "to_s", "each", "class", "slice!", "first", "hash", "flatten!", "to_yaml", "tainted?", "=~", "delete_at", "replace", "inject", "private_methods", "nitems", "reverse", "to_yaml_properties", "nil?", "untaint", "unshift", "sort_by", "fill", "max", "is_a?", "uniq!", "[]", "yaml_initialize"]
  35. 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. 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. 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. 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. 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. 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. 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
  42. 42. Hashes >> h.methods.sort => ["==", "===", "=~", "[]", "[]=", "__id__", "__send__", "all?", "any?", "class", "clear", "clone", "collect", "default", "default=", "default_proc", "delete", "delete_if", "detect", "display", "dup", "each", "each_key", "each_pair", "each_value", "each_with_index", "empty?", "entries", "eql?", "equal?", "extend", "fetch", "find", "find_all", "freeze", "frozen?", "grep", "has_key?", "has_value?", "hash", "id", "include?", "index", "indexes", "indices", "inject", "inspect", "instance_eval", "instance_of?", "instance_variable_defined?", "instance_variable_get", "instance_variable_set", "instance_variables", "invert", "is_a?", "key?", "keys", "kind_of?", "length", "map", "max", "member?", "merge", "merge!", "method", "methods", "min", "nil?", "object_id", "parametros_variaveis", "partition", "private_methods", "protected_methods", "public_methods", "rehash", "reject", "reject!", "replace", "respond_to?", "select", "send", "shift", "singleton_methods", "size", "sort", "sort_by", "store", "taguri", "taguri=", "taint", "tainted?", "to_a", "to_hash", "to_s", "to_yaml", "to_yaml_properties", "to_yaml_style", "type", "untaint", "update", "value?", "values", "values_at", "yaml_initialize", "zip"]
  43. 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. 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. 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. 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. 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. 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"
  49. 49. Expressões Regulares >> "Zagari".gsub(/ri/,"rI") => "ZagarI" >> er = /.*/ => /.*/ >> er.methods => ["inspect", "clone", "method", "public_methods", "instance_variable_defined?", "equal?", "freeze", "match", "methods", "respond_to?", "casefold?", "dup", "instance_variables", "taguri", "options", "__id__", "object_id", "eql?", "~", "parametros_variaveis", "id", "taguri=", "singleton_methods", "send", "taint", "frozen?", "instance_variable_get", "__send__", "instance_of?", "to_yaml_style", "kcode", "to_a", "type", "protected_methods", "instance_eval", "==", "display", "===", "instance_variable_set", "kind_of?", "extend", "to_s", "hash", "class", "to_yaml", "tainted?", "=~", "private_methods", "to_yaml_properties", "source", "nil?", "untaint", "is_a?"]
  50. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  65. 65. Operadores condicionais if / elsif / else / end case / when / else / end
  66. 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. 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. 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. 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
  70. 70. Loops while for until begin loop Padrões importantes
  71. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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.

×