SlideShare a Scribd company logo
1 of 57
DSL or NoDSL?


José Valim       blog.plataformatec.com   @josevalim
DSL or NoDSL?


   ID                    blog              twitter

José Valim       blog.plataformatec.com   @josevalim
A brief introduction...




José Valim          blog.plataformatec.com   @josevalim
A short story...




José Valim      blog.plataformatec.com   @josevalim
José Valim   blog.plataformatec.com   @josevalim
mail_form




José Valim    blog.plataformatec.com   @josevalim
Contact form recipe




José Valim        blog.plataformatec.com   @josevalim
Contact form recipe

               ✦   Controller (20 LOC)




José Valim            blog.plataformatec.com   @josevalim
Contact form recipe

               ✦ Controller (20 LOC)
               ✦ Model (30 LOC)




José Valim          blog.plataformatec.com   @josevalim
Contact form recipe

               ✦ Controller (20 LOC)
               ✦ Model (30 LOC)

               ✦ View (30 LOC)




José Valim          blog.plataformatec.com   @josevalim
Contact form recipe

               ✦ Controller (20 LOC)
               ✦ Model (30 LOC)

               ✦ View (30 LOC)



               ✦   Mailer (15 LOC)



José Valim            blog.plataformatec.com   @josevalim
Contact form recipe

               ✦ Controller (20 LOC)
               ✦ Model (30 LOC)

               ✦ View (30 LOC)



               ✦ Mailer (15 LOC)
               ✦ View (20 LOC)




José Valim          blog.plataformatec.com   @josevalim
Contact form recipe

               ✦ Controller (20 LOC)
               ✦ Model (30 LOC)

               ✦ View (30 LOC)



               ✦ Mailer (15 LOC)
               ✦ View (20 LOC)




José Valim          blog.plataformatec.com   @josevalim
Let’s create a DSL!




José Valim        blog.plataformatec.com   @josevalim
Domain Speci c Language




José Valim       blog.plataformatec.com   @josevalim
class ContactForm < MailForm::Base
         to "jose.valim@plataformatec.com.br"
         from "contact_form@app_name.com"
         subject "Contact form"

         attributes :name, :email, :message
       end

       ContactForm.new(params[:contact_form]).deliver




José Valim              blog.plataformatec.com          @josevalim
from { |c| "#{c.name} <#{c.email}>" }




José Valim               blog.plataformatec.com      @josevalim
to :author_email

             def author_email
               Author.find(self.author_id).email
             end




José Valim              blog.plataformatec.com     @josevalim
headers { |c|
               { "X-Spam" => "True" } if c.honey_pot
             }




José Valim                blog.plataformatec.com       @josevalim
class ContactForm < MailForm::Base
               to :author_email
               from { |c| "#{c.name} <#{c.email}>" }
               subject "Contact form"

              headers { |c|
                { "X-Spam" => "True" } if c.honey_pot
              }

              attributes :name, :email, :message

               def author_email
                 Author.find(self.author_id).email
               end
             end



José Valim                 blog.plataformatec.com       @josevalim
Issues




José Valim   blog.plataformatec.com   @josevalim
Issues


             ✦   Lacks simplicity




José Valim                 blog.plataformatec.com   @josevalim
Issues


             ✦ Lacks simplicity
             ✦ Reduces programmer happiness




José Valim             blog.plataformatec.com   @josevalim
NoDSL!


José Valim   blog.plataformatec.com   @josevalim
From: GitHub <noreply@github.com>
         To: jose.valim@plataformatec.com.br
         Message-Id: <4bfe3e812c22fc17d@github.com>
         Subject: [GitHub] someone commented on a commit
         Mime-Version: 1.0
         Content-Type: text/plain; charset=utf-8

         MESSAGE BODY




José Valim               blog.plataformatec.com       @josevalim
class ContactForm < MailForm::Base
               attributes :name, :email, :message

               def headers
                 {
                   :to => author_email,
                   :from => "#{name} <#{email}>",
                   :subject => "Contact form"
                 }
               end

               def author_email
                 Author.find(self.author_id).email
               end
             end



José Valim               blog.plataformatec.com      @josevalim
It provides a nice DSL




José Valim          blog.plataformatec.com   @josevalim
It relies on a simple contract




José Valim       blog.plataformatec.com   @josevalim
José Valim   blog.plataformatec.com   @josevalim
Rack




José Valim   blog.plataformatec.com   @josevalim
class RackApp
   def self.call(env)
     [200, { "Content-Type" => "text/html"}, ["Hello"]]
   end
 end




José Valim           blog.plataformatec.com       @josevalim
RackApp = Rack::AppBuilder.new do |env|
               status 200
               headers "Content-Type" => "text/html"
               body ["Hello"]

               after_return {
                 # do something
               }
             end




José Valim                blog.plataformatec.com       @josevalim
Rake and Thor




José Valim      blog.plataformatec.com   @josevalim
task :process do
               # do some processing
             end

             namespace :app do
               task :setup do
                 # do some setup
                 #
               end
             end

             rake app:setup




José Valim            blog.plataformatec.com   @josevalim
task :process do
               # do some processing
             end

             namespace :app do
               task :setup do
                 # do some setup
                 Rake::Task[:process].invoke
               end
             end

             rake app:setup




José Valim            blog.plataformatec.com   @josevalim
class Default < Thor
               def process
                 # do some processing
               end
             end

             class App < Thor
               def setup
                 # do some setup
                 #
               end
             end

             thor app:setup




José Valim        blog.plataformatec.com   @josevalim
class Default < Thor
               def process
                 # do some processing
               end
             end

             class App < Thor
               def setup
                 # do some setup
                 Default.new.process
               end
             end

             thor app:setup




José Valim        blog.plataformatec.com   @josevalim
Rspec and Test::Unit




José Valim         blog.plataformatec.com   @josevalim
# Rspec
             describe User do
               it "should be valid" do
                 User.new(@attributes).should be_valid
               end
             end

             # Test::Unit
             class UserTest < Test::Unit::Case
               def test_user_validity
                 assert User.new(@attributes).valid?
               end
             end




José Valim                 blog.plataformatec.com        @josevalim
A nal story...




José Valim      blog.plataformatec.com   @josevalim
class UsersController < ApplicationController
                  def index
                    @users = User.all


                      respond_to do |format|
                        format.html # index.html.erb
                        format.xml { render :xml => @users }
                    end
                  end


                  def show
                      @user = User.find(params[:id])


                      respond_to do |format|
                        format.html # show.html.erb
                        format.xml   { render :xml => @user }
                      end
                  end


                  def new
                    @user = User.new


                      respond_to do |format|
                        format.html # new.html.erb
                        format.xml { render :xml => @user }
                    end
                  end


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




             Scaffold Controller
                  def create
                      @user = User.new(params[:user])


                      respond_to do |format|
                        if @user.save
                          format.html { redirect_to(@user, :notice => 'User was successfully created.') }
                          format.xml { render :xml => @user, :status => :created, :location => @user }
                        else
                          format.html { render :action => "new" }
                          format.xml   { render :xml => @user.errors, :status => :unprocessable_entity }
                        end
                    end
                  end


                  def update
                      @user = User.find(params[:id])


                      respond_to do |format|
                        if @user.update_attributes(params[:user])
                          format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
                          format.xml { head :ok }
                        else
                          format.html { render :action => "edit" }
                          format.xml   { render :xml => @user.errors, :status => :unprocessable_entity }
                        end
                    end
                  end


                  def destroy
                      @user = User.find(params[:id])
                      @user.destroy


                      respond_to do |format|
                        format.html { redirect_to(users_url) }
                        format.xml { head :ok }
                    end
                  end
                end




José Valim                      blog.plataformatec.com                                                      @josevalim
class UsersController < ApplicationController
               restful!
             end




José Valim                    blog.plataformatec.com         @josevalim
class UsersController < ApplicationController
               restful!

              create do
                before {
                  # do something before
                }

                 success.flash "This is the message"
               end

               create.after do
                 # do something after
               end
             end




José Valim                    blog.plataformatec.com         @josevalim
InheritedResources




José Valim        blog.plataformatec.com   @josevalim
class UsersController < InheritedResources::Base
         def create
           # do something before
           flash[:success] = "This is the message"
           super
           # do something after
         end
       end




José Valim              blog.plataformatec.com       @josevalim
Bene ts




José Valim   blog.plataformatec.com   @josevalim
Bene ts

             ✦   Simple




José Valim                blog.plataformatec.com   @josevalim
Bene ts

             ✦ Simple
             ✦ Less code to maintain




José Valim              blog.plataformatec.com   @josevalim
Bene ts

             ✦ Simple
             ✦ Less code to maintain

             ✦ More time to focus on important

               features




José Valim             blog.plataformatec.com    @josevalim
Bene ts

             ✦ Simple
             ✦ Less code to maintain

             ✦ More time to focus on important

               features
             ✦ Just Ruby™




José Valim             blog.plataformatec.com    @josevalim
José Valim   blog.plataformatec.com   @josevalim
ORM Callbacks




José Valim      blog.plataformatec.com   @josevalim
# DSL
 class User < ActiveRecord::Base
   after_save :deliver_notification, :unless => :admin?
 end

 # NoDSL
 class User < ActiveRecord::Base
   def save(*)
     if super
       deliver_notification unless admin?
     end
   end
 end




José Valim            blog.plataformatec.com      @josevalim
DSL or NoDSL?


José Valim       blog.plataformatec.com   @josevalim
Thank you!




José Valim    blog.plataformatec.com   @josevalim
Questions? Feedback?
                  Opinions?



José Valim         blog.plataformatec.com   @josevalim
Questions? Feedback?
                  Opinions?


   ID                      blog              twitter

José Valim         blog.plataformatec.com   @josevalim

More Related Content

Similar to DSL or NoDSL - Euruko - 29may2010

The Future of Rubymotion
The Future of RubymotionThe Future of Rubymotion
The Future of Rubymotion
Clay Allsopp
 
Vb script tutorial for qtp[1]
Vb script tutorial for qtp[1]Vb script tutorial for qtp[1]
Vb script tutorial for qtp[1]
srikanthbkm
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
Yi-Ting Cheng
 
A Z Introduction To Ruby On Rails
A Z Introduction To Ruby On RailsA Z Introduction To Ruby On Rails
A Z Introduction To Ruby On Rails
railsconf
 

Similar to DSL or NoDSL - Euruko - 29may2010 (20)

Say Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick SuttererSay Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick Sutterer
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplos
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Ruby on Rails
Ruby on RailsRuby on Rails
Ruby on Rails
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Refactoring Workshop (Rails Pacific 2014)
Refactoring Workshop (Rails Pacific 2014)Refactoring Workshop (Rails Pacific 2014)
Refactoring Workshop (Rails Pacific 2014)
 
The Future of Rubymotion
The Future of RubymotionThe Future of Rubymotion
The Future of Rubymotion
 
Vb script tutorial for qtp[1]
Vb script tutorial for qtp[1]Vb script tutorial for qtp[1]
Vb script tutorial for qtp[1]
 
Introduction à Ruby
Introduction à RubyIntroduction à Ruby
Introduction à Ruby
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 
Multi tenant/lang application with Ruby on Rails
Multi tenant/lang application with Ruby on RailsMulti tenant/lang application with Ruby on Rails
Multi tenant/lang application with Ruby on Rails
 
A Z Introduction To Ruby On Rails
A Z Introduction To Ruby On RailsA Z Introduction To Ruby On Rails
A Z Introduction To Ruby On Rails
 
A-Z Intro To Rails
A-Z Intro To RailsA-Z Intro To Rails
A-Z Intro To Rails
 
Merb
MerbMerb
Merb
 
Rails OO views
Rails OO viewsRails OO views
Rails OO views
 
Rails2 Pr
Rails2 PrRails2 Pr
Rails2 Pr
 
Lightning talk
Lightning talkLightning talk
Lightning talk
 
Droidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offlineDroidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offline
 
Introduction to React Native Workshop
Introduction to React Native WorkshopIntroduction to React Native Workshop
Introduction to React Native Workshop
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weibo
 

More from Plataformatec

Do your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf URDo your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf UR
Plataformatec
 
As reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São PauloAs reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
Plataformatec
 
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Plataformatec
 
The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010
Plataformatec
 

More from Plataformatec (15)

Do your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf URDo your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf UR
 
Product Owner - Simples como dizem? - Agile Tour 2011
Product Owner - Simples como dizem? - Agile Tour 2011Product Owner - Simples como dizem? - Agile Tour 2011
Product Owner - Simples como dizem? - Agile Tour 2011
 
As reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São PauloAs reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
Writing your own programming language to understand Ruby better - Euruko 2011
Writing your own programming language to understand Ruby better - Euruko 2011Writing your own programming language to understand Ruby better - Euruko 2011
Writing your own programming language to understand Ruby better - Euruko 2011
 
Railties - Ruby Masters Conf - 26Feb2011
Railties - Ruby Masters Conf - 26Feb2011Railties - Ruby Masters Conf - 26Feb2011
Railties - Ruby Masters Conf - 26Feb2011
 
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
 
Rails 3 - The Developers Conference - 21aug2010
Rails 3 - The Developers Conference - 21aug2010Rails 3 - The Developers Conference - 21aug2010
Rails 3 - The Developers Conference - 21aug2010
 
CRUDing Open Source - WhyDay - 19aug2010
CRUDing Open Source - WhyDay - 19aug2010CRUDing Open Source - WhyDay - 19aug2010
CRUDing Open Source - WhyDay - 19aug2010
 
Rails 3 - RS on Rails - 21aug2010
Rails 3 - RS on Rails - 21aug2010Rails 3 - RS on Rails - 21aug2010
Rails 3 - RS on Rails - 21aug2010
 
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
 
Project Rescue - Oxente Rails - 05aug2010
Project Rescue - Oxente Rails - 05aug2010Project Rescue - Oxente Rails - 05aug2010
Project Rescue - Oxente Rails - 05aug2010
 
The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010
 
Classificação de textos - Dev in Sampa - 28nov2009
Classificação de textos - Dev in Sampa - 28nov2009Classificação de textos - Dev in Sampa - 28nov2009
Classificação de textos - Dev in Sampa - 28nov2009
 
Devise - RSLA - 13oct2009
Devise - RSLA - 13oct2009Devise - RSLA - 13oct2009
Devise - RSLA - 13oct2009
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Recently uploaded (20)

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
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
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
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
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
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
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
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
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
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

DSL or NoDSL - Euruko - 29may2010

  • 1. DSL or NoDSL? José Valim blog.plataformatec.com @josevalim
  • 2. DSL or NoDSL? ID blog twitter José Valim blog.plataformatec.com @josevalim
  • 3. A brief introduction... José Valim blog.plataformatec.com @josevalim
  • 4. A short story... José Valim blog.plataformatec.com @josevalim
  • 5. José Valim blog.plataformatec.com @josevalim
  • 6. mail_form José Valim blog.plataformatec.com @josevalim
  • 7. Contact form recipe José Valim blog.plataformatec.com @josevalim
  • 8. Contact form recipe ✦ Controller (20 LOC) José Valim blog.plataformatec.com @josevalim
  • 9. Contact form recipe ✦ Controller (20 LOC) ✦ Model (30 LOC) José Valim blog.plataformatec.com @josevalim
  • 10. Contact form recipe ✦ Controller (20 LOC) ✦ Model (30 LOC) ✦ View (30 LOC) José Valim blog.plataformatec.com @josevalim
  • 11. Contact form recipe ✦ Controller (20 LOC) ✦ Model (30 LOC) ✦ View (30 LOC) ✦ Mailer (15 LOC) José Valim blog.plataformatec.com @josevalim
  • 12. Contact form recipe ✦ Controller (20 LOC) ✦ Model (30 LOC) ✦ View (30 LOC) ✦ Mailer (15 LOC) ✦ View (20 LOC) José Valim blog.plataformatec.com @josevalim
  • 13. Contact form recipe ✦ Controller (20 LOC) ✦ Model (30 LOC) ✦ View (30 LOC) ✦ Mailer (15 LOC) ✦ View (20 LOC) José Valim blog.plataformatec.com @josevalim
  • 14. Let’s create a DSL! José Valim blog.plataformatec.com @josevalim
  • 15. Domain Speci c Language José Valim blog.plataformatec.com @josevalim
  • 16. class ContactForm < MailForm::Base to "jose.valim@plataformatec.com.br" from "contact_form@app_name.com" subject "Contact form" attributes :name, :email, :message end ContactForm.new(params[:contact_form]).deliver José Valim blog.plataformatec.com @josevalim
  • 17. from { |c| "#{c.name} <#{c.email}>" } José Valim blog.plataformatec.com @josevalim
  • 18. to :author_email def author_email Author.find(self.author_id).email end José Valim blog.plataformatec.com @josevalim
  • 19. headers { |c| { "X-Spam" => "True" } if c.honey_pot } José Valim blog.plataformatec.com @josevalim
  • 20. class ContactForm < MailForm::Base to :author_email from { |c| "#{c.name} <#{c.email}>" } subject "Contact form" headers { |c| { "X-Spam" => "True" } if c.honey_pot } attributes :name, :email, :message def author_email Author.find(self.author_id).email end end José Valim blog.plataformatec.com @josevalim
  • 21. Issues José Valim blog.plataformatec.com @josevalim
  • 22. Issues ✦ Lacks simplicity José Valim blog.plataformatec.com @josevalim
  • 23. Issues ✦ Lacks simplicity ✦ Reduces programmer happiness José Valim blog.plataformatec.com @josevalim
  • 24. NoDSL! José Valim blog.plataformatec.com @josevalim
  • 25. From: GitHub <noreply@github.com> To: jose.valim@plataformatec.com.br Message-Id: <4bfe3e812c22fc17d@github.com> Subject: [GitHub] someone commented on a commit Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 MESSAGE BODY José Valim blog.plataformatec.com @josevalim
  • 26. class ContactForm < MailForm::Base attributes :name, :email, :message def headers { :to => author_email, :from => "#{name} <#{email}>", :subject => "Contact form" } end def author_email Author.find(self.author_id).email end end José Valim blog.plataformatec.com @josevalim
  • 27. It provides a nice DSL José Valim blog.plataformatec.com @josevalim
  • 28. It relies on a simple contract José Valim blog.plataformatec.com @josevalim
  • 29. José Valim blog.plataformatec.com @josevalim
  • 30. Rack José Valim blog.plataformatec.com @josevalim
  • 31. class RackApp def self.call(env) [200, { "Content-Type" => "text/html"}, ["Hello"]] end end José Valim blog.plataformatec.com @josevalim
  • 32. RackApp = Rack::AppBuilder.new do |env| status 200 headers "Content-Type" => "text/html" body ["Hello"] after_return { # do something } end José Valim blog.plataformatec.com @josevalim
  • 33. Rake and Thor José Valim blog.plataformatec.com @josevalim
  • 34. task :process do # do some processing end namespace :app do task :setup do # do some setup # end end rake app:setup José Valim blog.plataformatec.com @josevalim
  • 35. task :process do # do some processing end namespace :app do task :setup do # do some setup Rake::Task[:process].invoke end end rake app:setup José Valim blog.plataformatec.com @josevalim
  • 36. class Default < Thor def process # do some processing end end class App < Thor def setup # do some setup # end end thor app:setup José Valim blog.plataformatec.com @josevalim
  • 37. class Default < Thor def process # do some processing end end class App < Thor def setup # do some setup Default.new.process end end thor app:setup José Valim blog.plataformatec.com @josevalim
  • 38. Rspec and Test::Unit José Valim blog.plataformatec.com @josevalim
  • 39. # Rspec describe User do it "should be valid" do User.new(@attributes).should be_valid end end # Test::Unit class UserTest < Test::Unit::Case def test_user_validity assert User.new(@attributes).valid? end end José Valim blog.plataformatec.com @josevalim
  • 40. A nal story... José Valim blog.plataformatec.com @josevalim
  • 41. class UsersController < ApplicationController def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } end end def show @user = User.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @user } end end def new @user = User.new respond_to do |format| format.html # new.html.erb format.xml { render :xml => @user } end end def edit @user = User.find(params[:id]) end Scaffold Controller def create @user = User.new(params[:user]) respond_to do |format| if @user.save format.html { redirect_to(@user, :notice => 'User was successfully created.') } format.xml { render :xml => @user, :status => :created, :location => @user } else format.html { render :action => "new" } format.xml { render :xml => @user.errors, :status => :unprocessable_entity } end end end def update @user = User.find(params[:id]) respond_to do |format| if @user.update_attributes(params[:user]) format.html { redirect_to(@user, :notice => 'User was successfully updated.') } format.xml { head :ok } else format.html { render :action => "edit" } format.xml { render :xml => @user.errors, :status => :unprocessable_entity } end end end def destroy @user = User.find(params[:id]) @user.destroy respond_to do |format| format.html { redirect_to(users_url) } format.xml { head :ok } end end end José Valim blog.plataformatec.com @josevalim
  • 42. class UsersController < ApplicationController restful! end José Valim blog.plataformatec.com @josevalim
  • 43. class UsersController < ApplicationController restful! create do before { # do something before } success.flash "This is the message" end create.after do # do something after end end José Valim blog.plataformatec.com @josevalim
  • 44. InheritedResources José Valim blog.plataformatec.com @josevalim
  • 45. class UsersController < InheritedResources::Base def create # do something before flash[:success] = "This is the message" super # do something after end end José Valim blog.plataformatec.com @josevalim
  • 46. Bene ts José Valim blog.plataformatec.com @josevalim
  • 47. Bene ts ✦ Simple José Valim blog.plataformatec.com @josevalim
  • 48. Bene ts ✦ Simple ✦ Less code to maintain José Valim blog.plataformatec.com @josevalim
  • 49. Bene ts ✦ Simple ✦ Less code to maintain ✦ More time to focus on important features José Valim blog.plataformatec.com @josevalim
  • 50. Bene ts ✦ Simple ✦ Less code to maintain ✦ More time to focus on important features ✦ Just Ruby™ José Valim blog.plataformatec.com @josevalim
  • 51. José Valim blog.plataformatec.com @josevalim
  • 52. ORM Callbacks José Valim blog.plataformatec.com @josevalim
  • 53. # DSL class User < ActiveRecord::Base after_save :deliver_notification, :unless => :admin? end # NoDSL class User < ActiveRecord::Base def save(*) if super deliver_notification unless admin? end end end José Valim blog.plataformatec.com @josevalim
  • 54. DSL or NoDSL? José Valim blog.plataformatec.com @josevalim
  • 55. Thank you! José Valim blog.plataformatec.com @josevalim
  • 56. Questions? Feedback? Opinions? José Valim blog.plataformatec.com @josevalim
  • 57. Questions? Feedback? Opinions? ID blog twitter José Valim blog.plataformatec.com @josevalim

Editor's Notes