Date post: | 28-May-2015 |
Category: |
Technology |
Upload: | mauricio-linhares |
View: | 899 times |
Download: | 0 times |
APRENDENDO RUBY Maurício Linhares
O que? � Do Japão ◦ Yukihiko “Matz” Matsumoto
� Trazida ao mundo ocidental pelos Pragmatic Programmers ◦ Andy Hunt e Dave Thomas (livro da
machadinha)
� Completamente orientada a objetos ◦ Não existem tipos primitivos
Como? � Linguagem “de script” interpretada;
� Muito influenciada por Smalltalk e Perl;
� Contém conceitos de linguagens funcionais (closures – blocos de código);
� Completamente dinâmica (tudo pode mudar em tempo de execução);
RVM – Ruby Version Manager
� Solução pra instalar vários interpretadores Ruby ao mesmo tempo na sua máquina;
� Possibilita criar aplicações completamente independentes no seu ambiente de desenvolvimento, isolando tudo e todos;
Instalando o RVM � Instale o Git na sua máquina
� bash < <(curl –s https://rvm.beginrescueend.com/install/rvm)
� Feche o console e abra outra vez
� rvm notes ◦ E faça o que ele mandar
Instalando um Ruby com o RVM
� rvm install ruby-1.9.2
� rvm use 1.9.2
� rvm --default use 1.9.2
Rubygems!
� gem install bundler rails
� O Rubygems é o gerenciador de pacotes do Ruby, é com ele que você vai instalar as dependências da sua aplicação;
� Na sua máquina ele é chamado pelo comando “gem”;
Bundler -> bundle install � É quem garante que todas as
dependências da sua aplicação estão disponíveis para que ela possa executar;
� Usa um arquivo chamando Gemfile onde você define as suas dependências e ele as instala usando o Rubygems;
� Garante que todos os desenvolvedores usam as mesmas coisas no trabalho;
Começando a brincar com o IRB
� IRB é o “Interactive Ruby”, o console da linguagem;
� Pode-se enviar comandos ou se definir classes, módulos, funções e qualquer outra coisa pra se utilizar durante uma sessão;
Brincando
numero = 30 outro_numero = -20 numero + outro_numero numero + outro_numero.abs
Primeiras tres regras de Ruby � Não se usam ‘;’ ou qualquer outra coisa pra
indicar o fim de uma linha, o fim da linha é o fim da linha, oras;
� Variáveis não tem tipo, elas simplesmente guardam um objeto qualquer, de qualquer tipo;
� Quando nós vamos dar nomes a variáveis, normalmente separamos nomes compostos com “_”;
Continuando a brincadeira, definindo um método def soma( primeiro, segundo) primeiro + segundo
end soma( 10, 20) soma 50, 90
Mais quatro regrinhas – 1
� A definição de um método começa com “def” depois vem o nome do método e depois seus parâmetros entre parenteses;
� Blocos de código, como métodos, classes, “ifs” são sempre fechados com “end”, aqui não tem “{}” não;
Mais quatro (5) regrinhas - 2 � Em Ruby não se usa “return”, se a última
expressão no corpo de um método for avaliada para um valor, esse valor é retornado;
� O uso de parênteses não é obrigatório na chamada de métodos, mas tenha cuidado com a legibilidade;
� Bem, você ainda pode usar “return” se quiser, mas é feio, oras;
Classes class Song def initialize(name, artist, duration) @name = name @artist = artist @duration = duration end
end musica = Song.new “Denied”, “Sonic
Syndicate”, 3 musica.inspect
Mais regras � A definição de uma classe começa com a
palavra “class”;
� As classes são sempre “abertas”, você pode redefinir os métodos de uma classe em qualquer lugar, é só declarar ela outra vez;
� Nomes de classe normalmente são definidos usando CamelCase (como em NomeDeClasse);
Mais regras
� Os contrutores são os métodos “initialize()”, que são invocados indiretamente, através do método de classe “new”;
� Não é possível fazer sobrecarga de construtores em Ruby =( ;
� Variáveis de instância tem o nome começado por “@”;
Atributos
class Song attr_writer :duration attr_reader :duration attr_acessor :title
end song = Song.new("Bicylops", "Fleck", 260) song.duration = 257 song.title = ‘Triciclops’
Regras denovo � attr_reader define métodos de acesso a
um atributo de instância de um objeto;
� attr_writer define métodos de alteraçao a um atributo de instância de um objeto, assim como o reader, ele cria a variável dentro do objeto;
� attr_acessor faz o mesmo que os dois anteriores juntos;
Definindo atributos virtuais
class Song def duration_in_minutes @duration/60.0 end def duration_in_minutes=(new_duration) @duration = (new_duration * 60).to_i end
end
O que é que nós fizemos?
� Criamos métodos de acesso a um atributo, mas o cliente não sabe se são métodos ou se ele está acessando os atributos diretamente;
� Sobrescrevemos o operador “=“ (atribuição) para a nossa propriedade, Ruby tem sobrecarga de operadores (alguns, apenas)!
Constantes, Variáveis e métodos de classe class SongList @@calls_total MAX_TIME = 5*60 # 5 minutos MIN_TIME = 1*60 # 1 minuto def SongList.is_too_long(song) song.duration > MAX_TIME end def self.is_too_short(song) song.duration < MIN_TIME end
end
E aí? � Variáveis de classe são definidas com dois
“@”, como em “@@variavel_de_classe”;
� Constantes são definidas com o seu nome completo em “caixa alta” (na verdade é só a primeira letra, mas use o NOME COMPLETO);
� Métodos de classe são definidos colocando o nome da classe antes do nome do método ou usando “self” (é o “this” em Ruby);
acesso aos objetos class MyClass
def method1 # o padrão é public end protected def method2 end private def method3 end public def method4 end
end
Como acessar?
� Os níveis de acesso são definidos em blocos, quando não há definição, é public, quando se quer definir um nível de acesso, deve-se utilizar um bloco de acesso;
� Um bloco termina assim que outro se iniciar;
Mas não é ruim não ter tipos?
Eu faço “quack()”, “nadar()” e “voar()”, igual a qualquer outro pato, eu sou ou não
um pato?
Tudo são mensagens!
� Pois é, você perdeu a aula de Smalltalk né?
� Não importa qual o tipo do objeto, o que importa são as mensagens (métodos?) que ele é capaz de responder;
� Se faz quack, nada e voa feito um pato, então pra mim é um pato;
Arrays
a = [ 3.14159, "pie", 99 ] a[0] # 3.14159 a[3] # nil a << 123 # adicionando um item a[4] = 456 #adicionando outro item a[-1] # 456 – acessando de trás pra frente a[2..4] # [99, 123, 456]
Explicando arrays � Arrays são definidos pela simples
declaração de “[]”, como em “a = []”, também pode-se fazer “a = Array.new”;
� Arrays são acessados pelo índice, tanto positivo (ordem crescente) como negativo (ordem decrescente);
� Quando se acessa um índice que não existe em um array, ele retorna “nil”;
Explicando arrays � Novos items podem ser colocados no array
simplesmente utilizando o próprio operador “[]”, como em “a[10] = 10”;
� Para se adicionar um item no fim do array usa-se o operador “<<“, como em “a << 10”;
� Arrays podem ser pegos em ‘pedaços’ como em “a[1..3]”, que cria um novo array com os itens do índice 1 ao 3;
hashes
h = { 'dog' => 'canine', 'cat' => 'feline', 'donkey' => 'asinine' }
h.length # 3 h['dog'] # "canine" h['cow'] = 'bovine' h[12] = 'dodecine' h['cat'] = 99
Entendendo hashes
� São conjuntos de “chave-valor” (Lembra do Map em Java?);
� São declarados com o uso de “{}” como em “h = {}”, ou usando Hash.new;
� Para se adicionar itens basta usar o operador [], como em “h[‘chave’] = ‘valor’”;
Você consegue explicar isso? class SongList def with_title(title) for i in [email protected] return @songs[i] if title == @songs[i].name end return nil end
end
E isso?
class SongList def with_title(title) @songs.find {|song| title == song.name } end
end
Código solto?
� Blocos são pedaços de código que podem ser passados como parâmetros para funções, para fazer algum trabalho especial, como filtragem, ordenação e outros;
� Você pode definir os seus próprios métodos que aceitam blocos;
Strings 'escape using "\\"' # escape using "\" 'That\'s right' ! #That's right "Seconds/day: #{24*60*60}" # Seconds/day:
86400 def to_s “Song: #@song Artist: #{@artist}”
end
strings
#Q!String de muitas linhas com aspas duplas e acessando variáveis #{variavel}!
#q( String de muitas linhas com aspas
simples, aqui não pode ter variável ) ‘a’ << ‘b’ << ‘c’ # ‘abc’
Como é? � Strings são sequências de caracteres de 8
bits, não necessariamente Unicode;
� Elas podem ser definidas usando ‘’ (aspas simples) ou “” (aspas duplas);
� Usando aspas duplas você pode colocar expressões ou variáveis com o uso do caracter “#” seguido de “{}” para variáveis de método ou funções ou apenas ‘@’ para variáveis de instância;
ranges 1..10 # [1,2,3,4,5,6,7,8,9,10] 'a'..'z‘ # lembra do alfabeto? my_array = [ 1, 2, 3 ] 0...my_array.length # [0,1,2,3,4] (1..10).to_a # [1, 2, 3, 4, 5, 6, 7, 8, 9,10] ('bar'..'bat').to_a # ["bar", "bas", "bat"]
O que são ranges? � São um conjunto de objetos em
sequência, normalmente caracteres ou números;
� São definidos através da declaração de [ ‘valor inicial’ .. ‘valor final’ ], como em [1..100];
� Você pode definir os seus próprios ranges com o operador “<=>” (disco voador?);
Criando Seu próprio range class VU include Comparable
attr :volume def initialize(volume) @volume = volume end def to_s '#' * @volume end def <=>(other) self.volume <=> other.volume end def succ raise(IndexError, "Volume too big") if @volume >= 9 VU.new(@volume.succ) end
end
Numeros
num = 81 6.times do puts "#{num.class}: #{num}" num *= num
end
Um pouco mais sobre métodos def cool_dude(arg1="Miles", arg2="Coltrane",
arg3="Roach") "#{arg1}, #{arg2}, #{arg3}."
end cool_dude # "Miles, Coltrane, Roach." cool_dude("Bart") # "Bart, Coltrane, Roach." cool_dude("Bart", "Elwood") # "Bart, Elwood,
Roach." cool_dude("Bart", "Elwood", "Linus") # "Bart,
Elwood, Linus."
Um pouco mais sobre métodos
def meth_three 100.times do |num| square = num*num return num, square if square > 1000 end
end num, square = meth_three
Um pouco mais sobre metodos def five(a, b, c, d, e) "I was passed #{a} #{b} #{c} #{d} #{e}"
end five(1, 2, 3, 4, 5 ) # "I was passed 1 2 3 4 5" five(1, 2, 3, *['a', 'b']) # "I was passed 1 2 3 a
b" five(*(10..14).to_a) # "I was passed 10 11
12 13 14"
Ainda em métodos class SongList def create_search(name, params) # ... end
end list.create_search('short jazz songs', :genre => :jazz, :duration_less_than => 270)
If/unless puts "a = #{a}" if debug print total unless total.zero? if x == 2 puts x
elsif x < 0 puts “#{x} é menor que zero”
else puts ‘Caiu no else’
end
Case/when (conhece o swiTch?)
leap = case when year % 400 == 0 then true when year % 100 == 0 then false else year % 4 == 0 end
Que lindo switch case input_line when "debug" dump_debug_info dump_symbols when /p\s+(\w+)/ dump_variable($1) when "quit", "exit" exit else print "Illegal command: #{input_line}" end
while print "Hello\n" while false begin print "Goodbye\n"
end while false while x < 10 puts “X é #{x}” x = x + 1
end
Quem precisa de um for? 3.times do print "Ho! “
end 0.upto(9) do |x| print x, " "
end [ 1..5 ].each {|val| puts “ #{val} ” }
Mas você ainda quer um for?
for i in ['fee', 'fi', 'fo', 'fum'] print i, " "
end for i in 1..3 print i, " "
end
Break, redo e next
while line = gets next if line =~ /^\s*#/ # pular comentários break if line =~ /^END/ # parar no fim # executar coisas redo if line.gsub!(/`(.*?)`/) { eval($1) } # process line ...
end
Tente outra vez
for i in 1..100 print "Now at #{i}. Restart? " retry if gets =~ /^y/i
end
DÚVIDAS?