AkitaOnRails.com
slideshare.net/akitaonrails
Thursday, June 4, 2009
2008
Thursday, June 4, 2009
2008
Thursday, June 4, 2009
13 e 14
Outubro
2009
Thursday, June 4, 2009
Thursday, June 4, 2009
~108 slides
~90 min
Thursday, June 4, 2009
www.slideshare.net/akitaonrails
fabio.akita@locaweb.com.br
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
“Especialista em
uma coisa só é um
amador em todo o
resto.”
Thursday, June 4, 2009
Thursday, June 4, 2009
Ruby on Rails 2.3
Ruby 1.8
Novo Ruby 1.9
Thursday, June 4, 2009
Ruby on Rails 2.3
Ruby 1.8
Novo Ruby 1.9
Thursday, June 4, 2009
Ruby on Rails 2.3
Ruby 1.8
Novo Ruby 1.9
Thursday, June 4, 2009
“Matz”
1993
Thursday, June 4, 2009
“Prag Dave”
2001
Thursday, June 4, 2009
“DHH”
2004
Thursday, June 4, 2009
Charles Nutter
2006
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
“Tornar as coisas
simples fáceis e as
coisas complexas
possíveis”
Filosofia Ruby
Thursday, June 4, 2009
Thursday, June 4, 2009
O que dizem
por aí ...
Thursday, June 4, 2009
Pouco usado
Thursday, June 4, 2009
Rails não Escala
Thursday, June 4, 2009
Ruby é Lento
Thursday, June 4, 2009
WTF!?
Thursday, June 4, 2009
Pouco usado
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Rails não Escala
Thursday, June 4, 2009
Thursday, June 4, 2009
Para colocar as coisas em
perspectiva, o Friendster foi
escrito em Java e eles
mudaram para PHP. MySpace
foi escrito em ColdFusion e
eles mudaram para ASP.NET.
Quando as pessoas caem em
problemas de escalabilidade,
normalmente acham que a
linguagem é o problema, mas
eu acho que isso raramente
é a realidade. Blaine Cook
http://www.akitaonrails.com/2008/6/17/chatting-with-blaine-cook-twitter
Thursday, June 4, 2009
“O The New York Times usou Ruby on Rails para
agregar, analizar e mostrar os resultados das
eleições em quase tempo real em um de seus
sites mais acessados de todos os tempos.”
http://www.computerworld.com.au/article/268003/ruby_rails_rolls_into_enterprise?fp=16&fpid=1
Thursday, June 4, 2009
Ruby é Lento
Thursday, June 4, 2009
x mais lento que C++
Thursday, June 4, 2009
x mais lento que C++
0
50
100
Python 2 150
Ruby 1.9 200
Perl
JRuby
Python 3
PHP
Ruby 1.8.6
Thursday, June 4, 2009
Homepage: 331 ms
Thursday, June 4, 2009
Homepage: 331 ms
Total: 5.45 s
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
PHP “puro” 331 req/s
CakePHP 4 a 8 req/s*
Code Igniter 22 a 98 req/s*
Rails (2008) 88 req/s
Thursday, June 4, 2009
PHP “puro” 331 req/s
CakePHP 4 a 8 req/s*
Code Igniter 22 a 98 req/s*
Rails (2008) 88 req/s
Thursday, June 4, 2009
PHP “puro” 331 req/s
CakePHP 4 a 8 req/s*
Code Igniter 22 a 98 req/s*
Rails (2008) 88 req/s
Thursday, June 4, 2009
PHP “puro” 331 req/s
CakePHP 4 a 8 req/s*
Code Igniter 22 a 98 req/s*
Rails (2008) 88 req/s
Thursday, June 4, 2009
Thursday, June 4, 2009
PHP Reload
Java Persistente
Ruby Misto
Thursday, June 4, 2009
PHP Reload
Java Persistente
Ruby Misto
Thursday, June 4, 2009
PHP Reload
Java Persistente
Ruby Misto
Thursday, June 4, 2009
Browser
Rails
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Browser
Rails
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Browser
Rails
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Browser
Rails
Banco Slave
Banco de
Dados
Thursday, June 4, 2009
Browser
Rails
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Browser
Rails
Memcached
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Browser
Rails
Memcached
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Browser
Memcached
Rails
Memcached
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Browser
Memcached Web Caches
Rails
Memcached
Banco de
Banco Slave
Dados
Thursday, June 4, 2009
Performance
!=
Escalabilidade
Thursday, June 4, 2009
Performance
Ghz
“Vertical”
Thursday, June 4, 2009
Escalabilidade
MultiCore
“Horizontal”
Thursday, June 4, 2009
Ruby on Rails
Thursday, June 4, 2009
RUBY
Thursday, June 4, 2009
Rails ActiveSupport
RUBY
Thursday, June 4, 2009
ActionController
ActionPack
ActionView
Rails ActiveSupport
RUBY
Thursday, June 4, 2009
RSpec
describe Product do
include ProductSpecHelper
before(:each) do
@product = Product.new
end
it \"should not be valid when empty\" do
@product.should_not be_valid
end
it \"should be valid when having correct information\" do
@product.attributes = valid_product_attributes
@product.should be_valid
end
end
Thursday, June 4, 2009
RSpec
describe Product do
include ProductSpecHelper
before(:each) do
@product = Product.new
end
it \"should not be valid when empty\" do
rake spec
@product.should_not be_valid
end
it \"should be valid when having correct information\" do
@product.attributes = valid_product_attributes
@product.should be_valid
end
end
Thursday, June 4, 2009
Rotas RESTFul
ActionController::Routing::Routes.draw do |map|
map.connect ':controller/service.wsdl', :action => 'wsdl'
map.resources :products,
:member => {:change_image => :post}
map.resources :addresses
map.resources :orders,
:has_many => [:line_items]
map.namespace :admin do |admin|
admin.resources :users
admin.resources :products
end
end
Thursday, June 4, 2009
Rotas RESTFul
ActionController::Routing::Routes.draw do |map|
GET /products/new
map.connect ':controller/service.wsdl', :action => 'wsdl'
GET /products
map.resources :products,
:member => POST /products
{:change_image => :post}
map.resources :addresses
GET /products/1
map.resources :orders,
GET /products/1/edit
:has_many => [:line_items]
map.namespacePUT /products/1
:admin do |admin|
DESTROY /products/1
admin.resources :users
admin.resources :products
end
end
Thursday, June 4, 2009
Migrations
class RenameAppConfiguration < ActiveRecord::Migration
def self.up
rename_table :app_configurations, :configurations
change_table :configurations do |t|
t.string :type
end
end
def self.down
change_table :configurations do |t|
t.remove :type
end
rename_table :configurations, :app_configurations
end
end
Thursday, June 4, 2009
Migrations
class RenameAppConfiguration < ActiveRecord::Migration
def self.up
rename_table :app_configurations, :configurations
change_table :configurations do |t|
t.string :type
end
end rake db:migrate
def self.down
change_table :configurations do |t|
t.remove :type
end
rename_table :configurations, :app_configurations
end
end
Thursday, June 4, 2009
“Beautiful Code”
Thursday, June 4, 2009
@Transient
public BigDecimal getTotal()
//$Id: Booking.java 5579 2007-06-27 00:06:49Z gavin $ {
package org.jboss.seam.example.booking; return hotel.getPrice().multiply( new BigDecimal( getNights() ) );
}
import java.io.Serializable;
import java.math.BigDecimal; @Transient
import java.text.DateFormat; public int getNights()
import java.util.Date; {
return (int) ( checkoutDate.getTime() - checkinDate.getTime() ) /
import javax.persistence.Basic; 1000 / 60 / 60 / 24;
import javax.persistence.Entity; }
import javax.persistence.GeneratedValue;
import javax.persistence.Id; @Id @GeneratedValue
import javax.persistence.ManyToOne; public Long getId()
import javax.persistence.Temporal; {
import javax.persistence.TemporalType; return id;
import javax.persistence.Transient; }
public void setId(Long id)
import org.hibernate.validator.Length; {
import org.hibernate.validator.NotNull; this.id = id;
import org.hibernate.validator.Pattern; }
import org.jboss.seam.annotations.Name;
@NotNull
@Entity @Basic @Temporal(TemporalType.DATE)
@Name(\"booking\") public Date getCheckinDate()
public class Booking implements Serializable {
{ return checkinDate;
private Long id; }
private User user; public void setCheckinDate(Date datetime)
private Hotel hotel; {
private Date checkinDate; this.checkinDate = datetime;
private Date checkoutDate; }
private String creditCard;
private String creditCardName; @ManyToOne @NotNull
private int creditCardExpiryMonth; public Hotel getHotel()
private int creditCardExpiryYear; {
private boolean smoking; return hotel;
private int beds; }
public void setHotel(Hotel hotel)
public Booking() {} {
this.hotel = hotel;
public Booking(Hotel hotel, User user) }
{
this.hotel = hotel; @ManyToOne @NotNull
this.user = user; public User getUser()
} {
return user;
}
Thursday, June 4, 2009
public int getBeds()
public void setUser(User user)
{
{
return beds;
this.user = user;
}
}
public void setBeds(int beds)
@Basic @Temporal(TemporalType.DATE)
{
@NotNull
this.beds = beds;
public Date getCheckoutDate()
}
{
@NotNull(message=\"Credit card name is required\")
return checkoutDate;
@Length(min=3, max=70, message=\"Credit card name is required\")
}
public String getCreditCardName()
public void setCheckoutDate(Date checkoutDate)
{
{
return creditCardName;
this.checkoutDate = checkoutDate;
}
}
public void setCreditCardName(String creditCardName)
@NotNull(message=\"Credit card number is required\")
{
@Length(min=16, max=16, message=\"Credit card number must 16 digits long\")
this.creditCardName = creditCardName;
@Pattern(regex=\"^\\\\d*$\", message=\"Credit card number must be numeric\")
}
public String getCreditCard()
{
public int getCreditCardExpiryMonth()
return creditCard;
{
}
return creditCardExpiryMonth;
}
public void setCreditCard(String creditCard)
{
public void setCreditCardExpiryMonth(int creditCardExpiryMonth)
this.creditCard = creditCard;
{
}
this.creditCardExpiryMonth = creditCardExpiryMonth;
}
@Transient
public String getDescription()
public int getCreditCardExpiryYear()
{
{
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
return creditCardExpiryYear;
return hotel==null ? null : hotel.getName() +
}
\", \" + df.format( getCheckinDate() ) +
\" to \" + df.format( getCheckoutDate() );
public void setCreditCardExpiryYear(int creditCardExpiryYear)
}
{
this.creditCardExpiryYear = creditCardExpiryYear;
public boolean isSmoking()
}
{
return smoking;
@Override
}
public String toString()
{
public void setSmoking(boolean smoking)
return \"Booking(\" + user + \",\"+ hotel + \")\";
{
}
this.smoking = smoking;
}
}
Thursday, June 4, 2009
class Booking < ActiveRecord::Base
belongs_to :hotel
belongs_to :user
validates_presence_of :hotel
validates_presence_of :user
validates_presence_of :credit_card
validates_presence_of :credit_card_name
validates_length_of :credit_card, :within => 16..16
validates_format_of :credit_card, :with => /^\\\\d*$/
validates_length_of :credit_card_name, :within => 3..70
def total
hotel.price * nights
end
def nights
((checkout_date - checkin_date) / 1.day).round
end
def to_s
\"Booking(#{user},#{hotel})\"
end
end
Thursday, June 4, 2009
class CreateBookings < ActiveRecord::Migration
def self.up
create_table :bookings do |t|
t.references :user
t.references :hotel
t.datetime :checkin
t.datetime :checkout
t.string :credit_card
t.string :credit_card_name
t.integer :credit_card_expiry_month
t.integer :credit_card_expiry_year
t.boolean :smoking
t.integer :beds
t.timestamps
end
end
def self.down
drop_table :bookings
end
end
Thursday, June 4, 2009
190
vs
40
Thursday, June 4, 2009
“Eles servem mais de 23 milhões de visitantes/mês. A conversão resultou em
20 mil linhas de Ruby em vez de 125 mil linhas de Java e, mais importante,
facilitou a dificuldade que tinham em manutenção. Uma vez completo e
otimizado, o site deles agora é mais rápido que antes. Eles também
finalizaram a reescrita do sistema em apenas 3 meses com 4 desenvolvedores.”
http://www.railsonwave.com/railsonwave/2008/6/4/yellowpages-com-migrates-to-rails
Thursday, June 4, 2009
Thursday, June 4, 2009
11 mil
classes!
46 só de
coleções!
Thursday, June 4, 2009
• Classes:
• Modules: • Array
• Enumerable • Hash
• Comparable • Set
• Sorted Set
Thursday, June 4, 2009
1.400 Classes:
•
classesArray
• Modules: •
• Enumerable • Hash
• Comparable 6 de Set
só •
• Sorted
coleções! Set
Thursday, June 4, 2009
Ferramentas
Ágeis
Thursday, June 4, 2009
Gerenciamento
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Repositórios
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Integração
Contínua
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Manutenção
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Thursday, June 4, 2009
Open Source
Thursday, June 4, 2009
Thursday, June 4, 2009
describe BankAccount do
before :each do
@bank_account = BankAccount.new :balance => 250
end
it \"should not be valid\" do
@bank_account.should be_valid
end
it \"should transfer funds successfully\" do
@bank_account.should_receive(:transfer)
.with_args(:amount => 100)
.and_return(true)
@bank_account.execute_transaction(:amount => 100)
@bank_account.balance.should == 150
end
end
Thursday, June 4, 2009
Thursday, June 4, 2009
Funcionalidade: Adição
Para evitar erros bobos
Como um péssimo matemático
Eu quero saber como somar dois números
Cenário: Adicionar dois números
Dado que eu digitei 50 na calculadora
E que eu digitei 70 na calculadora
Quando eu aperto o botão de soma
Então o resultado na calculadora deve ser 120
Thursday, June 4, 2009
Before do
@calc = Calculadora.new
end
Dado /que eu digitei (\\d+) na calculadora/ do |n|
@calc.push n.to_i
end
Quando 'eu aperto o botão de soma' do
@result = @calc.soma
end
Então /o resultado na calculadora deve ser (\\d*)/ do |result|
@result.should == result.to_i
end
Thursday, June 4, 2009
class SignupTest < ActionController::IntegrationTest
def test_trial_account_sign_up
visit home_path
click_link \"Sign up\"
fill_in \"Email\", :with => \"good@example.com\"
select \"Free account\"
click_button \"Register\"
end
end
Thursday, June 4, 2009
0 comments
Post a comment