Curso Ruby

5,075 views

Published on

Mini-curso de Introdução à Linguagem Ruby

Published in: Technology
  • Be the first to comment

Curso Ruby

  1. 1. Curso de Ruby Regis Pires Magalhães [email_address] “ A melhor forma de prever o futuro é inventá-lo.” Alan Kay
  2. 2. Overview <ul><li>Ruby – histórico, características, implementações, instalação, irb
  3. 3. Entrada / Saída
  4. 4. Comentários
  5. 5. Convenções
  6. 6. Variáveis, Constantes
  7. 7. Operadores
  8. 8. Tipos
  9. 9. Estruturas de Controle
  10. 10. Orientação a Objetos no Ruby
  11. 11. Meta-programação
  12. 12. Tratamento de Exceções
  13. 13. Módulos
  14. 14. Mixin
  15. 15. Procs
  16. 16. Fechamento ou Closure </li></ul>
  17. 17. Ruby <ul><li>1993 – Yukihiro Matsumoto – Matz
  18. 18. Matz nasceu no Japão em 1965.
  19. 19. Junta as melhores partes de gigantes do passado e do presente.
  20. 20. Mais usada no Japão que Python.
  21. 21. Popularizada pelo Rails. </li></ul>
  22. 22. Ruby Segundo Matz: “ Ruby é uma linguagem de scripting interpretada cujo objetivo é tornar a programação orientada a objetos simples e rápida. (...) É simples, direta, extensível e portável.” Fonte: http://www2.ruby-lang.org/en/20020101.html
  23. 23. Ruby – Características <ul><li>Dinâmica;
  24. 24. Tipagem forte;
  25. 25. Livre / Open Source;
  26. 26. Foco na simplicidade e produtividade ;
  27. 27. Programação divertida ;
  28. 28. Interpretada;
  29. 29. Mixins, blocos e fechamentos;
  30. 30. Totalmente orientada a objetos.
  31. 31. Classes e objetos são abertos para redefinições a qualquer momento </li></ul>
  32. 32. Implementações do Ruby <ul><li>MRI – Matz Runtime Interpreter
  33. 33. JRuby – Implementação em Java
  34. 34. YARV – Máquina Virtual – Versão 1.9 </li><ul><li>Bytecode interpreter
  35. 35. Rails ≈ 15% mais rápido que com Ruby 1.8.6 </li></ul><li>Rubinius – Extensões em Ruby
  36. 36. IronRuby – Implementação em .NET
  37. 37. MagLev – Ruby sobre VM da GemStone (excelente VM SmallTalk) </li></ul>
  38. 38. Instalação do Ruby 1 – No Linux – 2 alternativas: <ul><li>Compilar no braço: </li><ul><li>ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p22.tar.bz2 </li></ul></ul>tar xjvf ruby-1.8.7-p22.tar.bz2 ./configure make make install <ul><li>Via apt-get ou Synaptic (modo gráfico) no Ubuntu: </li></ul>sudo apt-get install ruby rubygems irb ri rdoc ruby1.8-dev build-essential sudo apt-get install libmysql-ruby libpgsql-ruby libsqlite3-ruby
  39. 39. Instalação do Ruby 2 – No Windows : One-Click Installer <ul><ul><ul><li>Já vem com RubyGems, editor de textos e alguns outros adicionais. </li></ul></ul></ul>http://rubyforge.org/frs/download.php/72085/rubyinstaller-1.8.7-p302.exe
  40. 40. Instalação do Ruby 3 – No Windows ou Linux: <ul><ul><li>Easy Rails = Ruby + Rails + Mongrel. </li><ul><li>Roda no Windows e Linux. </li></ul></ul></ul>http://rubyforge.org/frs/download.php/57834/easy-rails-0.9.5.exe http://rubyforge.org/frs/download.php/72564/easy-rails-linux-0.9.3.md5
  41. 41. Testando o Ruby ruby -v
  42. 42. irb - interactive ruby <ul><li>Interpretador interativo do Ruby.
  43. 43. Permite executar trechos de códigos Ruby, retornando o resultado de imediato. </li></ul>C : InstantRails rails_apps > irb irb ( main ) :001:0 > a = 123 => 123 irb ( main ) :002:0 > b = 456 => 456 irb ( main ) :003:0 > a * b => 56088 irb ( main ) :004:0 >
  44. 44. irb – ativando o auto-complemento irb ( main ) :010:0 > require 'irb/completion' => true ~ $ irb - r irb / completion <ul><li>Ao executar o irb:
  45. 45. Com o irb já em execução: </li></ul>
  46. 46. Totalmente orientada a objetos <ul><li>Não há tipos primitivos.
  47. 47. Qualquer coisa que não seja executado dentro de um método, está implicitamente sendo executado dentro do método main da classe Object . </li></ul>irb ( main ) :001:0 > puts self . class Object => nil irb ( main ) :002:0 > puts self main => nil
  48. 48. Totalmente orientada a objetos 1.class # => Fixnum 1.class . class # => Class 1.class . superclass # => Integer
  49. 49. Totalmente orientada a objetos <ul><li>1 é instância da classe Fixnum.
  50. 50. A classe Fixnum é instância da classe Class.
  51. 51. Class define todas as classes em Ruby.
  52. 52. Class é uma metaclasse, ou seja, uma classe que descreve uma classe.
  53. 53. Hierarquia: </li><ul><li>Classes: Object => Numeric => Integer => Fixnum
  54. 54. Metaclasses: Object => Module => Class </li></ul></ul>
  55. 55. Totalmente orientada a objetos <ul><li>Todo valor é um objeto e possui métodos. </li></ul>1.to_s # => &quot;1&quot; 1 + 1 # => 2 1. +( 1 ) # => 2 - 1.abs # => 1 &quot;123&quot; . length # => 3
  56. 56. <ul><li>Até mesmo classes são objetos.
  57. 57. Exemplo.methods é diferente de Exemplo.new.methods . </li></ul>Totalmente orientada a objetos Object . class # => Class class Exemplo ; end Exemplo . class # => Class Exemplo . methods # => [...]
  58. 58. O método methods 1.methods.sort 1.public_methods.sort 1.protected_methods.sort 1.private_methods.sort String.methods.sort
  59. 59. Entrada / Saída nome = gets . chomp Pedro # => &quot;Pedro&quot; puts nome Pedro # => nil chomp -> mastigar, roer
  60. 60. Comentários x = y + 5 # Isto é um comentário de linha. # Isto é um outro comentário de linha. =begin Isto é um comentário de bloco. =end
  61. 61. Convenções NomesDeClasse nomes_de_metodos e nomes_de_variaveis metodos_fazendo_pergunta? metodos_perigosos! @variaveis_de_instancia @@variaveis_de_classe $variaveis_globais ALGUMAS_CONSTANTES ou OutrasConstantes
  62. 62. Variáveis <ul><li>São tipadas dinamicamente: a = 4
  63. 63. São fortemente tipadas: 2 + &quot;2&quot; não é possível.
  64. 64. Variáveis locais: quantidade_dias = 3
  65. 65. Variáveis globais: </li></ul>$caminho = &quot;/home/curso&quot; <ul><li>Variáveis de instância: @nome = &quot;Maria&quot;
  66. 66. Variáveis de classe: </li></ul>@@vogais = ['a', 'e', 'i', 'o', 'u']
  67. 67. Variáveis <ul><li>Variáveis não precisam ser declaradas.
  68. 68. Variáveis são referências para objetos. </li></ul>~ $ irb irb ( main ) :001:0 > a = 1 => 1 irb ( main ) :002:0 > a = &quot;1&quot; => &quot;1&quot; '
  69. 69. Operadores <ul><li>Aritméticos: +, -, *, /, %, ** ... etc
  70. 70. Igualdade e comparação: >, >=, <, <=, ==, <=> ... etc.
  71. 71. Atribuição: =, +=, -=, *=, /=, ||= ... etc.
  72. 72. Lógico: &&, and, ||, or, !, not ... etc.
  73. 73. Ternário: </li></ul>(a == 2 ? &quot;Dois&quot; : &quot;Outra coisa&quot;)
  74. 74. Operadores <ul><li><=> </li><ul><li>Operador de comparação. Retorna -1, 0 ou 1 se for menor, igual ou maior que seu argumento. </li></ul><li>=~ </li><ul><li>Usado para associar padrões em expressões regulares. </li></ul></ul>'Curso de Ruby' =~ /de/ # => 6 <ul><li>||= </li></ul>cont ||= 0 # cont = cont || 0 <ul><ul><li>Resulta em 0 se cont não tiver um valor. </li></ul></ul>
  75. 75. Constantes <ul><li>Também carregam uma referência para um Objeto
  76. 76. Devem iniciar em caixa alta: PI = 3.14
  77. 77. Por convenção possuem todas as letras em caixa alta!
  78. 78. Podem ser alteradas: </li></ul>NOME = &quot;Sapo&quot; NOME = &quot;Gato&quot; # Gera um alerta warning: already initialized constant NOME
  79. 79. Tipos <ul><li>Números
  80. 80. Booleanos
  81. 81. nil
  82. 82. Strings
  83. 83. Ranges
  84. 84. [Arrays]
  85. 85. {Hashes}
  86. 86. :simbolos
  87. 87. Expressões Regulares </li></ul>
  88. 88. Números <ul><li>Ruby suporta tanto inteiros quanto ponto-flutuantes
  89. 89. Eles podem ter qualquer tamanho </li></ul>O tamanho do inteiro é que define seu tipo: n = 1000000 # => 1000000 n . class # => Fixnum n = 1000000000000000 # => 1000000000000000 n . class # => Bignum
  90. 90. Números 1.class # => Fixnum 1.0 . class # => Float 1_000_000.class # => Fixnum 1_000_000_000 * 1_000_000_000 # => 1000000000000000000 ( 1_000_000_000 * 1_000_000_000 ). class # => Bignum <ul><li>Ruby permite números de tamanho arbitrário.
  91. 91. A classe Bignum pode representar número com precisão infinita, restrita somente à memória e processamento da máquina. </li></ul>
  92. 92. Booleanos <ul><li>Há somente 2 instâncias que representam valores booleanos em Ruby: true e false . </li></ul>true . class # => TrueClass false . class # => FalseClass true . class . superclass # => Object false . class . superclass # => Object TrueClass . new NoMethodError : undefined method `new' for TrueClass:Class from (irb):17 from :0
  93. 93. nil <ul><li>O valor nulo é representado pelo objeto nil da classe NilClass . </li></ul>nil . class # => NilClass nil . class . superclass # => Object NilClass . new NoMethodError : undefined method `new' for NilClass:Class from (irb):21 from :0
  94. 94. Strings <ul><li>String é apenas uma sequência de bytes.
  95. 95. Pode carregar caracteres &quot;imprimíveis&quot; ou dados binários.
  96. 96. Podem ser delimitadas por aspas 'simples' ou &quot;duplas&quot;.
  97. 97. Podem ocupar várias linhas, sem precisar ficar concatenando. </li></ul>
  98. 98. Strings s = &quot;Curso de Ruby&quot; s [ 0 ] # => 67 s [ 0 ]. chr # => &quot;C&quot; s [ 6 , 2 ] # => &quot;de&quot; s [ 6 . . 7 ] # => &quot;de&quot;
  99. 99. Strings – Métodos Destrutivos a = &quot;Ruby&quot; # => &quot;Ruby&quot; a . object_id # => 20641550 a . upcase # => &quot;RUBY&quot; a # => &quot;Ruby&quot; a . upcase! # => &quot;RUBY&quot; a # => &quot;RUBY&quot; a . object_id # => 20641550 a.downcase! # => &quot;ruby&quot; a # => &quot;ruby&quot;
  100. 100. Strings são mutáveis s = &quot;Ruby&quot; # => &quot;Ruby&quot; s . object_id # => 20641550 s << &quot; on &quot; # => &quot;Ruby on &quot; s . object_id # => 20641550 <ul><li>Concatenação usando + resulta em outro objeto: </li></ul>s = s + &quot;Rails&quot; # => &quot;Ruby on Rails&quot; s . object_id # => 21074740
  101. 101. Strings – interpolação de valores <ul><li>Com aspas duplas podemos usar escapes especiais e interpolar códigos. </li></ul>nome = &quot;Pacheco&quot; # => &quot;Pacheco&quot; puts &quot;Oi, #{ nome } , Adorei a Escola da Ponte!&quot; # Oi, Pacheco, # Adorei a Escola da Ponte!
  102. 102. Strings longas nome = &quot;Descartes&quot; s = << FIM Penso, logo existo é uma frase de #{nome} FIM puts s # Penso, logo existo # é uma frase de Descartes
  103. 103. Strings a = &quot;valor&quot; # => &quot;valor&quot; 'aspas simples: #{a}' # => &quot;aspas simples: #{a}&quot; &quot;aspas duplas: #{ a } &quot; # => &quot;aspas duplas: valor&quot; %( marcadores especiais : #{a}) # => &quot;marcadores especiais: valor&quot; s = << FIM string com quebra de linha FIM # => &quot;string com quebra de linha &quot; 'sem interpolacao,' &quot;interpolacao e contrabarras&quot; %q(sem interpolacao) %Q(interpolacao e contrabarras) %(interpolacao e contrabarras)
  104. 104. Comparação de Strings a = &quot;Uma string qualquer&quot; b = String . new ( &quot;Uma string qualquer&quot; ) a == b # => true
  105. 105. Strings - Métodos s = &quot;Ruby on Rails&quot; s . gsub ( ' ' , '-' ) # => &quot;Ruby-on-Rails&quot; s . gsub ( /[aeiou]/ , '_' ) # => &quot;R_by _n R__ls&quot; s . index ( 'on' ) # => 5 &quot;hello &quot; . chomp #=> &quot;hello&quot; &quot;hello there&quot; . chomp #=> &quot;hello there&quot; &quot;hello&quot; . chomp ( &quot;llo&quot; ) #=> &quot;he&quot; s = 'Ruby on Rails' s [ 5 , 2 ] # => &quot;on&quot; s [ 5..6 ] # => &quot;on &quot; &quot;Ruby&quot; .reverse # => &quot;ybuR&quot;
  106. 106. Ranges <ul><li>É um tipo da linguagem que representa um intervalo de valores: crianca = 0..10
  107. 107. 1..7 inclui 1, 2, 3, 4, 5, 6 e 7
  108. 108. 1...7 não inclui o 7 </li></ul>&quot;Ruby&quot; [ 1 . . 2 ] # --> &quot;ub&quot; [ 1 , 2 , 3 , 4 , 5 ][ 1 . . 2 ] # --> [2,3] ( 2 . . 10 ) === 3 # true ( &quot;a&quot; .. &quot;z&quot; ). each {| i | puts i } for n in 5 . . 10 ; puts n ; end
  109. 109. [Arrays] <ul><li>Guardam uma coleção de objetos, cada um em uma posição </li></ul>a = [ 10 , 7.2 , &quot;Maria&quot; ] a . class # Array a [ 1 ] # 7.2 a . length # 3 a [- 1 ] # &quot;Maria&quot; a << 'Fim' a = Array . new a = [] a[ 4 ] = 'Ruby' a # => [nil, nil, nil, nil, &quot;Ruby&quot;]
  110. 110. [Arrays] irb ( main ) :009:0 > a = [ 1 , 2 , 3 ] => [ 1 , 2 , 3 ] irb ( main ) :010:0 > a . include? 2 => true irb ( main ) :011:0 > a . include? 4 => false <ul><li>Método include </li></ul>
  111. 111. [Arrays] a = [ 1 , 2 , 3 , 4 , 5 ] puts a 1 2 3 4 5 puts a.inspect [ 1 , 2 , 3 , 4 , 5 ]
  112. 112. %w – array de palavras a = %w(curso de ruby on rails) => [ &quot;curso&quot; , &quot;de&quot; , &quot;ruby&quot; , &quot;on&quot; , &quot;rails&quot; ] nome , sobrenome = 'regis' , 'pires' a = %w(#{ nome } #{ sobrenome }) => [ &quot;#{nome}&quot; , &quot;#{sobrenome}&quot; ] a = %W(#{ nome } #{ sobrenome }) => [ &quot;regis&quot; , &quot;pires&quot; ]
  113. 113. Arrays s = 'Ruby on Rails' s . split ( ' ' ) # => [&quot;Ruby&quot;, &quot;on&quot;, &quot;Rails&quot;] a = %w(um dois tres quatro cinco seis sete oito nove dez) => [ &quot;um&quot; , &quot;dois&quot; , &quot;tres&quot; , &quot;quatro&quot; , &quot;cinco&quot; , &quot;seis&quot; , &quot;sete&quot; , &quot;oito&quot; , &quot;nove&quot; , &quot;dez&quot; ] a . grep ( /s$/ ) => [ &quot;dois&quot; , &quot;tres&quot; , &quot;seis&quot; ]
  114. 114. Array de bytes b = 'Ruby' . bytes. to_a # => [82, 117, 98, 121] b. pack( &quot;c*&quot; ) # => &quot;Ruby&quot;
  115. 115. {Hashes} <ul><li>O mesmo que arrays associativos, mapas ou dicionários
  116. 116. Cada entrada é composta por uma chave (única) e um valor </li></ul>a = { 'um' => 1 , 'bola' => 2 , 3 => 'Maria' } a . class => Hash a [ 1 ] => nil a [ 'um' ] => 1 a . length => 3 a = Hash . new a = {}
  117. 117. :simbolos <ul><li>Identificador que corresponde a um nome.
  118. 118. Há apenas uma instância de cada um deles. </li></ul>&quot;vermelho&quot; . object_id != &quot;vermelho&quot; . object_id :vermelho . object_id == :vermelho . object_id <ul><li>São muito usados como chave nos Hashes </li></ul>pessoa = { :nome => 'Regis' , :idade => 17 , :profissao => 'Professor' } <ul><li>Imutáveis </li></ul>
  119. 119. :simbolos :nome . to_s # => &quot;nome&quot;
  120. 120. /Expressões Regulares/ <ul><li>Criadas com / , %r ou Regexp.new </li></ul>er = /^[0-9]/ er2 = %r{^[0-9]} er = Regexp.new(&quot;^[0-9]&quot;) <ul><li>Testadas com o operador de correspondência ( =~ ) ou o de não correspondência ( !~ ) </li></ul>&quot;123&quot; =~ er # => 0 &quot;123&quot; !~ er # => false &quot;abc&quot; =~ er # => nil &quot;abc&quot; !~ er # => true
  121. 121. Estruturas de Controle <ul><li>Falso é false e nil
  122. 122. then é opcional no if e unless
  123. 123. if elsif else end: </li></ul>if ( 1 != 2 ) puts &quot;Um nao eh dois&quot; end <ul><li>unless else end: </li></ul>unless ( 1 == 2 ) puts &quot;Um nao eh dois&quot; end
  124. 124. Estruturas de Controle puts 'ola' if not a or not b puts 'oi' unless y != 3 if x < 5 then puts 'menor que 5' end x = if a>0 then b else c end x = unless a<=0 then c else b end
  125. 125. Estruturas de Controle <ul><li>case when else end: </li></ul>case a when 1 : 'Um' else 'Outro' end
  126. 126. Estruturas de Controle case scale when 'C' , 'c' F = 1.8 * temp + 32 when 'F' , 'f' C = ( 5.0 / 9.0 ) * (temp- 32 ) else abort &quot;Must specify C or F.&quot; end
  127. 127. Estruturas de Controle <ul><li>do é opcional no while , until e for
  128. 128. while end: </li></ul>a = 0 while a < 5 a += 1 puts a end <ul><li>for in end: </li></ul>for a in 'a' .. 'f' puts a end
  129. 129. Estruturas de Controle list = [ 1 , 2 , 3 ] i= 0 while i < list.size do print &quot; #{list[i]} &quot; i += 1 end list = [ 1 , 2 , 3 ] i= 0 until i == list.size do print &quot; #{list[i]} &quot; i += 1 end
  130. 130. Laços contados 1.upto ( 10 ) { |x| puts x } 10.downto ( 1 ) { |x| puts x } 10.step ( 1 , - 2 ) { |x| puts x }
  131. 131. Métodos <ul><li>Sempre retornam alguma coisa </li><ul><li>Se um valor não for explicitamente retornado, nil é usado implicitamente. </li></ul><li>O return é opcional </li></ul>def soma ( a , b ) a + b end <ul><li>Chamamos assim: </li></ul>soma ( 1 , 2 ) ou soma 1 , 2
  132. 132. Métodos <ul><li>Os parâmetros podem ter valores opcionais ou default : </li></ul>def soma ( a , b = 1 ) a + b end soma ( 1 , 1 ) == soma ( 1 ) <ul><li>Array como lista de parâmetros de um método </li></ul>valores = [ 1 , 2 ] soma (* valores )
  133. 133. Métodos <ul><li>Os parâmetros podem ter quantidade variada (varargs): </li></ul>def campeao ( time , * anos ) puts &quot;O #{ time } foi campeão #{ anos . size } vezes&quot; end campeao ( 'Brasil' , 1958 , 1962 , 1970 , 1994 , 2002 ) <ul><li>Hashes são usados como parâmetro quando a lista é grande ou variada! </li></ul>open &quot;teste.txt&quot; , :create => true , :reset => false <ul><li>Retornando &quot;vários valores&quot; (arrays): </li></ul>nome , sobrenome = &quot;Regis Pires&quot; . split ( ' ' )
  134. 134. ola.rb def diga_ola ( nome ) if nome [ 0. . 3 ] == 'Matz' puts 'Ah, foi vc quem criou o Ruby!' else puts ( &quot;Ola #{ nome } &quot; ) end end print &quot;Qual o seu nome? &quot; nome = gets # Pede uma entrada do usuario diga_ola nome
  135. 135. Date require 'date' c = Date.today d = Date . new ( 2010 , 10 , 21 ) # => #<Date: 4910981/2,0,2299161> d . day # => 21 d .mon # => 10 d .month # => 10 d . year # => 2010 d .wda y # => 4 d .mda y # => 21 d . yday # => 294 d . to_s # => &quot;2010-10-21&quot; dt = DateTime.now t = Time.now
  136. 136. Arquivos f = File.new( &quot;teste.txt&quot; , &quot;w&quot; ) f << &quot;linha um &quot; f << &quot;linha dois &quot; f << &quot;linha tres &quot; f.close a = File.readlines( &quot;teste.txt&quot; ) => [ &quot;linha um &quot; , &quot;linha dois &quot; , &quot;linha tres &quot; ] a = File.readlines( &quot;teste.txt&quot; ).find_all {|l| l =~ /s$/} => [ &quot;linha dois &quot; , &quot;linha tres &quot; ]
  137. 137. UDP Server require 'socket' porta = 12345 s = UDPSocket.new s.bind( &quot;localhost&quot; ,porta) puts &quot;Servidor iniciado na porta #{porta} ...&quot; loop do msg,sender = s.recvfrom( 256 ) host = sender[ 3 ] puts &quot;Host #{host} enviou um pacote UDP: #{msg} &quot; end s.close
  138. 138. UDP Client require 'socket' porta = 12345 s = UDPSocket.open s.connect( &quot;localhost&quot; , porta) s.send(ARGV[ 0 ], 0 ) s.close
  139. 139. Blocos <ul><li>Um conjunto de instruções
  140. 140. São delimitados por {...} ou do...end .
  141. 141. Convenção: use {...} em uma só linha, e do...end para várias linhas.
  142. 142. Podem receber parâmetros: </li></ul>meu_array . each { | obj | puts obj } ( 1. . 10 ). each { | i | puts i } ( &quot;a&quot; .. &quot;z&quot; ). each { | i | puts i }
  143. 143. Blocos <ul><li>Podem ser passados como parâmetro: </li></ul>5.times { puts 'olá' } <ul><li>Podem receber parâmetros: </li></ul>5.times { | n | puts 'olá ' + n . to_s } <ul><li>Podem ser convertidos em objetos: </li><ul><li>Proc.new ou proc ou lambda . </li></ul><li>Muito usados no Ruby! </li></ul>
  144. 144. Arquivos com blocos de código File.open( &quot;teste.txt&quot; , 'w' ) do |f| f << &quot;linha um &quot; f << &quot;linha dois &quot; f << &quot;linha tres &quot; end File.readlines( &quot;teste.txt&quot; ).each {|l| puts l} File.open( &quot;teste.txt&quot; ) do |f| f.each_line do |l| print l end end Vantagem: não há perigo de esquecer o arquivo aberto, pois ele é fechado automaticamente.
  145. 145. Orientação a Objetos no Ruby <ul><li>Classes e Objetos
  146. 146. “Getters” e “Setters”
  147. 147. Variáveis de classe e de instância
  148. 148. Métodos de classe e de instância
  149. 149. Herança
  150. 150. Visibilidade dos Membros </li></ul>
  151. 151. Classes e Objetos <ul><li>Uma classe define um tipo de objeto.
  152. 152. Os objetos possuem dados (atributos/variáveis) e comportamentos (métodos).
  153. 153. Objetos também são chamados de instâncias.
  154. 154. 3, 12, 999 são instâncias da classe Fixnum. </li></ul>
  155. 155. Classes e Objetos <ul><li>&quot;Bola&quot;, 'Casa', 'b' são instâncias da classe String.
  156. 156. Usamos o ponto (.) para acessar os métodos: @pessoa.nome .
  157. 157. Instanciamos um objeto através do &quot;método construtor&quot; da sua classe: </li></ul>p = Pessoa . new 'Maria' , 54 <ul><li>Para alguns tipos básicos, não precisamos fazer isso: </li></ul>a = &quot;Bola&quot; ; b = 3 ; c = [ 1 , 2 , 9 ]
  158. 158. Classes e Objetos class Pessoa def initialize (nome, idade) @nome = nome @idade = idade end def to_s &quot; #{ @nome } tem #{ @idade } anos&quot; end end p1 = Pessoa . new ( &quot;Paulo&quot; , 12) p2 = Pessoa . new ( &quot;Marcio&quot; , 34 )
  159. 159. Classes e Objetos <ul><li>O método initialize é executado automaticamente quando new é usado.
  160. 160. initialize é automaticamente definido como private. </li></ul>
  161. 161. “Getters” e “Setters” <ul><li>Para permitir o acesso aos atributos, definimos métodos.
  162. 162. Ou utilizamos 'atalhos' para isso: attr_reader, attr_writter, attr_accessor . </li></ul>
  163. 163. “Getters” e “Setters” class Pessoa def initialize ( nome , idade ) @nome = nome @idade = idade end def nome= ( nome ) @nome = nome end def nome @nome end attr_accessor :idade end
  164. 164. Variáveis de classe e de instância <ul><li>O valor de uma variável de instância é exclusivo da instância, ou seja, p tem o seu nome ('Maria ...') e p2 tem o seu nome ('Mario ...')
  165. 165. O valor de uma variável de classe é compartilhado com as suas instâncias </li></ul>
  166. 166. Variáveis de classe e de instância class Pessoa @@numero_pessoas = 0 # Atrib de classe def initialize ( nome , idade ) @nome = nome # Atrib.de instância @idade = idade @@numero_pessoas += 1 end def numero_pessoas @@numero_pessoas end end
  167. 167. Métodos de classe e de instância <ul><li>Métodos também podem pertencer ao escopo de classe ou de instância.
  168. 168. Métodos de classe não acessam atributos de instância.
  169. 169. Método de instância: p.dados .
  170. 170. Método de classe: Pessoa.numero_pessoas ou self.numero_pessoas </li><ul><li>O uso de self facilita a alteração do nome da classe, evitando que a alteração também tenha que ser realizada nos métodos de classe. </li></ul><li>Observe que o new é um método de classe! </li></ul>
  171. 171. Métodos de classe <ul><li>Métodos de classe como Math.sin e File.delete são na verdade métodos de singleton , pois estão disponíveis apenas em um único objeto. </li><ul><li>Singleton, é um padrão de projeto (Design Pattern) que garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto.
  172. 172. Math é uma constante que referencia um objeto Module .
  173. 173. File é uma constante que referencia um objeto Class . </li></ul></ul>
  174. 174. Métodos de classe e de instância class Pessoa @@numero_pessoas = 0 def initialize ( nome , idade ) @nome = nome @idade = idade @@numero_pesssoas += 1 end def self . numero_pessoas @@numero_pessoas end end p = Pessoa . new 'Joao' , 23 p2 = Pessoa . new 'Maria' , 21 Pessoa . numero_pessoas # => 2 p .to_s # => &quot;Joao tem 23 anos&quot;
  175. 175. Métodos de uma única instância <ul><li>Também é possível escrever um método para um único objeto! </li></ul>p1 = Pessoa . new 'Joao' , 23 p2 = Pessoa . new 'Maria' , 21 def p1 . apresentacao &quot;Olá, sou o #{ @nome } &quot; end p1 . apresentacao # => &quot;Olá, sou o Joao&quot; p2 . apresentacao # => NoMethodError: ...
  176. 176. Herança <ul><li>Utilizamos quando queremos especializar uma classe.
  177. 177. A classe mais genérica é chamada de super-classe, e a mais específica de sub-classe.
  178. 178. Em Ruby existe apenas herança simples, embora possamos simular herança múltipla através de mixins.
  179. 179. O super chama o correspondente da super-classe. </li></ul>
  180. 180. Herança class B < A end
  181. 181. Herança class PessoaFisica < Pessoa def initialize ( nome , idade , cpf ) super ( nome , idade ) @cpf = cpf end # Método dados redefinido def to_s super + &quot;, Cpf= #{ @cpf } &quot; end end
  182. 182. Visibilidade dos Membros <ul><li>Os métodos podem ser: </li><ul><li>Públicos - chamados por qualquer um.
  183. 183. Protegidos - chamados apenas pela família.
  184. 184. Privados – chamados apenas no contexto do objeto atual. </li></ul><li>Em Ruby os atributos são sempre privados!
  185. 185. public , protected e private são métodos que modificam a classe dinamicamente e mantém o escopo de acesso até que outro escopo seja chamado. </li></ul>
  186. 186. Visibilidade dos Membros class MinhaClasse # Público é o default def metodo1 ... end protected # os seguintes serão protegidos def metodo2 ... end private # os seguintes serão privados def metodo3 ... end public # os seguintes serão públicos def metodo4 ... end end
  187. 187. Visibilidade dos Membros <ul><li>Também é possível fazer assim: </li></ul>class MinhaClasse def metodo1 ... end # os outros métodos public :metodo1 , :metodo4 protected :metodo2 private :metodo3 end
  188. 188. Meta-programação Cao = Class . new Cao . class_eval << FIM def latir puts &quot;Au, Au&quot; end FIM c = Cao . new # => #<Cao:0x2ae93c0> c . latir # => nil Au , Au Programação de programas que escrevem ou manipulam outros programas (ou a si próprios)
  189. 189. Meta-programação <ul><li>class <<obj </li><ul><li>Constrói um novo método somente para o objeto obj . </li></ul></ul>a = &quot;Hoje&quot; class << a def oi &quot;oi123&quot; end end a . oi # => &quot;oi123&quot;
  190. 190. Meta-programação class Object class << self def reader (* params ) for p in params self . class_eval &quot;def #{ p } ; @ #{ p } ; end&quot; end end end end Cria dinamicamente um “getter” semelhante a attr_reader.
  191. 191. Meta-programação <ul><li>eval </li></ul>a= 1 # => 1 b= 2 # => 2 c= 3 # => 3 formula= '(a+b+c)/3.0' # => &quot;(a+b+c)/3.0&quot; eval formula # => 2.0
  192. 192. Tratamento de Exceções <ul><li>begin . . . rescue . . . ensure . . . end </li></ul>begin z = x / y rescue TypeError => err print &quot;Erro de tipo&quot; rescue => err print &quot;Erro Geral&quot; ensure z = 3 end
  193. 193. Módulos <ul><li>São parecidos com classes.
  194. 194. Podem ter variáveis, constantes e métodos.
  195. 195. Não podem ser instanciados.
  196. 196. Benefícios: </li><ul><li>Fornecem um namespace, evitando conflito de nomes.
  197. 197. Permitem fazer mixin, ou seja, estender as funcionalidades de outras classes pela injeção de seu contexto. </li></ul><li>Normalmente, ficam em arquivo separado, e são carregados quando necessário. </li></ul>
  198. 198. Módulos # No arquivo calc.rb module Calc PI = 3.141592654 def self . seno ( x ) puts &quot;calc.seno de #{x}&quot; end def self . cosseno ( x ) puts &quot;calc.cosseno de #{x}&quot; end end # Em outro programa carregamos o arquivo # calc.rb usando require 'calc' # Chamamos métodos com &quot;.&quot; e constantes com &quot;::&quot; y = Calc . seno ( Calc :: PI / 4 )
  199. 199. Mixin <ul><li>Recurso que permite a injeção de novos métodos a classes ou instâncias. </li></ul>module Debug def quem_sou_eu? &quot; #{ self . class . name } : #{ self . to_s } &quot; end end class Livro include Debug end class PessoaFisica < Pessoa include Debug end livro = Livro . new ( &quot;Programming Ruby&quot; ) livro . quem_sou_eu? # => &quot;Livro: Programming Ruby &quot; pessoa = PessoaFisica . new ( &quot;Jose&quot; , 22 ) pessoa . quem_sou_eu? # => &quot;PessoaFisica: Jose, 22&quot;
  200. 200. Mixin module MyArray def hello puts &quot;Oi! #{ self . length } &quot; if self . respond_to? :length end end class String include MyArray end class Array include MyArray end str = 'teste' arr = [ 1 , 2 , 3 ] str . hello # &quot;Oi!5&quot; arr . hello # &quot;Oi!3&quot;
  201. 201. Carregamento de classes e módulos <ul><li>load </li><ul><li>Carrega um arquivo tantas vezes quanto seja executado.
  202. 202. load 'irb/completion.rb' </li></ul><li>require </li><ul><li>Carrega uma biblioteca, caso não tenha sido carregada ainda.
  203. 203. require 'irb/completion' </li></ul><li>include </li><ul><li>Faz o mixin de um ou mais módulos.
  204. 204. include Modulo1, Modulo2 </li></ul></ul>
  205. 205. Procs <ul><li>São blocos de código associados à uma variável.
  206. 206. Procs encapsulam blocos em objetos.
  207. 207. Pode-se usar Proc.new , proc ou lambda . </li></ul>vezes3 = Proc . new {| n | n * 3 } vezes3 . call ( 1 ) => 3 vezes3 . call ( 2 ) => 6 vezes3 . call ( 3 ) => 9
  208. 208. Procs <ul><li>Podemos transformar um bloco de código em uma Proc usando lambda ou proc: </li></ul>vezes3 = lambda {| n | n * 3 } vezes3 . call ( 1 ) => 3 vezes3 . call ( 2 ) => 6 vezes3 . call ( 3 ) => 9
  209. 209. Fechamento ou Closure <ul><li>É um bloco de código que pode ser passado como argumento a uma chamada de método.
  210. 210. Closures podem fazer referência a variáveis visíveis no momento em que elas foram definidas.
  211. 211. Closure = bloco de código + ligações ao ambiente do qual vieram.
  212. 212. São métodos anônimos com escopo fechado.
  213. 213. São métodos que carregam o contexto no qual foram criados.
  214. 214. O bloco pode usar todas as informações do seu contexto original mesmo que o ambiente no qual ele foi definido não mais exista. </li></ul>
  215. 215. Fechamento ou Closure def faz2 yield yield end faz2 { puts 'oi' }
  216. 216. Fechamento ou Closure class Array def each2 for element in self yield element end end end a = [ 1 , 2 , 3 ] a . each2 { | i | puts i }
  217. 217. Fechamento ou Closure salarios = [ 100 , 200 , 300 , 400 , 500 ] minimo = 300 salarios . each { | salario | puts salario if salario >= minimo } <ul><li>each é um método executado sobre o objeto salarios.
  218. 218. {| salario | puts salario if salario >= minimo } é a closure . </li><ul><li>Note que ela faz referência a uma variável que está fora da closure (minimo). </li></ul></ul>
  219. 219. Fechamento ou Closure def n_vezes ( algo ) Proc . new {| n | algo * n } end p1 = n_vezes 2 p1 . call ( 3 ) => 6 p1 . call ( 4 ) => 8 p2 = n_vezes 'Oi ' p2 . call ( 3 ) => &quot;Oi Oi Oi &quot;
  220. 220. Gem <ul><li>Uma gem é um pacote contendo uma biblioteca ou aplicação Ruby.
  221. 221. Rubygems é o projeto que desenvolveu o sistema de pacotes gem.
  222. 222. Simplifica bastante a instalação de bibliotecas em Ruby.
  223. 223. Listando as gems existentes: </li><ul><li>gem list </li></ul><li>Adicionando uma nova fonte de gems: </li><ul><li>gem sources -a http://gems.github.com </li></ul></ul>
  224. 224. Testes &quot;Sempre que estiver tentado a escrever um print ou uma expressão de depuração, escreva um teste.&quot; Martin Fowler
  225. 225. Testes class Retangulo def initialize (base, altura) @base = base @altura = altura end def area () @base * @altura end def perimetro () 2 * @base + 2 * @altura end end
  226. 226. Testes com RUnit # retangulo_test.rb require 'test/unit' require 'retangulo' class RetanguloTest < Test::Unit::TestCase def setup @r = Retangulo.new( 2 , 3 ) end def test_area assert_equal( 6 , @r .area) end def test_perimetro assert_equal( 10 , @r .perimetro) end def teardown @r = nil end end
  227. 227. Testes com RUnit <ul><li>Para executar: </li><ul><li>ruby retangulo_test.rb </li></ul></ul>
  228. 228. Rspec – Instalando gems <ul><li>gem install rspec -V
  229. 229. Para quem usa Ruby on Rails: </li><ul><li>gem install rspec-rails -V </li></ul></ul>
  230. 230. Testes com RSpec # retangulo_spec.rb require 'retangulo' describe Retangulo do before( :each ) do @r = Retangulo.new( 2 , 3 ) end it 'calcula area do retangulo' do @r .area.should == 6 end it 'calcula perimetro do retangulo' do @r .perimetro.should == 10 end after( :each ) do @r = nil end end
  231. 231. Testes com RSpec <ul><li>Para executar: </li><ul><li>rspec retangulo_spec.rb </li></ul></ul>
  232. 232. Referências <ul><li>Slides do Lucas de Castro sobre Ruby
  233. 233. Agile Web Development with Rails. 2ª Edição. </li><ul><li>Thomas e David Heinemeier Hansson. </li></ul><li>Conceitos de Ruby e Rails </li><ul><li>Gabriel Bogéa Perez (http://www.b2t.com.br) </li></ul><li>Tutorial de Ruby do TaQ </li><ul><li>http://www.eustaquiorangel.com/downloads/tutorialruby.pdf </li></ul><li>Crossing borders: Closures – Bruce Tate </li><ul><li>http://www.ibm.com/developerworks/java/library/j-cb01097.html </li></ul><li>Closure – Martin Fowler </li><ul><li>http://martinfowler.com/bliki/Closure.html </li></ul></ul>

×