Post on 11-May-2015
description
Workshop Ruby on Rails
Dia 1
Web development that doesn’t hurt
Ruby on Rails is an open-source web framework that’s optimized for programmer happiness and
sustainable productivity. It lets you write beautiful code by favoring convention over
configuration.
Agenda 1º Dia
Apresentação
A Linguagem de programação Ruby
Introdução ao Ruby on Rails
Agenda 2º Dia
Ruby On Rails all the Way
Live coding de uma aplicação web em Rails
“Ruby on Rails is astounding. Using it is like watching a kung-fu movie, where a dozen bad-ass frameworks prepare to beat up the little newcomer
only to be handed their asses in a variety of imaginative ways.”
Nathan Torkington, O'Reilly Program Chair for OSCON
• Jason Fried + David Heinemeier Hanson =>BaseCamp, Ruby on Rails• Java, PHP => Ruby• Best Hacker of the year 2005, Jolt Awards• Getting Real - Less is More• Dave Thomas and the Pragmatic Programmers• Agile Manifesto
Rails background
A linguagem de programação
Ruby
“I always thought Smalltalk would beat Java. I just didn’t know it would be called ‘Ruby’ when it did”
- Kent Beck
Mudança de Paradigma
•Criado em 1993 por Yukihiro Matsumoto, aka (Matz)•Linguagem Dinâmica, totalmente orientada a objectos.•Herança de Smalltalk, Lisp, Phyton, Perl, Eiffel, Ada.
RUBY
The image cannot be displayed. Your computer may not have enough memory to open the image, or the image may have been corrupted. Restart your computer, and then open the file again. If the red x still appears, you may have to delete the image and then insert it again.
• Genérica, interpretada, reflexiva , com garbage collection.• Optimizada para os programadores e não para os compiladores.• Mais poderosa do que o Perl, mais orientada a objectos do que o Python• Tudo são objectos.Não existem tipos primitivos• Tipagem Dinamica Forte.
O Ruby
•Linguagem natural e coerente•Princípio da menor supresa•Muito productiva: menos linhas de código•Comunidade muito activa
Ruby
•Tipagem dinámica (vs. estática)• Suporte completo para introspecção – (respond_to)• Redefinição de métodos• Method_missing• Criação de DSL – domain specific language
O Ruby é Altamente dinamico
Focus na produtividade do
programador
Rubyist do it with class !
Definir uma classe e instanciar um objecto
class Consultordef initialize(nome)
# As váriaveis de instancia começam com @@nome = nome
end
def diz_ola # Método de instanciaputs "#{@nome} diz olá”
end
end
tiago = Consultor.new(“Tiago”)tiago.diz_ola
Herança de Classes# Programador é um Consultor e extende a classe com carct. adicionaisclass Programador < Consultor def initialize(nome, ide_favorito)
super(nome) @ide_favorito = ide_favorito
end # redefinimos o método diz_ola no Consultor def diz_ola
superputs "O IDE favorito é #{@ide_favorito}”
endend
paulo = Programador.new(“Paulo”, “TextMate”)paulo.diz_ola
Métodos Getter- e Setterclass Consultor def initialize(nome)
self.nome = nome end
def nome@nome
end
def nome=(nome)@nome = nome
endend
consultor = Consultor.new("Pedro")puts consultor.nomeconsultor.nome = "David"puts consultor.nome
attr_accessor
class Consultor attr_accessor :nome def initialize(nome)
self.nome = nomeend
end
consultor = Consultor.new("Paulo")puts consultor.nomeconsultor.nome = "David"puts consultor.nome
attr_writer class Consultorattr_writer :pago
def initialize
@pago = falseend
def pago?@pago
end
def recebe_pagamento... codigo que executa o pagamento...pago = true # Indicate payment is done
endend
consultor = Consultor.newconsultor.recebe_pagamentoputs consultor.pago?
Métodos
•Quando se invoca um método os parêntesis nos argumentos são opcionais.•Os Métodos têm sempre um receptor. O receptor implícito é self.•Os métodos são identificados pelos seus nomes apenas, não existe overloading com assinaturas de argumentos•Existem métodos de classe e métodos de instância.•Os métodos podem ser públicos, protegidos ou privados.•A última expressão que é avaliada num método é o valor de retorno.•Os argumentos podem ter valores por defeito ex:def meu_metodo(a, b = {:consultor=>’senior’})
Convenções
• MinhaClasse• method_name, dangerous_method!, question_method?, setter_method=• MINHA_CONSTANTE = 3.14• variavel_local = 3.14• @variavel_instancia• @@variavel_classe• $variavel_global
Expressões Booleanas
• Todos os objectos devolvem verdade excepto false e nil• false e true são as únicas instancias da FalseClass and TrueClass• As expressões booleanas devolvem o último objecto avaliado.• a and b or c <=> (a and b) or c• a = b and c <=> (a = b) and c• a = b && c <=> a = (b && c)• puts a if a = b # Using assignments in boolean expressions• a = true; b = false; a and b and c() # => c() não é invocado
Atribuições
• a, b = b, a # trocar os valores• a = 1; b = 1• a = b = 1• a += 1 # a = a + 1• a, b = [1, 2]• a = b || c• a ||= b
Idiomatic Ruby# Extra verboso:user_id = nil
if commentsif comments.first
if comments.first.useruser_id = comments.first.user.id
endend
end
# Idiomatico:user_id = comments && comments.first &&comments.first.user && comments.first.user.id
Módulos# Mixins - em vez de herança múltipla
module NomeCompletodef nome_completo
"#{primeiro_nome} #{ultimo_nome}"end
end
class Consultorinclude NomeCompleto
end
Consultor.new("John", "Travolta").nome_completo
Módulos# Namespaces - para evitar colisões de nomesmodule MinhaApp class Consultor
attr_accessor :name
def initialize(name)self.name = name
end endend
MinhaApp::Consultor.new("John Travolta")
Modules vs Classes
• Os Módulos modelam características ou propriedades de entidades ou coisas. Os Módulos não podem ser instanciados.•Os nomes dos Módulos têm tendencia para serem adjectivos (Comparable, Enumerable etc.). •Uma class pode “mix in” vários módulos.•As classes modelam entidades ou coisas.•Os nomes das classes têm tendencia para serem substantivos, coisas.•Uma classe somente pode ter uma super-classe.
Tudo é um objecto
• 2 + 2 é equivalente a 2+(2) e 2.send(:+, 2)• 2.hours.ago• 2.class # => Fixnum• 2.class.methods - Object.methods• “workshop rails”.capitalize
Constantes
•As constantes definidas numa class/module estão disponiveis dentro dessa class/module e fora da classe com o operador scope ::• As constantes definidas fora da class/module podem ser acedidas de todo o lado.•As constantes não podem ser definidas nos métodos
Introspection
•andreas = Consultor.new(“Andreas”)•andreas.inspect•andreas.class # => Consultor•andreas.class.superclass # => Object•andreas.class.superclass.superclass # => nil•andreas.ancestors # lists Modules•Consultor.instance_methods(false)•puts Kernel.methods.join(“\n”)
Aritmética e Conversões2.class == Fixnum
Fixnum.superclass == Integer
Integer.superclass == Numeric
3.0.class == Float
Float.superclass == Numeric
2/3 == 0 ; 2/3.0 # => 0.6666667 ; 2 + 3.0 == 5.0 ;
“2”.to_i + “3.0”.to_f == 5.0
10000000000.class == Bignum ; Bignum.superclass == Integer
2 + “3” # => TypeError: String can’t be coerced into
String class• “ruby”.upcase + “ “ + “rails”.capitalize
• “time is: #{Time.now}\n second line”
• ‘no interpolation “here” #{Time.now}’
• “I“ << “Go” << “Ruby”
• %Q(“C” och “Java”} # “\”C\” och \”Java\””
• %q{single ‘quoted’} # ‘single \’quoted\’’
• <<-END
A here
document at #{Time.now}
END
array classa = [“Ruby”, 99, 3.14] ; a[1] == 99 ; a << “Rails”
[‘C’, ‘Java’, ‘Ruby’] == %w{C Java Ruby}
[1, 2, 3].map { |x| x**2 }.join(“, “)
[1, 2, 3].select { |x| x % 2 == 0 }
[1, 2, 3].reject { |x| x < 3 }
[1, 2, 3].inject { |sum, i| sum + i }
[1, [2, 3]].flatten! # => [1, 2, 3]
raise “Invalid language” if ! %w {C Java Ruby}.include?(language)
fruits = [‘apple’, ‘banana’]
fruits += [‘apple’] unless fruits.include?(‘apple’)
fruits |= [‘apple’]
hash class
h = {:lang => ‘Ruby’, :framework => ‘Rails’}
h[:lang] == ‘Ruby’
h[:perl] == nil
ENV = {“USER” => “peter”, “SHELL” => “/bin/bash”}
ENV.each {|k, v| puts “#{k}=#{v}” }
Symbols
# Os Symbols començam com :
:action.class == Symbol
:action.to_s == “action”
:action == “action”.to_sym
# Existe apenas uma instancia de cada simbolo
:action.equal?(:action) # => true
‘action’.equal?(‘action’) # => false
# tipicamente são utilizados como chaves nas tabelas de Hash
link_to “Home”, :controller => “home”
Mais sobre os métodos
• Um número arbitrário de argumentos: def my_methods(*args)
• Converter um Array para argumentos: my_method([a, b]*)
• Invocação dinámica de um método: object.send(:method_name)
• Duck typing: object.respond_to?(:nome_metodo)
• Se o último argumento é uma Hash table, as chavetas podem ser omitidas: link_to “Home”, :controller => ‘home’
if, unless e o operador ?
message = if count > 10 “Try again”
elsif tries == 3
“You lose”
else
“Enter command”
end
raise “Unauthorized” if !current_user.admin?
raise “Unauthorized” unless current_user.admin?
status = input > 10 ? “Number too big” : “ok”
Iterators: while, until, and forwhile count < 100
puts count count += 1end
pagamento.make_request while (pagamento.failure? and pagamento.tentativas < 3)
for user in @users next if user.admin? if user.pago? puts user break endend
until count > 5 puts count count += 1end
# Statement modifier version of untilputs(count += 1) until count > 5
casecase x
when 0when 1, 2..5
puts "Second branch"when 6..10
puts "Third branch"when *[11, 12]
puts “Fourth branch”when String: puts “Fifth branch”when /\d+\.\d+/
puts “Sixth branch”when x.downcase == “peter”
puts “Seventh branch”else
puts "Eight branch"end
Blocos, fechos, e objectosproc
def invoke_blockputs "before block"yield 5puts "after block"
endname = "Ruby"invoke_block { |n| puts "In block with #{name}, received #{n}"}my_proc = Proc.new { |n| puts "In proc, received #{n}"}my_proc.call 2invoke_block &my_proc
Exemplos de utilização de Blocos# Iteração
[1, 2, 3].each {|item| puts item }
# Utilizar Recursosfile_contents = open(file_name) { |f| f.read }
# Callbackswidget.on_button_press do
puts “Got button press”end
# Convençaõ: blocos só de uma linha utilizam {...} e os blocos multilinha usam do ... end
operações frequentes em strings
•“ “.blank? == true•my_string.each_with_index { |line, i| puts “#{i}: #{line}” }•“abc”.scan(/./).each { |char| puts char }•“we split words”.split.join(“, “)•“ strip space “.strip•sprintf(“value of %s is %.2f”, “PI”, 3.1416)•“I Go Ruby”[2, 2] == “I Go Ruby”[2..3] == “Go”
Uff... ainda não acabou ?
Para uma próxima oportunidade:- Expressões regulares- Exceptions- Reabertura de classes e monkey patching
Metaprogramação com:- method_missing, const_missing, eval, binding, instance_eval class_eval / module_eval
Instalação do Ruby
Instalação
Pré-instalado em MAC
Em Windows: One-Click-Installer:
http://rubyforge.org/frs/?group_id=167
Em Linux:
http://www.ruby-lang.org/en/downloads/
Introdução à consola IRB
IRB
consola interactiva de Ruby
basta escrever irb na shell
Futuro do Ruby
Futuro do Ruby
• versão 1.9.1
• outras inovações previstas
Introdução ao Ruby on Rails
Framework open-source para construção de aplicações web
utilizando a linguagem de programação Ruby.
PessoasTempo
DistanciaFuso Horário
Limitações
REAL
baseado em necessidades reais
DRY
elimina tarefas repetitivas
COC
adopta convenções
ÁGIL
aberto a mudanças no desenvolvimento
PríncipiosDRY: Don’t Repeat Yourself
Cada coisa no seu sítio
Reduzir a quantidade de código reduz erros
COC: Convenção sobre Configuração
Torna as aplicações mais fáceis de entender
Menos trabalho de desenvolvimento
Só precisamos de configurar situações extra-
• Desenhado para a “felicidade” do programador
• Felicidade + Motivação = produtividade
• Ambiente de testes incluído
• Flexibilidade perante as mudanças
• Velocidade de desenvolvimento (agilidade)
• Beleza do código
VídeoBlog em 15 Minutos
http://rubyonrails.org/screencasts
Bons exemplos de aplicações
• Basecamp• Twitter • GetSatisfaction• RevolutionHealth• Scribd• Hulu• HighRise• Shopify• La Coctelera
Lá fora
• Book Worms
• Goplan
• InfoFranchising
• Casa Certificada
• Alta de Lisboa
• Adega Mayor
Cá dentro
Perguntas ?
Obrigado
Emanuel Mota www.ruby-pt.org - emanuel.mota@gmail.com
Pedro Sousa www.thinkorange.pt - psousa@thinkorange.pt