SlideShare uma empresa Scribd logo
1 de 239
Edgar J. Suarez
   http://rails.mx
Ruby
1993
Yukihiro Matsumoto
...computer engineers, focus on the machines. They think, "By
    doing this, the machine will run faster. By doing this, the
   machine will run more effectively..." They are focusing on
  machines. But in fact we need to focus on humans, on how
           humans care about doing programming...

          We are the masters. They are the slaves.
"I hope to see Ruby help every programmer
 in the world to be productive, and to enjoy
 programming, and to be happy. That is the
     primary purpose of Ruby language."
Perl + Smalltalk + Eiffel + Lisp
Dynamic Typing
x = 1
x = "hoge"
x = Class
Duck typing
"When I see a bird that walks like a duck
 and swims like a duck and quacks like a
      duck, I call that bird a duck."
Readable
(human friendly)
3.times do |i|
  puts "Now i is #{i}"
end

@user.is_admin?

@transaction.complete!
Flexible syntax
say_hello()
say_hello

multiply(3, 2)
multiply 3, 2
Reflexive
(metaprogramming)
a = "by_name"

eval <<-eos
  def find_#{a}(name)
    puts "finding by name"
  end
eos

find_by_name("edgar") # => "finding by name"
Iterators / blocks
5.times do
  puts "Hello"
end

['ruby', 'rocks'].each do |word|
  puts word
end

1.upto(3) do |i|
  puts i
end
Exception handling
begin
  this_line.could_throw_an_exception!
rescue Exception => e
  puts "Exception rescued: #{e}"
end
Object oriented
person.say_hi

3.to_s

"a string".capitalize

[].empty?

nil.class # => NilClass
Data types
3.class                      #   =>   Fixnum
4.24.class                   #   =>   Float
"Campus".class               #   =>   String
[1, 2, 3, 4].class           #   =>   Array
(10..15).class               #   =>   Range
:name.class                  #   =>   Symbol
{ :name => "Maria" }.class   #   =>   Hash
Symbols
"name".object_id # => 2156968560
"name".object_id # => 2156964240

:name.object_id # => 68828
:name.object_id # => 68828
Hashes
{
    "name" => "John",
    2      => 54,
    true   => "(345) 434-554"
}
{
    :name => "John",
    :age   => 54,
    :phone => "(345) 434-554"
}
Automatic Garbage
    Collection
Boolean coercion
(everything is true except false and nil)
Open classes
class Person
  def walk
    "walking..."
  end
end

juan = Person.new
juan.walk # => "walking..."

class Person
  def eat
    "eating..."
  end
end

juan.eat # => "eating..."
Default arguments
def multiply(a, b = 2)
  a * b
end

multiply 3, 4 # => 12

multiply 4 # => 8
Splat arguments
def menu_list(*args)
  options = args.pop
  args.each do |arg|
    puts "<a href='#' style='#{options[:style]}'>#{arg}</a>"
  end
end

menu_list   :home, :about, :contact, {:style => "color: green;"}
  # => <a   href=’#’ style=’color: green;’>home</a>
  # => <a   href=’#’ style=’color: green;’>about</a>
  # => <a   href=’#’ style=’color: green;’>contact</a>

menu_list :home, :about, {:style => "color: green;"}
  # => <a href=’#’ style=’color: green;’>home</a>
  # => <a href=’#’ style=’color: green;’>about</a>
Attributes
class Person

  def name=(name)
    @name = name
  end

  def name
    @name
  end

end

a = Person.new
a.name = "Pepe"
a.name # => Pepe
class Person

  attr_accessor :name
  attr_reader   :age
  attr_writer   :phone

end
“Class” methods
class Number
  def self.sum(a, b)
    a + b
  end

  def Number.pow(a, b)
    a ** b
  end
end

Number.sum(2, 2) # => 4
Number.pow(4, 2) # => 16
Self
class Number
  def self.base
    10
  end

  def self.parse(str)
    str.to_i(self.base)
  end
end

Number.parse("30") # => 30
class Person
  attr_accessor :first_name, :last_name

  def full_name
    "#{self.first_name} #{self.last_name}"
  end
end

raul = Person.new
raul.first_name = "Raul"
raul.last_name = "Mendez"
raul.full_name # => Raul Mendez
Inheritance
class Shape
  def area
    @a * @b
  end
end

class Square < Shape
end

sq = Square.new
sq.area
class Shape
  def area
    @a * @b
  end
end

class Square < Shape
  def area
    if @a == @b
      @a * @a
    else
      super
    end
  end
end

sq = Square.new
sq.area
Mixins
module Walkable
  def walk
    puts "I'm walking"
  end
end

module Runnable
  def run
    puts "I'm running"
  end
end

class Person
  include Walkable
  include Runnable
end

joe = Person.new
joe.walk # => I'm walking
joe.run # => I'm running
module Summable
  def sum(a, b)
    a + b
  end
end

class Number
  extend Summable
end

Number.sum 2, 4 # => 6
Namespaces
module ActiveRecord
  class Base

  end
end

ActiveRecord::Base.new
Blocks
3.times do
  puts "hey"
end

3.times { puts "hey" }
3.times do
  puts "hey"
end

class Fixnum

  def times
    i = 0
    while i < self
      yield
      i += 1
    end
  end

end
3.times do
  puts "hey"
end

class Fixnum

  def times(&block)
    i = 0
    while i < self
      block.call
      i += 1
    end
  end

end
3.times do           3.times do
  puts "hey"           puts "hey"
end                  end

class Fixnum         class Fixnum

  def times            def times(&block)
    i = 0                i = 0
    while i < self       while i < self
      yield                block.call
      i += 1               i += 1
    end                  end
  end                  end

end                  end
3.times do |i|
  puts i
end

class Fixnum

  def times
    i = 0
    while i < self
      yield(i)
      i += 1
    end
  end

end
Gems
http://rubygems.org/
$ gem install rails
$ gem list
$ gem uninstall bundler
Implementations
• MRI (Matz)
• JRuby (java)
• Rubinius (Ruby)
• IronRuby (.NET)
• MacRuby (Cocoa)
• REE (Enterprise Edition)
Versions
1.8.7
1.9.2
Installation
Windows
Ruby Installer - http://j.mp/rubywindows
Linux / Mac
 RVM - http://j.mp/installrvm
Live CD
Ubuntu - http://j.mp/railsmxlivecd
Ruby on Rails
July 2004
David Heinemeier
    Hansson
     @ 37signals
$ rails new isshoni -d mysql
+-isshoni/
  +-app/
  +-config/
  +-db/
  +-public/
Bundler
$ gem install bundler
Gemfile
source 'http://rubygems.org'

gem 'rails', '3.0.9'
gem 'mysql2', '0.2.7'
$ bundle install
MVC
+-isshoni/
  +-app/
  | +-controllers/
  | +-models/
  | +-views/
  +-config/
  +-db/
  +-public/
Models
ORM
ActiveRecord
Database
+-isshoni/
  +-app/
  +-config/
  | +-database.yml
  +-db/
  +-public/
login: &login
  adapter: mysql2
  encoding: utf8
  username: root
  password:

development:
  <<: *login
  database: isshoni_development

test:
  <<: *login
  database: isshoni_test

production:
 <<: *login
  database: isshoni_production
$ rails g model User name:string email:string
+-isshoni/
  +-app/
  | +-models/
  | | +-user.rb
  +-config/
  +-db/
  | +-migrate/
  | | +-201107211030001_create_users.rb
  +-public/
class User < ActiveRecord::Base
end
class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :name
      t.string :email
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end
$ rails g model Profile user_id:integer about:text
+-isshoni/
  +-app/
  | +-models/
  | | +-user.rb
  | | +-profile.rb
  +-config/
  +-db/
  | +-migrate/
  | | +-201107211030001_create_users.rb
  | | +-201107211035002_create_profiles.rb
  +-public/
class Profile < ActiveRecord::Base
end
class CreateProfiles < ActiveRecord::Migration
  def self.up
    create_table :profiles do |t|
      t.integer :user_id
      t.text :about
      t.timestamps
    end
  end

  def self.down
    drop_table :profiles
  end
end
Migrations
$   rake   db:create
$   rake   db:migrate
$   rake   db:rollback
$   rake   db:drop
Associations
has_one
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy
end
@user = User.new
@user.profile = Profile.new
@user.profile.about = “Me”
belongs_to
class Profile < ActiveRecord::Base
  belongs_to :user
end
@profile.user # => #<User id:1>
has_many
class User < ActiveRecord::Base
  has_many :addresses
end
@user.addresses = []
@user.addresses.push(Address.new)
Persistence
@user = User.new
@user.save

@user = User.create
@user = User.new
@user.new_record? # => true

@user.save

@user.new_record? # => false
@user = User.create
@user.new_record? # => false
@user = User.new(:name => “Raj”)
@user.save
@user.name # => Raj

@user = User.create(:name => “Penny”)
@user.name # => Penny
Callbacks
class User < ActiveRecord::Base

  before_create :set_profile

  private

  def set_profile
    self.profile = Profile.new
  end

end
@user = User.new
@user.save

@user.profile # => <#Profile id: 1, about: nil>
Validations
class User < ActiveRecord::Base

  validates_presence_of :email
  validates_uniqueness_of :email

end
@user = User.new
@user.save # => false

@user.valid? # => false

@user.errors # => { :email => [“Can’t be blank”] }

@user.email = “foo@bar.com”
@user.save # => true
Finders / Arel / SQL
@user = User.find(3)
# => SELECT * FROM users WHERE id = 3;

@user = User.find_by_name(“Joe”)
# => SELECT * FROM users WHERE name = ‘Joe’ LIMIT 1;

@user = User.first
# => SELECT * FROM users LIMIT 1;
@users = User.all
# => SELECT * FROM users;

@users = User.where(:name => “John”)
# => SELECT * FROM users WHERE name = ‘John’;

@users = User.where(“name LIKE ?”, “Jo%”)
# => SELECT * FROM users WHERE name LIKE ‘Jo%’;
@users = User.order(“created_at DESC”)
# => SELECT * FROM users ORDER BY created_at DESC;

@users = User.joins(:profile).where(“profiles.about IS NULL”)
# => SELECT * FROM users LEFT OUTER JOIN profiles ON users.id =
profiles.user_id WHERE profiles.about IS NULL;
Scopes
class User < ActiveRecord::Base

  scope :with_name, where(“name IS NOT NULL”)

end
User.with_name
# => SELECT * from users WHERE name
IS NOT NULL;
User.with_name.where(“email = ‘foo@bar.com’”)
# => SELECT * FROM users WHERE name IS NOT NULL AND
email = ‘foo@bar.com’;
Controllers
REST
GET /users

GET /users/2
POST /users

PUT /users/2

DELETE /users/2
Routing
+-isshoni/
  +-app/
  +-config/
  | +-routes.rb
  +-db/
  +-public/
Isshoni::Application.routes.draw do

  get '/users'            =>   'users#index'
  get '/users/:id'        =>   'users#show'
  get '/users/new'        =>   'users#new'
  post '/users'           =>   'users#create'
  get '/users/:id/edit'   =>   'users#edit'
  put '/users/:id'        =>   'users#update'
  delete '/users/:id'     =>   'users#destroy'

end
Isshoni::Application.routes.draw do

  resources :users

end
Isshoni::Application.routes.draw do

  resources :users, :only => [:index, :show]

end
Isshoni::Application.routes.draw do

  resources :users do
    resources :ideas
  end

end

# => /users/:id/ideas
Isshoni::Application.routes.draw do

 resources :users do
   match '/activate' => 'users#activate', :on => :member
 end

end

# => /users/:id/activate
Isshoni::Application.routes.draw do

 resources :users do
   match '/active' => 'users#active', :on => :collection
 end

end

# => /users/active
Actions
$ rails g controller users
+-isshoni/
  +-app/
  | +-controllers/
  | | +-application_controller.rb
  | | +-users_controller.rb
  +-config/
  +-db/
  +-public/
class UsersController < ApplicationController

end
class ApplicationController < ActionController::Base
end
Isshoni::Application.routes.draw do

  get '/users'            =>   'users#index'
  get '/users/:id'        =>   'users#show'
  get '/users/new'        =>   'users#new'
  post '/users'           =>   'users#create'
  get '/users/:id/edit'   =>   'users#edit'
  put '/users/:id'        =>   'users#update'
  delete '/users/:id'     =>   'users#destroy'

end
Isshoni::Application.routes.draw do

  resources :users

end
# /users
users_path

# /users/:id
user_path(@user)

# /users/new
new_user_path

# /users/:id/edit
edit_user_path(@user)
class UsersController < ApplicationController

  def index
  end

  def show
  end

  def new
  end

  def create
  end

  def edit
  end

  def update
  end

  def destroy
  end

end
class UsersController < ApplicationController

  # GET /users
  def index
    @users = User.all
  end

end
class UsersController < ApplicationController

  # GET /users/:id
  def show
    @user = User.find(params[:id])
  end

end
class UsersController < ApplicationController

  # GET /users/new
  def new
    @user = User.new
  end

end
class UsersController < ApplicationController

  # POST /users
  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to users_path
    else
      render :new
    end
  end

end
class UsersController < ApplicationController

  # GET /users/:id/edit
  def edit
    @user = User.find(params[:id])
  end

end
class UsersController < ApplicationController

  # PUT /users/:id
  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      redirect_to user_path(@user)
    else
      render :edit
    end
  end

end
class UsersController < ApplicationController

  # DELETE /users/:id
  def destroy
    @user = User.find(params[:id])
    @user.destroy
    redirect_to users_path
  end

end
class UsersController < ApplicationController
  # GET /users
  def index
    @users = User.all
  end
                                                  # GET /users/:id/edit
  # GET /users/:id
                                                  def edit
  def show
                                                    @user = User.find(params[:id])
    @user = User.find(params[:id])
                                                  end
  end
                                                  # PUT /users/:id
  # GET /users/new
                                                  def update
  def new
                                                    @user = User.find(params[:id])
    @user = User.new
                                                    if
  end
                                                @user.update_attributes(params[:user])
                                                      redirect_to user_path(@user)
  # POST /users
                                                    else
  def create
                                                      render :edit
    @user = User.new(params[:user])
                                                    end
    if @user.save
                                                  end
      redirect_to users_path
    else
                                                  # DELETE /users/:id
      render :new
                                                  def destroy
    end
                                                    @user = User.find(params[:id])
  end
                                                    @user.destroy
                                                    redirect_to users_path
                                                  end
                                                end
Filters
class UsersController < ApplicationController
  before_filter :get_user, :only => [:show, :edit, :update, :destroy]

  def show
  end

  def edit
  end

  def update
    if @user.update_attributes(params[:user])
      redirect_to user_path(@user)
    else
      render :edit
    end
  end

  def destroy
    @user.destroy
    redirect_to users_path
  end

 private

  def get_user
    @user = User.find(params[:id])
  end
end
#   . #around (code before yield)
#   . . #before
#   . . . execute action
#   . . -
#   . #around (code after yield)
#   #after
Views
ERb
<%= "Hello" %>
<p><%= 3 * 2 %></p>


     <p>6</p>
<% ["Joe", "Mei"].each do |name| %>
  <p>Hello <%= name %></p>
<% end %>
<p>Hello Joe</p>
<p>Hello Mei</p>
+-isshoni/
  +-app/
  | +-views/
  | | +-users/
  | | | +-index.html.erb
  | | | +-new.html.erb
  | | | +-edit.html.erb
  | | | +-show.html.erb
  | | | +-_form.html.erb
  | | +-layouts/
  | | | +-application.html.erb
  +-config/
  +-db/
  +-public/
application.html.erb
<!DOCTYPE html>
<html>
<head>
  <title>Isshoni</title>
  <%= stylesheet_link_tag 'style' %>
  <%= javascript_include_tag :defaults %>
</head>
<body>
  <%= yield %>
</body>
</html>
<%= stylesheet_link_tag ‘style’ %>
# /public/stylesheets/style.css
<%= javascript_include_tag ‘application’ %>
# /public/javascripts/application.js
<%= yield %>
users/index.html.erb
<h1>Users</h1>
<p><%= link_to 'Add user', new_user_path %></p>

<% @users.each do |user| %>
  <div class="user"><%= user.name %></div>
<% end %>
users/show.html.erb
<h1><%= @user.name %></h1>

<p>
  <strong>Email:</strong>
  <%= @user.email %>
</p>

<p>
  <strong>About:</strong>
  <%= @user.profile.about %>
</p>
users/new.html.erb
<h1>Add user</h1>

<%= form_for @user do |f| %>
  <p>
    <%= f.label :name %>
    <%= f.text_field :name %>
  </p>

  <p>
    <%= f.label :email %>
    <%= f.email_field :email %>
  </p>

 <% f.fields_for :profile do |p| %>
   <p>
     <%= p.label :about %>
     <%= p.text_area :about %>
   </p>
 <% end %>

  <p>
    <%= f.submit %>
  </p>
<% end %>
users/edit.html.erb
<h1>Edit user</h1>

<%= form_for @user do |f| %>
  <p>
    <%= f.label :name %>
    <%= f.text_field :name %>
  </p>

  <p>
    <%= f.label :email %>
    <%= f.email_field :email %>
  </p>

 <% f.fields_for :profile do |p| %>
   <p>
     <%= p.label :about %>
     <%= p.text_area :about %>
   </p>
 <% end %>

  <p>
    <%= f.submit %>
  </p>
<% end %>
Partials
<h1>Add user</h1>

<%= form_for @user do |f| %>
  <%= render :partial => 'form', :object => f %>
<% end %>
<h1>Edit user</h1>

<%= form_for @user do |f| %>
  <%= render :partial => 'form', :object => f %>
<% end %>
users/_form.html.erb
<p>
  <%= form.label :name %>
  <%= form.text_field :name %>
</p>

<p>
  <%= form.label :email %>
  <%= form.email_field :email %>
</p>

<% form.fields_for :profile do |p| %>
  <p>
    <%= p.label :about %>
    <%= p.text_area :about %>
  </p>
<% end %>

<p>
  <%= form.submit %>
</p>
Nested attributes
<% form.fields_for :profile do |p| %>
  <p>
    <%= p.label :about %>
    <%= p.text_area :about %>
  </p>
<% end %>
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy

  accepts_nested_attributes_for :profile
end
Helpers
<%= link_to 'Add user', new_user_path %>
<a href=”/users/new”>Add user</a>

<%= form_for @user do |f| %>
<% end %>
<form action=”/users” method=”post”>
</form>

<%= text_field_tag :name %>
<input type=”text” name=”name” id=”name” />

<%= javascript_include_tag 'application' %>
<script type=”text/javascript” src=”/javascripts/application.js”></script>


<%= image_tag 'background.png' %>
<img src=”/images/background.png” alt=”background” />
Mailers
class UserMailer < ActionMailer::Base
  default :from => "no-reply@foobar.com"

  def password_reset_instructions(user)
    @user = user
    mail :to => @user.email, :subject => "Password Reset"
  end

end
UserMailer.password_reset_instructions(@user).deliver
Security
Mass-assignment
class UsersController < ApplicationController

  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to users_path
    else
      render :new
    end
  end

end
<%= form_for @user do |f| %>
  <p>
    <%= f.label :username %>
    <%= f.text_field :username %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>
<%= form_for @user do |f| %>
  <p>
    <%= f.label :username %>
    <%= f.text_field :username %>
  </p>
  <input type="hidden" name="user[is_admin]" value="1" />
  <p>
    <%= f.submit %>
  </p>
<% end %>
# params[:user] => { :username => "joe", :is_admin => true }
@user = User.new(params[:user])
@user.save

@user.is_admin? # => true
class User < ActiveRecord::Base
  attr_protected :is_admin
end
class User < ActiveRecord::Base
  attr_accessible :username
end
SQL injection
@users = User.where("username LIKE '%#{params[:username]}%'")
# params[:username] = "nick' OR 1 = 1 OR username LIKE '%"
@users = User.where("username LIKE '%#{params[:username]}%'")

# SELECT * FROM users WHERE username LIKE '%nick' OR 1 = 1 OR username LIKE '%';
# params[:username] = "nick' OR 1 = 1 OR username LIKE '%"

@users = User.where("username LIKE ?", "%#{params[:username]}%")

# SELECT * FROM users WHERE username LIKE 'nick' OR 1 = 1 OR username LIKE '%';
XSS
mysite.com                  badsite.com




     POST mysite.com/delete_account
class ApplicationController < ActionController::Base
  protect_from_forgery
end
<head>
  <%= csrf_meta_tag %>
</head>


<head>
  <meta name="csrf-param" content="authenticity_token"/>
  <meta name="csrf-token" content="W8oH32123LgvCYNlVjQXsPAcLigB8CtX8eXYBGyp3yE="/>
</head>
Log Filtering
+-isshoni/
  +-app/
  +-config/
  +-db/
  +-public/
  +-log/
  | +-production.log
Started POST "/sessions" for 127.0.0.1 at Sat Jun 25 19:43:44 -0500 2011
  Processing by SessionsController#create as HTML
  Parameters: {"password"=>"123456", "email"=>"foo@bar.com"}
  SQL (0.5ms) SHOW TABLES
  Account Load (0.2ms) SELECT `accounts`.* FROM `accounts` WHERE
`accounts`.`email` = 'foo@bar.com' LIMIT 1
Completed 200 OK in 274ms (Views: 66.3ms | ActiveRecord: 0.7ms)
+-isshoni/
  +-app/
  +-config/
  | +-application.rb
  +-db/
  +-public/
  +-log/
module Deli
  class Application < Rails::Application

   config.filter_parameters += [:password]

  end
end
Started POST "/sessions" for 127.0.0.1 at Sat Jun 25 19:43:44 -0500 2011
  Processing by SessionsController#create as HTML
  Parameters: {"password"=>"[FILTERED]", "email"=>"foo@bar.com"}
  SQL (0.5ms) SHOW TABLES
  Account Load (0.2ms) SELECT `accounts`.* FROM `accounts` WHERE
`accounts`.`email` = 'foo@bar.com' LIMIT 1
Completed 200 OK in 274ms (Views: 66.3ms | ActiveRecord: 0.7ms)
I18n / L10n
+-isshoni/
  +-app/
  +-config/
  | +-application.rb
  +-db/
  +-public/
  +-log/
module Deli
  class Application < Rails::Application

   config.i18n.default_locale = :es

  end
end
<h1><%= I18n.t('home.title') %></h1>

<h2><%= t('home.subtitle') %></h2>
+-isshoni/
  +-app/
  +-config/
  | +-locales/
  |   | +-es.yml
  +-db/
  +-public/
  +-log/
es:
  home:
    title: "Ruby en la CP"
    subtitle: "Taller de RoR en CP"
<h1>Ruby en la CP</h1>

<h2>Taller de RoR en CP</h2>
+-isshoni/
  +-app/
  +-config/
  | +-locales/
  |   | +-es.yml
  |   | +-en.yml
  +-db/
  +-public/
  +-log/
en:
  home:
    title: "Ruby at CP"
    subtitle: "RoR workshopt at CP"
class ApplicationController < ActionController::Base
  before_filter :set_language

 private

  def set_language
    I18n.locale = params[:lang].to_sym if params[:lang]
  end
end
http://mysite.com/users?lang=en
<h1>Ruby at CP</h1>

<h2>RoR workshop at CP</h2>
Console
$ rails console
Loading development environment (Rails 3.0.9)
>>
Loading development environment (Rails 3.0.7)
>> User.all
=> []
Loading development environment (Rails 3.0.7)
>> User.all
=> []
>> User.create(:username => 'Testing')
=> #<User id: 2, username: "Testing", email: nil>
Best practices
DRY
(Don’t Repeat Yourself)
KISS
(Keep It Simple Stupid)
Convention over
 configuration
Fat models, thin
  controllers
TDD / BDD
Thanks!
Edgar J. Suarez
  @edgarjs

Mais conteúdo relacionado

Mais procurados

Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The Libraries
Simon Willison
 

Mais procurados (20)

7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
 
PubNative Tracker
PubNative TrackerPubNative Tracker
PubNative Tracker
 
Rediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The LibrariesRediscovering JavaScript: The Language Behind The Libraries
Rediscovering JavaScript: The Language Behind The Libraries
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2
 
An (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to PythonAn (Inaccurate) Introduction to Python
An (Inaccurate) Introduction to Python
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
Ruby 101
Ruby 101Ruby 101
Ruby 101
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
Barcelona.pm Curs1211 sess01
Barcelona.pm Curs1211 sess01Barcelona.pm Curs1211 sess01
Barcelona.pm Curs1211 sess01
 
jQuery introduction
jQuery introductionjQuery introduction
jQuery introduction
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
 
Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)Why is Haskell so hard! (And how to deal with it?)
Why is Haskell so hard! (And how to deal with it?)
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language Relations
 
Closure, Higher-order function in Swift
Closure, Higher-order function in SwiftClosure, Higher-order function in Swift
Closure, Higher-order function in Swift
 
Python 1
Python 1Python 1
Python 1
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 

Destaque

Destaque (8)

WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on RailsWorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
WorkshopCamp Mexico 09 - Uniendo los puntos con Ruby on Rails
 
Workshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a RubyWorkshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a Ruby
 
WorkshopCamp México - BDD
WorkshopCamp México - BDDWorkshopCamp México - BDD
WorkshopCamp México - BDD
 
Productividad para programadores
Productividad para programadoresProductividad para programadores
Productividad para programadores
 
Productividad en el Equipo de Desarrollo de Software
Productividad en el Equipo de Desarrollo de SoftwareProductividad en el Equipo de Desarrollo de Software
Productividad en el Equipo de Desarrollo de Software
 
¿Se puede medir la productividad del área de desarrollo?
¿Se puede medir la productividad del área de desarrollo?¿Se puede medir la productividad del área de desarrollo?
¿Se puede medir la productividad del área de desarrollo?
 
The Presentation Come-Back Kid
The Presentation Come-Back KidThe Presentation Come-Back Kid
The Presentation Come-Back Kid
 
The Buyer's Journey - by Chris Lema
The Buyer's Journey - by Chris LemaThe Buyer's Journey - by Chris Lema
The Buyer's Journey - by Chris Lema
 

Semelhante a Desarrollando aplicaciones web en minutos

Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
aztack
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
Nando Vieira
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Jon Kruger
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
Jano Suchal
 

Semelhante a Desarrollando aplicaciones web en minutos (20)

Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Ruby on Rails
Ruby on RailsRuby on Rails
Ruby on Rails
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Ruby
RubyRuby
Ruby
 
Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is Awesome
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Ruby Intro {spection}
Ruby Intro {spection}Ruby Intro {spection}
Ruby Intro {spection}
 

Último

Último (20)

Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

Desarrollando aplicaciones web en minutos

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n
  177. \n
  178. \n
  179. \n
  180. \n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n
  187. \n
  188. \n
  189. \n
  190. \n
  191. \n
  192. \n
  193. \n
  194. \n
  195. \n
  196. \n
  197. \n
  198. \n
  199. \n
  200. \n
  201. \n
  202. \n
  203. \n
  204. \n
  205. \n
  206. \n
  207. \n
  208. \n
  209. \n
  210. \n
  211. \n
  212. \n
  213. \n
  214. \n
  215. \n
  216. \n
  217. \n
  218. \n
  219. \n
  220. \n
  221. \n
  222. \n
  223. \n
  224. \n
  225. \n
  226. \n
  227. \n
  228. \n
  229. \n
  230. \n
  231. \n
  232. \n
  233. \n
  234. \n
  235. \n
  236. \n
  237. \n
  238. \n
  239. \n