Curso de Ruby  Regis Pires Magalhães [email_address] “ A melhor forma de prever o futuro é inventá-lo.” Alan Kay
Overview Ruby – histórico, características, implementações, instalação, irb
Entrada / Saída
Comentários
Convenções
Variáveis, Constantes
Operadores
Tipos
Estruturas de Controle
Orientação a Objetos no Ruby
Meta-programação
Tratamento de Exceções
Módulos
Mixin
Procs
Fechamento ou Closure
Ruby 1993 – Yukihiro Matsumoto – Matz
Matz nasceu no Japão em 1965.
Junta as melhores partes de gigantes do passado e do presente.
Mais usada no Japão que Python.
Popularizada pelo Rails.
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
Ruby – Características Dinâmica;
Tipagem forte;
Livre / Open Source;
Foco na  simplicidade  e  produtividade ;
Programação  divertida ;
Interpretada;
Mixins, blocos e fechamentos;
Totalmente orientada a objetos.
Classes e objetos são abertos para redefinições a qualquer momento
Implementações do Ruby MRI  – Matz Runtime Interpreter
JRuby – Implementação em Java
YARV – Máquina Virtual – Versão 1.9 Bytecode interpreter
Rails  ≈  15% mais rápido que com Ruby 1.8.6 Rubinius  – Extensões em Ruby
IronRuby  – Implementação em .NET
MagLev  – Ruby sobre VM da GemStone (excelente VM SmallTalk)
Instalação do Ruby 1 – No Linux  – 2 alternativas: Compilar no braço: ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p22.tar.bz2 tar xjvf ruby-1.8.7-p22.tar.bz2 ./configure make make install Via apt-get ou Synaptic (modo gráfico) no Ubuntu: sudo apt-get install ruby rubygems irb ri rdoc ruby1.8-dev build-essential sudo apt-get install libmysql-ruby libpgsql-ruby libsqlite3-ruby
Instalação do Ruby 2 – No Windows : One-Click Installer Já vem com RubyGems, editor de textos e alguns outros adicionais. http://rubyforge.org/frs/download.php/72085/rubyinstaller-1.8.7-p302.exe
Instalação do Ruby 3 – No Windows ou Linux: Easy Rails  = Ruby + Rails + Mongrel. Roda no Windows e Linux.  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
Testando o Ruby ruby -v
irb - interactive ruby Interpretador interativo do Ruby.
Permite executar trechos de códigos Ruby, retornando o resultado de imediato. 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 >
irb – ativando o auto-complemento irb ( main ) :010:0 >   require   'irb/completion' =>   true ~ $  irb   - r   irb / completion Ao executar o irb:
Com o irb já em execução:
Totalmente orientada a objetos Não há tipos primitivos.
Qualquer coisa que não seja executado dentro de um método, está implicitamente sendo executado dentro do método  main  da classe  Object . irb ( main ) :001:0 >   puts   self . class Object =>   nil irb ( main ) :002:0 >   puts   self main =>   nil
Totalmente orientada a objetos 1.class   # => Fixnum  1.class . class   # => Class  1.class . superclass   # => Integer
Totalmente orientada a objetos 1 é instância da classe Fixnum.
A classe Fixnum é instância da classe Class.
Class define todas as classes em Ruby.
Class é uma metaclasse, ou seja, uma classe que descreve uma classe.
Hierarquia: Classes:  Object => Numeric => Integer => Fixnum
Metaclasses:  Object => Module => Class
Totalmente orientada a objetos Todo valor é um objeto e possui métodos. 1.to_s   # => "1"  1   +   1   # => 2  1. +( 1 )   # => 2  - 1.abs   # => 1  "123" . length   # => 3
Até mesmo classes são objetos.
Exemplo.methods  é diferente de  Exemplo.new.methods . Totalmente orientada a objetos Object . class   # => Class  class   Exemplo ;   end   Exemplo . class   # => Class  Exemplo . methods   # => [...]
O método methods 1.methods.sort 1.public_methods.sort 1.protected_methods.sort 1.private_methods.sort String.methods.sort
Entrada / Saída nome   =   gets . chomp Pedro # => "Pedro" puts   nome Pedro # => nil chomp -> mastigar, roer
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
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
Variáveis São tipadas dinamicamente:  a = 4
São fortemente tipadas:  2 + "2"  não é possível.
Variáveis locais:  quantidade_dias = 3
Variáveis globais:  $caminho = "/home/curso" Variáveis de instância:  @nome = "Maria"
Variáveis de classe:  @@vogais = ['a', 'e', 'i', 'o', 'u']
Variáveis Variáveis não precisam ser declaradas.
Variáveis são referências para objetos. ~ $  irb   irb ( main ) :001:0 >   a   =   1   =>   1   irb ( main ) :002:0 >   a   =   "1"   =>   "1" '
Operadores Aritméticos:   +, -, *, /, %, **  ... etc
Igualdade e comparação:   >, >=, <, <=, ==, <=>  ... etc.
Atribuição:   =, +=, -=, *=, /=, ||=  ... etc.
Lógico:   &&, and, ||, or, !, not  ... etc.
Ternário: (a == 2 ? &quot;Dois&quot; : &quot;Outra coisa&quot;)
Operadores <=> Operador de comparação. Retorna -1, 0 ou 1 se for menor, igual ou maior que seu argumento. =~ Usado para associar padrões em expressões regulares. 'Curso de Ruby' =~ /de/   # => 6 ||= cont ||= 0   # cont = cont || 0 Resulta em 0 se cont não tiver um valor.
Constantes Também carregam uma referência para um Objeto
Devem iniciar em caixa alta:  PI = 3.14
Por convenção possuem todas as letras em caixa alta!
Podem ser alteradas: NOME   =   &quot;Sapo&quot; NOME   =   &quot;Gato&quot;   # Gera um alerta warning: already initialized constant NOME
Tipos Números
Booleanos
nil
Strings
Ranges
[Arrays]
{Hashes}
:simbolos
Expressões Regulares
Números Ruby suporta tanto inteiros quanto ponto-flutuantes
Eles podem ter qualquer tamanho O tamanho do inteiro é que define seu tipo: n   =   1000000   # => 1000000 n . class   # => Fixnum n   =   1000000000000000   # => 1000000000000000 n . class   # => Bignum
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  Ruby permite números de tamanho arbitrário.
A classe Bignum pode representar número com precisão infinita, restrita somente à memória e processamento da máquina.
Booleanos Há somente 2 instâncias que representam valores booleanos em Ruby:  true  e  false . 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
nil O valor nulo é representado pelo objeto  nil  da classe  NilClass . nil . class   # => NilClass nil . class . superclass   # => Object NilClass . new NoMethodError :   undefined   method   `new' for NilClass:Class from (irb):21 from :0
Strings String é apenas uma sequência de bytes.
Pode carregar caracteres &quot;imprimíveis&quot; ou dados binários.
Podem ser delimitadas por aspas  'simples'  ou  &quot;duplas&quot;.
Podem ocupar várias linhas, sem precisar ficar concatenando.
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;
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;
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 Concatenação usando  +  resulta em outro objeto: s   =   s   +   &quot;Rails&quot;   # => &quot;Ruby on Rails&quot; s . object_id   # => 21074740
Strings – interpolação de valores Com aspas duplas podemos usar escapes especiais e interpolar códigos. nome   =   &quot;Pacheco&quot;   # => &quot;Pacheco&quot; puts   &quot;Oi,  #{ nome } ,\nAdorei a Escola da Ponte!&quot; # Oi, Pacheco,  # Adorei a Escola da Ponte!
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
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\n quebra de linha\n&quot; 'sem interpolacao,' &quot;interpolacao e contrabarras&quot; %q(sem interpolacao) %Q(interpolacao e contrabarras) %(interpolacao e contrabarras)
Comparação de Strings a   =   &quot;Uma string qualquer&quot;   b   =   String . new ( &quot;Uma string qualquer&quot; )   a   ==   b   # => true
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\r\n&quot; . chomp   #=> &quot;hello&quot; &quot;hello \n there&quot; . chomp   #=> &quot;hello \n 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;
Ranges É um tipo da linguagem que representa um intervalo de valores:  crianca = 0..10
1..7  inclui 1, 2, 3, 4, 5, 6 e 7
1...7  não inclui o 7 &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
[Arrays] Guardam uma coleção de objetos, cada um em uma posição 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;]
[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 Método include
[Arrays] a   =   [ 1 ,   2 ,   3 ,   4 ,   5 ]   puts   a 1 2 3 4 5 puts   a.inspect [ 1 ,   2 ,   3 ,   4 ,   5 ]
%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; ]
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; ]
{Hashes} O mesmo que arrays associativos, mapas ou dicionários

Curso Ruby

  • 1.
    Curso de Ruby Regis Pires Magalhães [email_address] “ A melhor forma de prever o futuro é inventá-lo.” Alan Kay
  • 2.
    Overview Ruby –histórico, características, implementações, instalação, irb
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
    Ruby 1993 –Yukihiro Matsumoto – Matz
  • 18.
    Matz nasceu noJapão em 1965.
  • 19.
    Junta as melhorespartes de gigantes do passado e do presente.
  • 20.
    Mais usada noJapão que Python.
  • 21.
  • 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.
  • 24.
  • 25.
    Livre / OpenSource;
  • 26.
    Foco na simplicidade e produtividade ;
  • 27.
  • 28.
  • 29.
    Mixins, blocos efechamentos;
  • 30.
  • 31.
    Classes e objetossão abertos para redefinições a qualquer momento
  • 32.
    Implementações do RubyMRI – Matz Runtime Interpreter
  • 33.
  • 34.
    YARV – MáquinaVirtual – Versão 1.9 Bytecode interpreter
  • 35.
    Rails ≈ 15% mais rápido que com Ruby 1.8.6 Rubinius – Extensões em Ruby
  • 36.
    IronRuby –Implementação em .NET
  • 37.
    MagLev –Ruby sobre VM da GemStone (excelente VM SmallTalk)
  • 38.
    Instalação do Ruby1 – No Linux – 2 alternativas: Compilar no braço: ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p22.tar.bz2 tar xjvf ruby-1.8.7-p22.tar.bz2 ./configure make make install Via apt-get ou Synaptic (modo gráfico) no Ubuntu: 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.
    Instalação do Ruby2 – No Windows : One-Click Installer Já vem com RubyGems, editor de textos e alguns outros adicionais. http://rubyforge.org/frs/download.php/72085/rubyinstaller-1.8.7-p302.exe
  • 40.
    Instalação do Ruby3 – No Windows ou Linux: Easy Rails = Ruby + Rails + Mongrel. Roda no Windows e Linux. 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.
  • 42.
    irb - interactiveruby Interpretador interativo do Ruby.
  • 43.
    Permite executar trechosde códigos Ruby, retornando o resultado de imediato. 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.
    irb – ativandoo auto-complemento irb ( main ) :010:0 > require 'irb/completion' => true ~ $ irb - r irb / completion Ao executar o irb:
  • 45.
    Com o irbjá em execução:
  • 46.
    Totalmente orientada aobjetos Não há tipos primitivos.
  • 47.
    Qualquer coisa quenão seja executado dentro de um método, está implicitamente sendo executado dentro do método main da classe Object . irb ( main ) :001:0 > puts self . class Object => nil irb ( main ) :002:0 > puts self main => nil
  • 48.
    Totalmente orientada aobjetos 1.class # => Fixnum 1.class . class # => Class 1.class . superclass # => Integer
  • 49.
    Totalmente orientada aobjetos 1 é instância da classe Fixnum.
  • 50.
    A classe Fixnumé instância da classe Class.
  • 51.
    Class define todasas classes em Ruby.
  • 52.
    Class é umametaclasse, ou seja, uma classe que descreve uma classe.
  • 53.
    Hierarquia: Classes: Object => Numeric => Integer => Fixnum
  • 54.
    Metaclasses: Object=> Module => Class
  • 55.
    Totalmente orientada aobjetos Todo valor é um objeto e possui métodos. 1.to_s # => &quot;1&quot; 1 + 1 # => 2 1. +( 1 ) # => 2 - 1.abs # => 1 &quot;123&quot; . length # => 3
  • 56.
    Até mesmo classessão objetos.
  • 57.
    Exemplo.methods édiferente de Exemplo.new.methods . Totalmente orientada a objetos Object . class # => Class class Exemplo ; end Exemplo . class # => Class Exemplo . methods # => [...]
  • 58.
    O método methods1.methods.sort 1.public_methods.sort 1.protected_methods.sort 1.private_methods.sort String.methods.sort
  • 59.
    Entrada / Saídanome = gets . chomp Pedro # => &quot;Pedro&quot; puts nome Pedro # => nil chomp -> mastigar, roer
  • 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.
    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.
    Variáveis São tipadasdinamicamente: a = 4
  • 63.
    São fortemente tipadas: 2 + &quot;2&quot; não é possível.
  • 64.
    Variáveis locais: quantidade_dias = 3
  • 65.
    Variáveis globais: $caminho = &quot;/home/curso&quot; Variáveis de instância: @nome = &quot;Maria&quot;
  • 66.
    Variáveis de classe: @@vogais = ['a', 'e', 'i', 'o', 'u']
  • 67.
    Variáveis Variáveis nãoprecisam ser declaradas.
  • 68.
    Variáveis são referênciaspara objetos. ~ $ irb irb ( main ) :001:0 > a = 1 => 1 irb ( main ) :002:0 > a = &quot;1&quot; => &quot;1&quot; '
  • 69.
    Operadores Aritméticos: +, -, *, /, %, ** ... etc
  • 70.
    Igualdade e comparação: >, >=, <, <=, ==, <=> ... etc.
  • 71.
    Atribuição: =, +=, -=, *=, /=, ||= ... etc.
  • 72.
    Lógico: &&, and, ||, or, !, not ... etc.
  • 73.
    Ternário: (a ==2 ? &quot;Dois&quot; : &quot;Outra coisa&quot;)
  • 74.
    Operadores <=> Operadorde comparação. Retorna -1, 0 ou 1 se for menor, igual ou maior que seu argumento. =~ Usado para associar padrões em expressões regulares. 'Curso de Ruby' =~ /de/ # => 6 ||= cont ||= 0 # cont = cont || 0 Resulta em 0 se cont não tiver um valor.
  • 75.
    Constantes Também carregamuma referência para um Objeto
  • 76.
    Devem iniciar emcaixa alta: PI = 3.14
  • 77.
    Por convenção possuemtodas as letras em caixa alta!
  • 78.
    Podem ser alteradas:NOME = &quot;Sapo&quot; NOME = &quot;Gato&quot; # Gera um alerta warning: already initialized constant NOME
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
    Números Ruby suportatanto inteiros quanto ponto-flutuantes
  • 89.
    Eles podem terqualquer tamanho O tamanho do inteiro é que define seu tipo: n = 1000000 # => 1000000 n . class # => Fixnum n = 1000000000000000 # => 1000000000000000 n . class # => Bignum
  • 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 Ruby permite números de tamanho arbitrário.
  • 91.
    A classe Bignumpode representar número com precisão infinita, restrita somente à memória e processamento da máquina.
  • 92.
    Booleanos Há somente2 instâncias que representam valores booleanos em Ruby: true e false . 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.
    nil O valornulo é representado pelo objeto nil da classe NilClass . nil . class # => NilClass nil . class . superclass # => Object NilClass . new NoMethodError : undefined method `new' for NilClass:Class from (irb):21 from :0
  • 94.
    Strings String éapenas uma sequência de bytes.
  • 95.
    Pode carregar caracteres&quot;imprimíveis&quot; ou dados binários.
  • 96.
    Podem ser delimitadaspor aspas 'simples' ou &quot;duplas&quot;.
  • 97.
    Podem ocupar váriaslinhas, sem precisar ficar concatenando.
  • 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.
    Strings – MétodosDestrutivos 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.
    Strings são mutáveiss = &quot;Ruby&quot; # => &quot;Ruby&quot; s . object_id # => 20641550 s << &quot; on &quot; # => &quot;Ruby on &quot; s . object_id # => 20641550 Concatenação usando + resulta em outro objeto: s = s + &quot;Rails&quot; # => &quot;Ruby on Rails&quot; s . object_id # => 21074740
  • 101.
    Strings – interpolaçãode valores Com aspas duplas podemos usar escapes especiais e interpolar códigos. nome = &quot;Pacheco&quot; # => &quot;Pacheco&quot; puts &quot;Oi, #{ nome } ,\nAdorei a Escola da Ponte!&quot; # Oi, Pacheco, # Adorei a Escola da Ponte!
  • 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.
    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\n quebra de linha\n&quot; 'sem interpolacao,' &quot;interpolacao e contrabarras&quot; %q(sem interpolacao) %Q(interpolacao e contrabarras) %(interpolacao e contrabarras)
  • 104.
    Comparação de Stringsa = &quot;Uma string qualquer&quot; b = String . new ( &quot;Uma string qualquer&quot; ) a == b # => true
  • 105.
    Strings - Métodoss = &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\r\n&quot; . chomp #=> &quot;hello&quot; &quot;hello \n there&quot; . chomp #=> &quot;hello \n 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.
    Ranges É umtipo da linguagem que representa um intervalo de valores: crianca = 0..10
  • 107.
    1..7 inclui1, 2, 3, 4, 5, 6 e 7
  • 108.
    1...7 nãoinclui o 7 &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.
    [Arrays] Guardam umacoleção de objetos, cada um em uma posição 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.
    [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 Método include
  • 111.
    [Arrays] a = [ 1 , 2 , 3 , 4 , 5 ] puts a 1 2 3 4 5 puts a.inspect [ 1 , 2 , 3 , 4 , 5 ]
  • 112.
    %w – arrayde 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.
    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.
    {Hashes} O mesmoque arrays associativos, mapas ou dicionários
  • 115.
    Cada entrada écomposta por uma chave (única) e um valor a = { 'um' => 1 , 'bola' => 2 , 3 => 'Maria' } a . class => Hash a [ 1 ] => nil a [ 'um' ] => 1 a . length => 3 a = Hash . new a = {}
  • 116.
    :simbolos Identificador quecorresponde a um nome.
  • 117.
    Há apenas umainstância de cada um deles. &quot;vermelho&quot; . object_id != &quot;vermelho&quot; . object_id :vermelho . object_id == :vermelho . object_id São muito usados como chave nos Hashes pessoa = { :nome => 'Regis' , :idade => 17 , :profissao => 'Professor' } Imutáveis
  • 118.
    :simbolos :nome .to_s # => &quot;nome&quot;
  • 119.
    /Expressões Regulares/ Criadascom / , %r ou Regexp.new er = /^[0-9]/ er2 = %r{^[0-9]} er = Regexp.new(&quot;^[0-9]&quot;) Testadas com o operador de correspondência ( =~ ) ou o de não correspondência ( !~ ) &quot;123&quot; =~ er # => 0 &quot;123&quot; !~ er # => false &quot;abc&quot; =~ er # => nil &quot;abc&quot; !~ er # => true
  • 120.
    Estruturas de ControleFalso é false e nil
  • 121.
    then éopcional no if e unless
  • 122.
    if elsif elseend: if ( 1 != 2 ) puts &quot;Um nao eh dois&quot; end unless else end: unless ( 1 == 2 ) puts &quot;Um nao eh dois&quot; end
  • 123.
    Estruturas de Controleputs '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
  • 124.
    Estruturas de Controlecase when else end: case a when 1 : 'Um' else 'Outro' end
  • 125.
    Estruturas de Controlecase 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
  • 126.
    Estruturas de Controledo é opcional no while , until e for
  • 127.
    while end: a = 0 while a < 5 a += 1 puts a end for in end: for a in 'a' .. 'f' puts a end
  • 128.
    Estruturas de Controlelist = [ 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
  • 129.
    Laços contados 1.upto( 10 ) { |x| puts x } 10.downto ( 1 ) { |x| puts x } 10.step ( 1 , - 2 ) { |x| puts x }
  • 130.
    Métodos Sempre retornamalguma coisa Se um valor não for explicitamente retornado, nil é usado implicitamente. O return é opcional def soma ( a , b ) a + b end Chamamos assim: soma ( 1 , 2 ) ou soma 1 , 2
  • 131.
    Métodos Os parâmetrospodem ter valores opcionais ou default : def soma ( a , b = 1 ) a + b end soma ( 1 , 1 ) == soma ( 1 ) Array como lista de parâmetros de um método valores = [ 1 , 2 ] soma (* valores )
  • 132.
    Métodos Os parâmetrospodem ter quantidade variada (varargs): def campeao ( time , * anos ) puts &quot;O #{ time } foi campeão #{ anos . size } vezes&quot; end campeao ( 'Brasil' , 1958 , 1962 , 1970 , 1994 , 2002 ) Hashes são usados como parâmetro quando a lista é grande ou variada! open &quot;teste.txt&quot; , :create => true , :reset => false Retornando &quot;vários valores&quot; (arrays): nome , sobrenome = &quot;Regis Pires&quot; . split ( ' ' )
  • 133.
    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
  • 134.
    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
  • 135.
    Arquivos f = File.new( &quot;teste.txt&quot; , &quot;w&quot; ) f << &quot;linha um\n&quot; f << &quot;linha dois\n&quot; f << &quot;linha tres\n&quot; f.close a = File.readlines( &quot;teste.txt&quot; ) => [ &quot;linha um\n&quot; , &quot;linha dois\n&quot; , &quot;linha tres\n&quot; ] a = File.readlines( &quot;teste.txt&quot; ).find_all {|l| l =~ /s$/} => [ &quot;linha dois\n&quot; , &quot;linha tres\n&quot; ]
  • 136.
    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
  • 137.
    UDP Client require 'socket' porta = 12345 s = UDPSocket.open s.connect( &quot;localhost&quot; , porta) s.send(ARGV[ 0 ], 0 ) s.close
  • 138.
    Blocos Um conjuntode instruções
  • 139.
    São delimitados por {...} ou do...end .
  • 140.
    Convenção: use {...} em uma só linha, e do...end para várias linhas.
  • 141.
    Podem receber parâmetros:meu_array . each { | obj | puts obj } ( 1. . 10 ). each { | i | puts i } ( &quot;a&quot; .. &quot;z&quot; ). each { | i | puts i }
  • 142.
    Blocos Podem serpassados como parâmetro: 5.times { puts 'olá' } Podem receber parâmetros: 5.times { | n | puts 'olá ' + n . to_s } Podem ser convertidos em objetos: Proc.new ou proc ou lambda . Muito usados no Ruby!
  • 143.
    Arquivos com blocosde código File.open( &quot;teste.txt&quot; , 'w' ) do |f| f << &quot;linha um\n&quot; f << &quot;linha dois\n&quot; f << &quot;linha tres\n&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.
  • 144.
    Orientação a Objetosno Ruby Classes e Objetos
  • 145.
  • 146.
    Variáveis de classee de instância
  • 147.
    Métodos de classee de instância
  • 148.
  • 149.
  • 150.
    Classes e ObjetosUma classe define um tipo de objeto.
  • 151.
    Os objetos possuemdados (atributos/variáveis) e comportamentos (métodos).
  • 152.
    Objetos também sãochamados de instâncias.
  • 153.
    3, 12, 999são instâncias da classe Fixnum.
  • 154.
    Classes e Objetos&quot;Bola&quot;, 'Casa', 'b' são instâncias da classe String.
  • 155.
    Usamos o ponto(.) para acessar os métodos: @pessoa.nome .
  • 156.
    Instanciamos um objetoatravés do &quot;método construtor&quot; da sua classe: p = Pessoa . new 'Maria' , 54 Para alguns tipos básicos, não precisamos fazer isso: a = &quot;Bola&quot; ; b = 3 ; c = [ 1 , 2 , 9 ]
  • 157.
    Classes e Objetosclass 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 )
  • 158.
    Classes e ObjetosO método initialize é executado automaticamente quando new é usado.
  • 159.
    initialize é automaticamentedefinido como private.
  • 160.
    “Getters” e “Setters”Para permitir o acesso aos atributos, definimos métodos.
  • 161.
    Ou utilizamos 'atalhos'para isso: attr_reader, attr_writter, attr_accessor .
  • 162.
    “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
  • 163.
    Variáveis de classee de instância 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 ...')
  • 164.
    O valor deuma variável de classe é compartilhado com as suas instâncias
  • 165.
    Variáveis de classee 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
  • 166.
    Métodos de classee de instância Métodos também podem pertencer ao escopo de classe ou de instância.
  • 167.
    Métodos de classenão acessam atributos de instância.
  • 168.
  • 169.
    Método de classe: Pessoa.numero_pessoas ou self.numero_pessoas 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. Observe que o new é um método de classe!
  • 170.
    Métodos de classeMé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. 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.
  • 171.
    Math éuma constante que referencia um objeto Module .
  • 172.
    File éuma constante que referencia um objeto Class .
  • 173.
    Métodos de classee 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;
  • 174.
    Métodos de umaúnica instância Também é possível escrever um método para um único objeto! 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: ...
  • 175.
    Herança Utilizamos quandoqueremos especializar uma classe.
  • 176.
    A classe maisgenérica é chamada de super-classe, e a mais específica de sub-classe.
  • 177.
    Em Ruby existeapenas herança simples, embora possamos simular herança múltipla através de mixins.
  • 178.
    O super chama o correspondente da super-classe.
  • 179.
    Herança class B < A end
  • 180.
    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
  • 181.
    Visibilidade dos MembrosOs métodos podem ser: Públicos - chamados por qualquer um.
  • 182.
    Protegidos -chamados apenas pela família.
  • 183.
    Privados –chamados apenas no contexto do objeto atual. Em Ruby os atributos são sempre privados!
  • 184.
    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.
  • 185.
    Visibilidade dos Membrosclass 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
  • 186.
    Visibilidade dos MembrosTambém é possível fazer assim: class MinhaClasse def metodo1 ... end # os outros métodos public :metodo1 , :metodo4 protected :metodo2 private :metodo3 end
  • 187.
    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)
  • 188.
    Meta-programação class <<objConstrói um novo método somente para o objeto obj . a = &quot;Hoje&quot; class << a def oi &quot;oi123&quot; end end a . oi # => &quot;oi123&quot;
  • 189.
    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.
  • 190.
    Meta-programação eval 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
  • 191.
    Tratamento de Exceçõesbegin . . . rescue . . . ensure . . . end begin z = x / y rescue TypeError => err print &quot;Erro de tipo&quot; rescue => err print &quot;Erro Geral&quot; ensure z = 3 end
  • 192.
  • 193.
    Podem ter variáveis,constantes e métodos.
  • 194.
    Não podem serinstanciados.
  • 195.
    Benefícios: Fornecem umnamespace, evitando conflito de nomes.
  • 196.
    Permitem fazer mixin,ou seja, estender as funcionalidades de outras classes pela injeção de seu contexto. Normalmente, ficam em arquivo separado, e são carregados quando necessário.
  • 197.
    Módulos # Noarquivo 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 )
  • 198.
    Mixin Recurso quepermite a injeção de novos métodos a classes ou instâncias. 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;
  • 199.
    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;
  • 200.
    Carregamento de classese módulos load Carrega um arquivo tantas vezes quanto seja executado.
  • 201.
    load 'irb/completion.rb' require Carrega uma biblioteca, caso não tenha sido carregada ainda.
  • 202.
    require 'irb/completion' include Faz o mixin de um ou mais módulos.
  • 203.
  • 204.
    Procs São blocosde código associados à uma variável.
  • 205.
  • 206.
    Pode-se usar Proc.new , proc ou lambda . vezes3 = Proc . new {| n | n * 3 } vezes3 . call ( 1 ) => 3 vezes3 . call ( 2 ) => 6 vezes3 . call ( 3 ) => 9
  • 207.
    Procs Podemos transformarum bloco de código em uma Proc usando lambda ou proc: vezes3 = lambda {| n | n * 3 } vezes3 . call ( 1 ) => 3 vezes3 . call ( 2 ) => 6 vezes3 . call ( 3 ) => 9
  • 208.
    Fechamento ou ClosureÉ um bloco de código que pode ser passado como argumento a uma chamada de método.
  • 209.
    Closures podem fazerreferência a variáveis visíveis no momento em que elas foram definidas.
  • 210.
    Closure =bloco de código + ligações ao ambiente do qual vieram.
  • 211.
    São métodos anônimoscom escopo fechado.
  • 212.
    São métodos quecarregam o contexto no qual foram criados.
  • 213.
    O bloco podeusar todas as informações do seu contexto original mesmo que o ambiente no qual ele foi definido não mais exista.
  • 214.
    Fechamento ou Closuredef faz2 yield yield end faz2 { puts 'oi' }
  • 215.
    Fechamento ou Closureclass Array def each2 for element in self yield element end end end a = [ 1 , 2 , 3 ] a . each2 { | i | puts i }
  • 216.
    Fechamento ou Closuresalarios = [ 100 , 200 , 300 , 400 , 500 ] minimo = 300 salarios . each { | salario | puts salario if salario >= minimo } each é um método executado sobre o objeto salarios.
  • 217.
    {| salario | puts salario if salario >= minimo } é a closure . Note que ela faz referência a uma variável que está fora da closure (minimo).
  • 218.
    Fechamento ou Closuredef 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;
  • 219.
    Gem Uma gemé um pacote contendo uma biblioteca ou aplicação Ruby.
  • 220.
    Rubygems é oprojeto que desenvolveu o sistema de pacotes gem.
  • 221.
    Simplifica bastante ainstalação de bibliotecas em Ruby.
  • 222.
    Listando as gemsexistentes: gem list Adicionando uma nova fonte de gems: gem sources -a http://gems.github.com
  • 223.
    Testes &quot;Sempre queestiver tentado a escrever um print ou uma expressão de depuração, escreva um teste.&quot; Martin Fowler
  • 224.
    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
  • 225.
    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
  • 226.
    Testes com RUnitPara executar: ruby retangulo_test.rb
  • 227.
    Rspec – Instalandogems gem install rspec -V
  • 228.
    Para quem usaRuby on Rails: gem install rspec-rails -V
  • 229.
    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
  • 230.
    Testes com RSpecPara executar: rspec retangulo_spec.rb
  • 231.
    Referências Slides doLucas de Castro sobre Ruby
  • 232.
    Agile Web Developmentwith Rails. 2ª Edição. Thomas e David Heinemeier Hansson. Conceitos de Ruby e Rails Gabriel Bogéa Perez (http://www.b2t.com.br) Tutorial de Ruby do TaQ http://www.eustaquiorangel.com/downloads/tutorialruby.pdf Crossing borders: Closures – Bruce Tate http://www.ibm.com/developerworks/java/library/j-cb01097.html Closure – Martin Fowler http://martinfowler.com/bliki/Closure.html