Mini-curso de Introdução à Linguagem Ruby

Embed Size (px)

Citation preview

Curso de Ruby

A melhor forma de prever o futuro invent-lo. Alan Kay

Regis Pires [email protected]

Overview

Ruby histrico, caractersticas, implementaes, instalao, irb Entrada / Sada Comentrios Convenes Variveis, Constantes Operadores Tipos Estruturas de Controle Orientao a Objetos no Ruby Meta-programao Tratamento de Excees Mdulos Mixin Procs Fechamento ou Closure

Ruby

1993 Yukihiro Matsumoto Matz Matz nasceu no Japo em 1965. Junta as melhores partes de gigantes do passado e do presente. Mais usada no Japo que Python. Popularizada pelo Rails.

RubySegundo Matz: Ruby uma linguagem de scripting interpretada cujo objetivo tornar a programao orientada a objetos simples e rpida. (...) simples, direta, extensvel e portvel. Fonte: http://www2.ruby-lang.org/en/20020101.html

Ruby Caractersticas

Dinmica; Tipagem forte; Livre / Open Source; Foco na simplicidade e produtividade; Programao divertida; Interpretada; Mixins, blocos e fechamentos; Totalmente orientada a objetos. Classes e objetos so abertos para redefinies a qualquer momento

Implementaes do Ruby

MRI Matz Runtime Interpreter JRuby Implementao em Java YARV Mquina Virtual Verso 1.9

Bytecode interpreter Rails 15% mais rpido que com Ruby 1.8.6

Rubinius Extenses em Ruby IronRuby Implementao em .NET MagLev Ruby sobre VM da GemStone (excelente VM SmallTalk)

Instalao do Ruby1 No Linux 2 alternativas:

Compilar no brao:

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 grfico) no Ubuntu: sudo apt-get install ruby rubygems irb ri rdoc ruby1.8-dev build-essential sudo apt-get install libmysql-ruby libpgsqlruby libsqlite3-ruby

Instalao 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/rubyinst aller-1.8.7-p302.exe

Instalao do Ruby3 No Windows ou Linux:

Easy Rails = Ruby + Rails + Mongrel.

Roda no Windows e Linux. http://rubyforge.org/frs/download.php/57834/ea http://rubyforge.org/frs/download.php/7256 4/easy-rails-linux-0.9.3.md5

Testando o Rubyruby -v

irb - interactive ruby

Interpretador interativo do Ruby. Permite executar trechos de cdigos 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

Ao executar o irb:~$ irb -r irb/completion

Com o irb j em execuo:irb(main):010:0> require 'irb/completion' => true

Totalmente orientada a objetos

No h tipos primitivos. Qualquer coisa que no seja executado dentro de um mtodo, est implicitamente sendo executado dentro do mtodo main da classe Object.irb(main):001:0> puts self.class Object => nil irb(main):002:0> puts self main => nil

Totalmente orientada a objetos1.class # => Fixnum 1.class.class # => Class 1.class.superclass # => Integer

Totalmente orientada a objetos

1 instncia da classe Fixnum. A classe Fixnum instncia 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 mtodos. 1.to_s 1 + 1 1.+(1) -1.abs "123".length # # # # # => => => => => "1" 2 2 1 3

Totalmente orientada a objetos

At mesmo classes so objetos. Object.class class Exemplo; end Exemplo.class Exemplo.methods # => Class # => Class # => [...]

Exemplo.methods diferente de Exemplo.new.methods.

O mtodo methods1.methods.sort 1.public_methods.sort 1.protected_methods.sort 1.private_methods.sort String.methods.sort

Entrada / Sadanome = gets.chomp Pedro # => "Pedro" puts nome Pedro # => nil

chomp mastigar, roer

Comentriosx = y + 5 # Isto um comentrio de linha. # Isto um outro comentrio de linha. =begin Isto um comentrio de bloco. =end

ConvenesNomesDeClasse nomes_de_metodos e nomes_de_variaveis metodos_fazendo_pergunta? metodos_perigosos! @variaveis_de_instancia @@variaveis_de_classe $variaveis_globais ALGUMAS_CONSTANTES ou OutrasConstantes

Variveis

So tipadas dinamicamente: a = 4 So fortemente tipadas: 2 + "2" no possvel. Variveis locais: quantidade_dias = 3 Variveis globais: $caminho = "/home/curso" Variveis de instncia: @nome = "Maria" Variveis de classe: @@vogais = ['a', 'e', 'i', 'o', 'u']

Variveis

Variveis no precisam ser declaradas. Variveis so referncias para objetos.

~$ irb irb(main):001:0> a = 1 => 1 irb(main):002:0> a = "1" ' => "1"

Operadores

Aritmticos: +, -, *, /, %, ** ... etc Igualdade e comparao: >, >=, => => => 1000000 Fixnum 1000000000000000 Bignum

Nmeros1.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 nmeros de tamanho arbitrrio. A classe Bignum pode representar nmero com preciso infinita, restrita somente memria e processamento da mquina.

Booleanos

H somente 2 instncias 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 sequncia de bytes. Pode carregar caracteres "imprimveis" ou dados binrios. Podem ser delimitadas por aspas 'simples' ou "duplas". Podem ocupar vrias linhas, sem precisar ficar concatenando.

Stringss = "Curso de Ruby" s[0] # => 67 s[0].chr # => "C" s[6,2] # => "de" s[6..7] # => "de"

Strings Mtodos Destrutivosa = "Ruby" a.object_id a.upcase a a.upcase! a a.object_id a.downcase! a # # # # # # # # # => => => => => => => => => "Ruby" 20641550 "RUBY" "Ruby" "RUBY" "RUBY" 20641550 "ruby" "ruby"

Strings so mutveiss = "Ruby" s.object_id s => => =>

"Ruby" 20641550 "Ruby on " 20641550

Concatenao usando + resulta em outro objeto:

s = s + "Rails" s.object_id

# => "Ruby on Rails" # => 21074740

Strings interpolao de valores

Com aspas duplas podemos usar escapes especiais e interpolar cdigos.

nome = "Pacheco" # => "Pacheco" puts "Oi, #{nome},\nAdorei a Escola da Ponte!" # Oi, Pacheco, # Adorei a Escola da Ponte!

Strings longasnome = "Descartes" s = "aspas simples: \#{a}" "aspas duplas: #{a}" # => "aspas duplas: valor" %(marcadores especiais: #{a}) # => "marcadores especiais: valor" s = true

Strings - Mtodoss = "Ruby on Rails" s.gsub(' ','-') s.gsub(/[aeiou]/,'_') s.index('on') "hello\r\n".chomp "hello \n there".chomp "hello".chomp("llo") s = 'Ruby on Rails' s[5,2] # => "on" s[5..6] # => "on " "Ruby".reverse # => "ybuR" # => "Ruby-on-Rails" # => "R_by _n R__ls" # => 5 #=> "hello" #=> "hello \n there" #=> "he"

Ranges

um tipo da linguagem que representa um intervalo de valores: crianca = 0..101..7 inclui 1, 2, 3, 4, 5, 6 e 7 1...7 no inclui o 7 "Ruby"[1..2] [1,2,3,4,5][1..2] (2..10) === 3 # --> "ub" # --> [2,3] # true

("a".."z").each {|i| puts i} for n in 5..10; puts n; end

[Arrays]

Guardam uma coleo de objetos, cada um em uma posioa = [10, 7.2, "Maria"] a.class # Array a[1] # 7.2 a.length # 3 a[-1] # "Maria" a [nil, nil, nil, nil, "Ruby"]

[Arrays]

Mtodo includeirb(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

[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 palavrasa = %w(curso de ruby on rails) => ["curso","de","ruby","on","rails"] nome, sobrenome = 'regis', 'pires' a = %w(#{nome} #{sobrenome}) => ["\#{nome}", "\#{sobrenome}"] a = %W(#{nome} #{sobrenome}) => ["regis", "pires"]

Arrayss = 'Ruby on Rails' s.split(' ') # => ["Ruby", "on", "Rails"] a = %w(um dois tres quatro cinco seis sete oito nove dez) => ["um", "dois", "tres", "quatro", "cinco", "seis", "sete", "oito", "nove", "dez"] a.grep(/s$/) => ["dois", "tres", "seis"]

Array de bytesb = 'Ruby'.bytes.to_a # => [82, 117, 98, 121] b.pack("c*") # => "Ruby"

{Hashes}

O mesmo que arrays associativos, mapas ou dicionrios Cada entrada composta por uma chave (nica) e um valora = {'um' => 1, 'bola' => 2, 3 => 'Maria'}

a.class => Hash a[1] => nil a['um'] => 1 a.length => 3 a = Hash.new a = {}

:simbolos

Identificador que corresponde a um nome. H apenas uma instncia de cada um deles."vermelho".object_id != "vermelho".object_id :vermelho.object_id == :vermelho.object_id

So muito usados como chave nos Hashespessoa = {:nome => 'Regis', :idade => 17, :profissao => 'Professor'}

Imutveis

:simbolos:nome.to_s # => "nome"

/Expresses Regulares/

Criadas com /, %r ou Regexp.newer = /^[0-9]/ er2 = %r{^[0-9]} er = Regexp.new("^[0-9]")

Testadas com o operador de correspondncia (=~) ou o de no correspondncia (!~)"123" "123" "abc" "abc" =~ !~ =~ !~ er er er er # # # # => => => => 0 false nil true

Estruturas de Controle

Falso false e nil then opcional no if e unless if elsif else end:if (1 != 2) puts "Um nao eh dois" end

unless else end:unless (1 == 2) puts "Um nao eh dois" end

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 atrue, :reset=>false

Retornando "vrios valores" (arrays):nome, sobrenome = "Regis Pires".split(' ')

ola.rbdef diga_ola(nome) if nome[0..3] == 'Matz' puts 'Ah, foi vc quem criou o Ruby!' else puts("Ola #{nome}") end end print "Qual o seu nome? " nome = gets # Pede uma entrada do usuario diga_ola nome

Daterequire 'date' c = Date.today d = Date.new(2010, 10, 21) # => # d.day # => 21 d.mon # => 10 d.month # => 10 d.year # => 2010 d.wday # => 4 d.mday # => 21 d.yday # => 294 d.to_s # => "2010-10-21" dt = DateTime.now t = Time.now

Arquivosf = File.new("teste.txt","w") f NoMethodError: ...

Herana

Utilizamos quando queremos especializar uma classe. A classe mais genrica chamada de super-classe, e a mais especfica de subclasse. Em Ruby existe apenas herana simples, embora possamos simular herana mltipla atravs de mixins. O super chama o correspondente da super-classe.

Heranaclass B < A end

Heranaclass PessoaFisica < Pessoa def initialize (nome, idade, cpf) super(nome, idade) @cpf = cpf end # Mtodo dados redefinido def to_s super + ", Cpf=#{@cpf}" end end

Visibilidade dos Membros

Os mtodos podem ser:

Pblicos - chamados por qualquer um. Protegidos - chamados apenas pela famlia. Privados chamados apenas no contexto do objeto atual.

Em Ruby os atributos so sempre privados! public, protected e private so mtodos que modificam a classe dinamicamente e mantm o escopo de acesso at que outro escopo seja chamado.

Visibilidade dos Membrosclass MinhaClasse # Pblico o default def metodo1 ... end protected # os seguintes sero protegidos def metodo2 ... end private # os seguintes sero privados def metodo3 ... end public # os seguintes sero pblicos def metodo4 ... end end

Visibilidade dos Membros

Tambm possvel fazer assim:class MinhaClasse def metodo1 ... end # os outros mtodos public :metodo1, :metodo4 protected :metodo2 private :metodo3 end

Meta-programaoProgramao de programas que escrevem ou manipulam outros programas (ou a si prprios)Cao = Class.new Cao.class_eval nil

Meta-programao

class 2.0

Tratamento de Excees

begin . . . rescue . . . ensure . . . end

begin z = x/y rescue TypeError => err print "Erro de tipo" rescue => err print "Erro Geral" ensure z = 3 end

Mdulos

So parecidos com classes. Podem ter variveis, constantes e mtodos. No podem ser instanciados. Benefcios:

Fornecem um namespace, evitando conflito de nomes. Permitem fazer mixin, ou seja, estender as funcionalidades de outras classes pela injeo de seu contexto.

Normalmente, ficam em arquivo separado, e so carregados quando necessrio.

Mdulos# No arquivo calc.rb module Calc PI = 3.141592654 def self.seno(x) puts "calc.seno de #{x}" end def self.cosseno(x) puts "calc.cosseno de #{x}" end end # Em outro programa carregamos o arquivo # calc.rb usando require 'calc' # Chamamos mtodos com "." e constantes com "::" y = Calc.seno(Calc::PI / 4)

Mixin

Recurso que permite a injeo de novos mtodos a classes ou instncias.

module Debug def quem_sou_eu? "#{self.class.name}: #{self.to_s}" end end class Livro include Debug end class PessoaFisica < Pessoa include Debug end livro = Livro.new("Programming Ruby") livro.quem_sou_eu? # => "Livro: Programming Ruby" pessoa = PessoaFisica.new("Jose", 22) pessoa.quem_sou_eu? # => "PessoaFisica: Jose, 22"

Mixinmodule MyArray def hello puts "Oi!#{self.length}" 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 # "Oi!5" arr.hello # "Oi!3"

Carregamento de classes e mdulos

load

Carrega um arquivo tantas vezes quanto seja executado. load 'irb/completion.rb' Carrega uma biblioteca, caso no tenha sido carregada ainda. require 'irb/completion' Faz o mixin de um ou mais mdulos. include Modulo1, Modulo2

require

include

Procs

So blocos de cdigo associados uma varivel. Procs encapsulam blocos em objetos. 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

Procs

Podemos transformar um bloco de cdigo em uma Proc usando lambda ou proc:vezes3 = lambda {|n| n*3} vezes3.call(1) => 3 vezes3.call(2) => 6 vezes3.call(3) => 9

Fechamento ou Closure

um bloco de cdigo que pode ser passado como argumento a uma chamada de mtodo. Closures podem fazer referncia a variveis visveis no momento em que elas foram definidas. Closure = bloco de cdigo + ligaes ao ambiente do qual vieram. So mtodos annimos com escopo fechado. So mtodos que carregam o contexto no qual foram criados. O bloco pode usar todas as informaes do seu contexto original mesmo que o ambiente no qual ele foi definido no mais exista.

Fechamento ou Closuredef faz2 yield yield end faz2 { puts 'oi' }

Fechamento ou Closureclass Array def each2 for element in self yield element end end end a = [1,2,3] a.each2 { |i| puts i }

Fechamento ou Closuresalarios = [100,200,300,400,500] minimo = 300 salarios.each { |salario| puts salario if salario >= minimo }

each um mtodo executado sobre o objeto salarios.{|salario| puts salario if salario >= minimo}

a closure.

Note que ela faz referncia a uma varivel que est fora da closure (minimo).

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) => "Oi Oi Oi "

Gem

Uma gem um pacote contendo uma biblioteca ou aplicao Ruby. Rubygems o projeto que desenvolveu o sistema de pacotes gem. Simplifica bastante a instalao de bibliotecas em Ruby. Listando as gems existentes:

gem listgem sources -a http://gems.github.com

Adicionando uma nova fonte de gems:

Testes"Sempre que estiver tentado a escrever um print ou uma expresso de depurao, escreva um teste." Martin Fowler

Testesclass Retangulo def initialize(base, altura) @base = base @altura = altura end def area() @base * @altura end def perimetro() 2 * @base + 2 * @altura end

end

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

Testes com RUnit

Para executar:

ruby retangulo_test.rb

Rspec Instalando gems

gem install rspec -V Para quem usa Ruby on Rails:

gem install rspec-rails -V

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

Testes com RSpec

Para executar:

rspec retangulo_spec.rb

Referncias

Slides do Lucas de Castro sobre Ruby Agile Web Development with Rails. 2 Edio.

Thomas e David Heinemeier Hansson. Gabriel Boga Perez (http://www.b2t.com.br) http://www.eustaquiorangel.com/downloads/tutorialruby .pdf http://www.ibm.com/developerworks/java/library/jcb01097.html

Conceitos de Ruby e Rails

Tutorial de Ruby do TaQ

Crossing borders: Closures Bruce Tate

Closure Martin Fowler