Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Introdução a programação em Ruby, Notas de estudo de Introdução à Computação

Apostila do curso introdutório de programação Ruby dos cursos de Introdução à programação do IME-SP (instituto de matemática e estatísica da USP)

Tipologia: Notas de estudo

2020

Compartilhado em 20/04/2020

guilherme-nery-10
guilherme-nery-10 🇧🇷

4.7

(3)

6 documentos

1 / 32

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
apida Introdu¸ao a Ruby
Gubi
7 de mar¸co de 2019
Sum´ario
1 Introdu¸ao 3
1.1 PerlePython .......................................... 3
1.2 Ruby............................................... 4
2 Conceitos asicos 4
2.1 Tiposb´asicos .......................................... 5
2.1.1 N´umeros......................................... 5
2.1.2 Strings.......................................... 6
2.1.3 S´ımbolos......................................... 7
2.1.4 Arrays .......................................... 7
2.1.5 Hashes.......................................... 7
2.1.6 Faixas .......................................... 7
2.2 Estruturasdecontrole ..................................... 8
3 Fun¸oes, Blocos, Procedimentos e Lambdas 9
4 Exemplos 10
5 Orienta¸ao a Ob jetos 11
5.1 Encapsulamento......................................... 12
5.2 Heran¸ca ............................................. 12
5.3 Polimorfismo .......................................... 12
6 Implementando classes e objetos 12
6.1 Agrupamento .......................................... 13
7 Classes 13
8 Heran¸ca 16
9 Heran¸ca ultipla (ou ao) 19
10 Exce¸oes e Tratamento de Erros 22
10.1 Throw eCatch ......................................... 26
1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20

Pré-visualização parcial do texto

Baixe Introdução a programação em Ruby e outras Notas de estudo em PDF para Introdução à Computação, somente na Docsity!

R´apida Introdu¸c˜ao a Ruby

- 7 de mar¸co de Gubi
  • 1 Introdu¸c˜ao Sum´ario
    • 1.1 Perl e Python
    • 1.2 Ruby
  • 2 Conceitos B´asicos
    • 2.1 Tipos b´asicos
      • 2.1.1 N´umeros
      • 2.1.2 Strings
      • 2.1.3 S´ımbolos
      • 2.1.4 Arrays
      • 2.1.5 Hashes
      • 2.1.6 Faixas
    • 2.2 Estruturas de controle
  • 3 Fun¸c˜oes, Blocos, Procedimentos e Lambdas
  • 4 Exemplos
  • 5 Orienta¸c˜ao a Objetos
    • 5.1 Encapsulamento
    • 5.2 Heran¸ca
    • 5.3 Polimorfismo
  • 6 Implementando classes e objetos
    • 6.1 Agrupamento
  • 7 Classes
  • 8 Heran¸ca
  • 9 Heran¸ca M´ultipla (ou n˜ao)
  • 10 Exce¸c˜oes e Tratamento de Erros
    • 10.1 Throw e Catch

Metaprograma¸c˜ao 27 11.1 Introspec¸c˜ao........................................... 27 11.2 Classes abertas......................................... 28 11.2.1 Objetos abertos?.................................... 29 11.3 Cria¸c˜ao dinˆamica de m´etodos................................. 30 11.4 Cuidados............................................. 31

Sua principal qualidade ´e a integra¸c˜ao f´acil com o sistema operacional e a facilidade em trabalhar com express˜oes regulares. Os programas ficam curtos e aparentemente cr´ıpticos para os n˜ao iniciados, o que faz com que os “pythonistas” tor¸cam o nariz. J´a Python ´e uma linguagem “purista”. E bastante exigente na clareza do c´´ odigo e na forma em que as coisas s˜ao implementadas. Possui suporte a programa¸c˜ao funcional e ´e de fato orientada a objetos ea meta-programa¸c˜ao. Embora n˜ao perca a flexibilidade, o lema ´e “existe, em geral, uma forma ideal de se fazer as coisas”. A grande caracter´ıstica ´e a capacidade para modulariza¸c˜ao de c´odigo e a orienta¸c˜ao a objetos pro- priamente dita. Os programas s˜ao ligeiramente mais verborr´agicos do que em Perl, o que faz com que os monges do Perl (perl monks) tor¸cam o nariz.

1.2 Ruby

Ruby foi criada por Yukihiro Matsumoto (vulgo Matz) em 1993, no Jap˜ao. O objetivo da linguagem ´e produtividade e simplicidade. De certa forma, ela combina for¸cas de v´arias outras linguagens, em particular Perl e Python. Matz escreveu que queria uma linguagem mais poderosa do que Perl e mais orientada a objetos do que Python. O alvo era uma linguagem natural, mas n˜ao necessariamente simples, “assim como a vida”. O resultado ´e uma linguagem com a facilidade de escrita pr´oxima a Perl (depois de se acostumar) e com um rigor pr´oximo a Python. Seu suporte a express˜oes regulares ´e excelente e ´e completamente orientada a objetos, al´em de ter suporte avan¸cado a programa¸c˜ao funcional. Esta discuss˜ao n˜ao reflete a hist´oria real de Ruby, mas minha vis˜ao do resultado final. Desde a cria¸c˜ao de Ruby, tanto Perl como Python evolu´ıram muito, mas alguns paralelos com ambas linguagens fazem com que tanto monges e pythonistas tor¸cam o nariz... Brincadeiras a parte, Ruby ´e uma linguagem f´acil e divertida de programar, que se adapta muito bem `a cria¸c˜ao de sistemas web, principalmente se aliada ao arcabou¸co espec´ıfico chamado Rails.

2 Conceitos B´asicos

Meu objetivo aqui n˜ao ´e ensinar a programar, mas mostrar Ruby para quem j´a conhece outras linguagens. Explicarei as principais diferen¸cas com pequenos trechos de programa e discutirei os conceitos envolvidos. H´a muito material de excelente qualidade online, este texto serve como uma referˆencia e uma r´apida introdu¸c˜ao. No que segue, a resposta do interpretador Ruby (irb) ser´a apresentada neste formato. A primeira coisa que se deve ter em mente com Ruby ´e que tudo ´e um objeto. Veja o exemplo abaixo, que usa o m´etodo even? para saber se um n´umero ´e par

  1. even? => sa´ıda

O n´umero 1769 ´e um objeto da classe Fixnum, cujo m´etodo even? indica se o objeto ´e par ou ´ımpar. A presen¸ca de um? no nome do m´etodo pode parecer estranha, mas ´e permitida em Ruby se estiver no fim. Como veremos, alguns m´etodos tamb´em possuem um! no final. A ideia ´e usar o? para indicar m´etodos que retornam um valor booleano e! para m´etodos que alteram o estado do objeto. Esta conven¸c˜ao torna o c´odigo literalmente mais leg´ıvel. Para saber qual a classe de um determinado objeto, use o m´etodo class. Todo objeto tamb´em deve ter uma identifica¸c˜ao ´unica, que pode ser consultada com object id.

  1. class => Fixnum
  2. object_id => 3459

2.1 Tipos b´asicos

As vari´aveis em Ruby n˜ao s˜ao declaradas, seu tipo ´e determinado na atribui¸c˜ao de valores. O tipo ´e do valor, n˜ao da vari´avel.

x = 4 => 4 x. class => Fixnum x = " oi " => "oi" x. class => String

Come¸caremos com constantes, que n˜ao formam um tipo, nem s˜ao constantes (calma, j´a explico). Qualquer vari´avel que come¸ca com uma letra mai´uscula ´e considerada constante, independente do valor associado. E poss´´ ıvel mudar o valor da constante, mas Ruby manda um alerta se isso acontecer:

Resposta = 42 => 42 Resposta = 1729 (irb):149: warning: already initialized constant Resposta (irb):148: warning: previous definition of Resposta was here => 1729

2.1.1 N´umeros

N´umeros em Ruby seguem o padr˜ao de outras linguagens. Os tipos b´asicos s˜ao inteiros e ponto flutuante, s´o n˜ao se esque¸ca que divis˜ao de inteiros produz resultado inteiro. Existe ainda um terceiro tipo b´asico, que s˜ao inteiros muito grandes, pertencentes a classe Bignum, fa¸ca um teste. As coisas ficam mais divertidas quando se usa os m´etodos especiais. Este exemplo d´a uma ideia do que se pode fazer.

puts " Hey Shrek "

  1. times { puts " N ´o s j´a chegamos? " }

Retornaremos a este exemplo mais tarde, mas d´a para perceber tudo o que ´e estranho? O puts na primeira linha deve ser claro: simplesmente imprime o argumento. Note que n˜ao existe necessidade de parˆenteses, uma vez que a situa¸c˜ao ´e clara. Em Ruby, os comandos terminam com um final de linha ou com ;, como em Python. A segunda linha ´e mais interessante. O m´etodo times faz com que o bloco `a direita seja repetido o n´umero de vezes representado pelo inteiro que o chamou. Pode-se pensar que o bloco ´e um argumento

Em todos os casos tamb´em ´e poss´ıvel incluir valores formatados no estilo de Python, com %. puts " Produto : % -10.10 s \ nPre ¸c o : %7.2 " %[ ’A ¸c ´u car ’ , 4.80]

Finalmente, as aspas simples, duplas e invertidas podem ser substitu´ıdas, respectivamente, pelas se- guintes constru¸c˜oes: %q[delim].. .[delim], %Q[delim].. .[delim], %x[delim].. .[delim]. [delim] pode ser qual- quer pontua¸c˜ao ou parˆenteses, chaves ou colchetes balanceados.

2.1.3 S´ımbolos

S´ımbolos s˜ao nomes e funcionam como strings constantes, muito ´uteis para chaves de dicion´arios e identificadores. Os s´ımbolos seguem as regras de forma¸c˜ao de identificadores, come¸cando com ’:’.

c1 = " cadeia " c2 = " cadeia " s1 = : cadeia s2 = : cadeia puts c1. object_id puts c2. object_id puts s1. object_id puts s2. object_id

2.1.4 Arrays

Arrays s˜ao similares aos de Python e funcionam como esperado. ´Indices podem ser negativos, contando a partir do final. Existem v´arias maneiras de instanciar um array. Veja os exemplos abaixo:

a = [1 ,4 , " blabla " , [3 ,4]] b = Array. new (20) # 20 elementos nil c = Array. new (3 , ’ bla ’) # [" bla " , " bla " , " bla "] d = Array. new (4) {| x | x * x } # [0 , 1 , 4 , 9] e = Array (3..5) # [3 ,4 ,5] f = Array .[](1 ,0 ,4 , " !! " ) # [1 ,0 ,4 ,"!!"]

A grande novidade, emprestada de Perl, ´e a possibilidade de construir um array de strings direta- mente a partir de uma lista de palavras, para simplificar a inicializa¸c˜ao.

lista = % w [ um dois tr ^e s quatro ] # [" um " , " dois " , " tr ^e s " , " quatro "]

2.1.5 Hashes

Hashes ou dicion´arios tamb´em funcionam como os equivalentes em Perl ou Python. Adicionalmente, possuem diversos m´etodos interessantes que facilitam muito sua manipula¸c˜ao. Veremos alguns nos exemplos mais adiante.

2.1.6 Faixas

Faixas ou ranges s˜ao intervalos de valores que podem ser usados como ´ındices ou listas para for, de modo similar ao que acontece em Python.

Em Ruby, s˜ao indicados por (inicio..fim) ou (inicio...fim). Neste ´ultimo caso “fim” n˜ao faz parte da sequˆencia.

a = Array (3..6) # [3 ,4 ,5 ,6] b = Array (3...6) # [3 ,4 ,5] c = Array ( ’ aa ’ .. ’ cx ’) # adivinhe o que sai

2.2 Estruturas de controle

As estruturas de controle s˜ao as usuais, apenas com algumas diferen¸cas de sintaxe. E mais r´´ apido ilustrar com exemplos:

condicionais

if a > 4 puts " #{ a } ´e grande " end

ou , equivalentemente , para express ~o es simples

puts " #{ a } ´e grande " if a > 4

outra forma

if a > 4 then puts " #{ a } ´e grande " end

unless ´e o if com a condi ¸c ~a o invertida

puts " #{ a } ´e grande " unless a <= 4

for usando uma enumera ¸c~a o

for i in 1.. puts i end

case ou switch

case a when 3 then puts " quase l ´a " when 4 then puts " em cima " when 5..10 then puts " sobrou " end

Os testes executados por when usam um operador especial (===) que normalmente ´e explicado de uma forma muito confusa. O que === faz ´e uma verifica¸c˜ao de continˆencia, a express˜ao a === b responde `a pergunta “b pode ser um elemento de a?”. No ´ultimo exemplo acima, perguntamos se a ´e um dos valores da enumera¸c˜ao 5..10. Os comandos while e until s˜ao usados da mesma maneira e tamb´em podem ser colocados no final da express˜ao.

x = 3 puts x -= while x > 0

Os comandos abaixo servem para controlar os la¸cos:

triplo = - >( n ) { 3* n } triplo. call (2)

ou

triplo .(2) # note o ’. ’

Para entender a diferen¸ca de comportamento de return nos dois casos, veja este exemplo.

def no_proc puts Proc. new { return " Sa ´ı do proc " }. call return " Resto do proc " end

def no_lambda puts lambda { return " Sa ´ı do lambda " }. call return " Resto do lambda " end

puts no_proc puts no_lambda

Para passar um lambda como argumento de uma fun¸c˜ao que usa yield ´e preciso primeiro transform´a- la em Proc, isto ´e feito com o operador &:

me = - >{ puts " M ´a rio! " }

def oi print " It ’s me , " yield end

oi & me

Se n˜ao houver um return expl´ıcito, o ´ultimo valor calculado ´e retornado.

4 Exemplos

Aqui est˜ao alguns exemplos divertidos usando express˜oes regulares e elementos acima. O operador ~ verifica se uma string bate com uma express˜ao regular. A nega¸c˜ao ´e !~. Procure entender o restante. Marcador de milhares

!/ usr / bin / env ruby

while x = gets break if x !~ /\ d/ ’ wtf ’ while x. sub !(/(.*\ d ) (\ d \ d \ d ) / , ’ \1.\2 ’) puts " >> #{ x } " end

Histograma, com alguns truques:

!/ usr / bin / env ruby

val = Hash. new (0) # valor default para novas entradas

while lin = gets lin. split. each { | p | val [ p ]+=1 } end

val. sort_by {| k , v | -v }. each {| k , v | puts " % -20.20 s : %4 d \ n " %[ k , v ]}

O que faz este c´odigo?

!/ usr / bin / env ruby

while l = gets. to_i break unless l > 1 puts " Sim! " unless ’1 ’ * l =~ /^(11+) \1+ $ /; end

5 Orienta¸c˜ao a Objetos

A ideia b´asica ´e construir uma abstra¸c˜ao, o centro da programa¸c˜ao n˜ao ´e mais voltada para como definir a sequˆencia de opera¸c˜oes (programa¸c˜ao imperativa), mas como modelar melhor as informa¸c˜oes e dados tratados pelo programa. A partir de um bom modelo, a programa¸c˜ao fica mais f´acil. Este tipo de abordagem traz outras vantagens, como reutiliza¸c˜ao de c´odigo, extensibilidade e inde- pendˆencia de implementa¸c˜ao. O ponto de partida ´e o objeto, isto ´e, uma entidade representada no computador. As caracter´ısticas b´asicas de um objeto s˜ao:

  • Tudo ´e um objeto. Existem diversos tipos, ou classes, de objetos. Qualquer elemento de seu programa, incluindo o pr´oprio, ´e representado como um objeto.
  • Um programa ´e uma cole¸c˜ao de objetos interagindo entre si.
  • Um objeto pode ser composto de outros objetos.
  • Todo objeto tem um tipo. “Um objeto ´e uma instˆancia de uma classe”.
  • Classes podem conter subclasses. (Um tipo ´e um conjunto, um subtipo ´e definido por restri¸c˜oes neste conjunto)
  • Objetos da mesma classe reagem do mesmo modo.

Uma forma mais simples de descrever um objeto ´e indicar trˆes propriedades:

  • Estado. Descrito por um conjunto de vari´aveis.
  • Comportamento. Descrito por fun¸c˜oes, normalmente chamadas de m´etodos no linguajar de ori- enta¸c˜ao a objetos.

6.1 Agrupamento

J´a vimos que classes podem ter uma rela¸c˜ao hier´arquica por meio de heran¸ca, mas esta n˜ao ´e a ´unica possibilidade. Uma certa implementa¸c˜ao pode precisar de classes auxiliares relacionadas e uma estrutura mais ampla do programa como um todo ´e interessante.

7 Classes

A defini¸c˜ao de classes tamb´em segue uma sintaxe usual. Uma classe ´e composta de atributos e m´etodos. Atributos s˜ao campos e m´etodos s˜ao fun¸c˜oes membro. Convenciona-se que todos os nomes de classes comecem com uma letra mai´uscula.

!/ usr / bin / env ruby

coding : utf -

class Carta def initialize (v , n ) @naipe = n @valor = v end def to_s " %2 s de % s " %[ @valor , @naipe ] end end

class Baralho def initialize @cartas = [] % w [♣ ♥ ♠ ♦]. each do | n | ([ " A" ] + Array (2..10) + [ " J " ," Q " , " K " ]). each do | v | @cartas << Carta. new (v , n ) end end end

def print @cartas. each do | c | puts c ; end end

def embaralha emb = [] while @cartas. size > 0 i = rand (0 ... @cartas. size ) emb << @cartas. delete_at ( i ) end @cartas = emb end

def distribui ( nj , ncartas ) return nil if nj * ncartas > @cartas. size

m ~a os = Array. new ( nj ) m ~a os. map! {| p | p = Array. new }

(1.. ncartas ). each do | i | (0... nj ). each do | j | m ~a os [ j ] << @cartas. pop end end return m ~a os end end

b = Baralho. new b. embaralha b. print print ( " ----" * 5) puts m = b. distribui (3 ,2)

(0... m. size ). each do | i | puts " Cartas do jogador n. #{ i +1} " m [ i ]. each do | c | puts c end puts ’ ---- ’ end

No exemplo da classe Carta, n˜ao podemos mexer diretamente nos dois campos naipe e valor diretamente, como c.valor=4 ou puts c.naipe. Para isso precisamos de m´etodos especiais para ler e/ou escrever nestas vari´aveis. Estes m´etodos s˜ao chamados de getter s e setter s, respectivamente. Para fazer um getter, basta escrever um m´etodo com o nome do atributo, que retorna seu valor. O setter usa um m´etodo com o nome do atributo seguido de um =:

8 Heran¸ca

Veja este exemplo com heran¸ca simples. A classe Progress~ao define uma progress˜ao gen´erica de n´umeros consecutivos. As outras classes implementam varia¸c˜oes e aproveitam as propriedades de Progress~ao sem precisar redefini-las ou nem mesmo conhecer a implementa¸c˜ao.

!/ usr / bin / env ruby

coding : utf -

class Progress ~a o def initialize ( ini =0) @prim = ini @atual = ini end

def primeiro @atual = @prim end

def prox @atual += 1 end

def imprime ( n =1) print " #{ @prim } " for i in 2.. n print " #{ prox }" end end

end

Neste exemplo, require faz com que o c´odigo de Progress~ao.rb seja lido e processado. Isto acontece uma ´unica vez, mesmo que o comando aparecesse mais de uma vez no c´odigo. E equivalente ao´ import de Java e Python.

Progress˜ao aritm´etica.

!/ usr / bin / env ruby

coding : utf -

require ’ ./ Progress ~a o ’

class Aritm ´e tica < Progress ~a o def initialize ( inc = 1 , ini ) @inc = inc super ( ini ) end

def prox @atual += @inc end end

Progress˜ao geom´etrica.

!/ usr / bin / env ruby

coding : utf -

require ’ ./ Progress ~a o ’

class Geom ´e trica < Progress ~a o def initialize ( inc = 1 , ini ) @inc = inc super ( ini ) end

def prox @atual *= @inc end end

v ´a rios = [ Aritm ´e tica. new (1 , 6) , Progress ~a o. new (2) , Fibonacci. new (1 , 1) , Geom ´e trica. new (1 , 2) , Fibonacci. new (7 , 9) , Geom ´e trica. new (3 , 3) , Progress ~a o. new (4) , Geom ´e trica. new (5 , 1) , Geom ´e trica. new (2 , 2.3) , ]

def moldura print " [ " yield puts " ] " end

v ´a rios. each {| p | moldura { p. imprime (5) }}

9 Heran¸ca M´ultipla (ou n˜ao)

Para criar um objeto com caracter´ısticas de dois tipos diferentes precisar´ıamos ter heran¸ca m´ultipla (a classe extenderia mais de uma classe base). No entanto heran¸ca m´ultipla tem seus inconvenientes. Uma classe pode herdar implementa¸c˜oes diferentes dos mesmos m´etodos ou ainda ser derivada mais de uma vez da mesma base. Existe ainda o problema de um campo ou m´etodo de um ancestral comum ser modificado indiretamente por m´etodos diferentes. Vejamos um exemplo onde aparece a necessidade de heran¸ca m´ultipla: considere a hierarquia de alimentos da figura 1.

Alimento

S´olido

Carne Ovo Fruta Sais

L´ıquido

Aquoso

Agua´ Leite Suco

Oleo´

Figura 1: Hierarquia de Alimentos

Esta hierarquia pode ser facilmente estendida para v´arios casos. No entanto, temos um problema se precisarmos escolher alimentos de origem animal, mineral ou vegetal. Existem exemplos em diversos ramos desta ´arvore. Uma solu¸c˜ao, sem o fazer uso de heran¸ca m´ultipla, s˜ao mixins. Mixins declaram m´etodos que podem ser usados em outras classes. Em Ruby, os mixins s˜ao definidos por modules. Instˆancias de uma classe C que incluem um module M recebe os m´etodos (portanto o comportamento) definidos em M. Este arranjo simples evita os problemas de heran¸ca m´ultipla mas fornece um mecanismo para que objetos compartilhem propriedades de outro tipo, al´em do esquema de deriva¸c˜ao usual. Podemos colocar m´etodos adicionais nos objetos, fazendo com que eles se comportem como elementos de um tipo adicional. Isto ´e chamado de duck typing (se anda como um pato e grasna como um pato, deve ser um pato). Com m´odulos, isso fica mais f´acil de fazer. Os m´odulos tamb´em podem ser usados para simplesmente agrupar m´etodos e vari´aveis dentro de um grupo separado, com um espa¸co de nomes pr´oprio.

!/ usr / bin / env ruby

coding : utf -

module Frit ´a vel @frito = false def fritar print self. class. name if @frito puts " >>> Torrou !! " else puts " > shhhhhhhhzz! " @frito = true end end end

class Alimento end

class S ´o lido < Alimento end

class Carne < S ´o lido include Frit ´a vel end

class Ovo < S ´o lido include Frit ´a vel end

class Fruta < S ´o lido end