SlideShare uma empresa Scribd logo
1 de 46
Writing a DSL in Ruby
    Why Ruby makes it soooo easy!
DSL!!!!11one
domain specific
      language TL;DR

➡ Customized to specific problem domain
➡ Evaluated in context of the domain
➡ Helps creating ubiquitous language
internal vs. external
„Internal DSLs are particular ways of using a
 host language to give the host language the
        feel of a particular language.“


„External DSLs have their own custom syntax
and you write a full parser to process them.“
internal vs. external
„Internal DSLs are particular ways of using a
 host language to give the host language the
        feel of a particular language.“


„External DSLs have their own custom syntax
and you write a full parser to process them.“
internal vs. external
„Internal DSLs are particular ways of using a
 host language to give the host language the
        feel of a particular language.“



                       er
                     wl
                   Fo
                 tin
                ar
„External DSLs have their own custom syntax
               M


and you write a full parser to process them.“
Rails, collection of DSLs
          • Routes
          • Tag- / Form-Helpers
          • Builder
          • Associations, Migrations, ...
          • Rake / Thor
          • Bundler
          • [...]
all about API design
Ruby makes it easy to create DSL:
           • expressive & concise syntax
           • open classes
           • mixins
           • operator overloading
           • [...]
Gregory Brown   Russ Olsen
DSL by EXAMPLE
Method Params
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"
Method Params
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"


def doit_with(some, parameters)
  # does it
end
Method Params
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"


def doit_with(some, parameters)      def doit_with(mandatory, optional=nil, parameters=nil)
  # does it                            # does it
end                                  end
Method Params
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"


def doit_with(some, parameters)          def doit_with(mandatory, optional=nil, parameters=nil)
  # does it                                # does it
end                                      end




def doit_with(options={:named => 'parameter'})
  # does it
end
Method Params
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"


def doit_with(some, parameters)          def doit_with(mandatory, optional=nil, parameters=nil)
  # does it                                # does it
end                                      end




def doit_with(options={:named => 'parameter'})     def doit_with(mandatory, *optional_paramters)
  # does it                                          # does it
end                                                end
Method Params
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"


def doit_with(some, parameters)          def doit_with(mandatory, optional=nil, parameters=nil)
  # does it                                # does it
end                                      end




def doit_with(options={:named => 'parameter'})     def doit_with(mandatory, *optional_paramters)
  # does it                                          # does it
end                                                end




       def doit_with(*args)
         options = args.pop if Hash === args.last
         name = args.first
         # [...]
         raise ArgumentError, 'Bad combination of parameters' unless args.size == 1
         # does it
       end
Blocks
Twitter.configure do |config|
  config.consumer_key = YOUR_CONSUMER_KEY
  config.consumer_secret = YOUR_CONSUMER_SECRET
end
Blocks
        Twitter.configure do |config|
          config.consumer_key = YOUR_CONSUMER_KEY
          config.consumer_secret = YOUR_CONSUMER_SECRET
        end




def doit_with(&explicit_block)
  explicit_block.call
end
Blocks
        Twitter.configure do |config|
          config.consumer_key = YOUR_CONSUMER_KEY
          config.consumer_secret = YOUR_CONSUMER_SECRET
        end




def doit_with(&explicit_block)     def doit_with_implicit_block
  explicit_block.call                yield if block_given?
end                                end
Blocks
        Twitter.configure do |config|
          config.consumer_key = YOUR_CONSUMER_KEY
          config.consumer_secret = YOUR_CONSUMER_SECRET
        end




def doit_with(&explicit_block)     def doit_with_implicit_block
  explicit_block.call                yield if block_given?
end                                end




              def doit_with_block_for_configuration
                yield self
              end
Blocks
        Twitter.configure do |config|
          config.consumer_key = YOUR_CONSUMER_KEY
          config.consumer_secret = YOUR_CONSUMER_SECRET
        end




def doit_with(&explicit_block)     def doit_with_implicit_block
  explicit_block.call                yield if block_given?
end                                end




              def doit_with_block_for_configuration
                yield self
              end




def doit_with(&arity_sensitive_block)
  arity_sensitive_block.call 'foo', 'bar' if
    arity_sensitive_block.arity == 2
end
Instance Eval
Twitter.configure do |config|
  config.consumer_key = YOUR_CONSUMER_KEY
  config.consumer_secret = YOUR_CONSUMER_SECRET
end
Instance Eval
Twitter.configure do |config|
  consumer_key = YOUR_CONSUMER_KEY
  config.consumer_key = YOUR_CONSUMER_KEY
  consumer_secret = YOUR_CONSUMER_SECRET
  config.consumer_secret = YOUR_CONSUMER_SECRET
end
Instance Eval
Twitter.configure do |config|
  consumer_key = YOUR_CONSUMER_KEY
  config.consumer_key = YOUR_CONSUMER_KEY
  consumer_secret = YOUR_CONSUMER_SECRET
  config.consumer_secret = YOUR_CONSUMER_SECRET
end




  def doit_with(&instance_eval_block)
    if instance_eval_block.arity == 0
      # could also be class_eval, module_eval
      self.instance_eval(&instance_eval_block)
    else
      instance_eval_block.call self
    end
  end
Method Missing
Client.find_by_firstname_and_lastname_and_gender('uschi', 'mueller', :female)
Method Missing
Client.find_by_firstname_and_lastname_and_gender('uschi', 'mueller', :female)




            METHOD_PATTERN = /^find_by_/

            def method_missing(method, *args, &block)
              if method.to_s =~ METHOD_PATTERN
                # finder magic
              else
                super
              end
            end
Method Missing
Client.find_by_firstname_and_lastname_and_gender('uschi', 'mueller', :female)




            METHOD_PATTERN = /^find_by_/

            METHOD_PATTERN = /^find_by_/
            def method_missing(method, *args, &block)
              if method.to_s =~ METHOD_PATTERN
            def method_missing(method, *args, &block)
                # finder magic
              if method.to_s =~ METHOD_PATTERN
              else
                # finder magic
                super
              else
              end
            end super
              end
            end respond_to?(method)
            def
              return true if method =~ METHOD_PATTERN
              super
            end
Code Generation
    client.firstname = 'uschi'

    puts client.lastname
Code Generation
             client.firstname = 'uschi'

             puts client.lastname




 def generate(name)
   self.class.send(:define_method, name){puts name}
   eval("def #{name}() puts '#{name}' end")
   def some_method(name)
     puts name
   end
   # [...]
 end
Makros
class Client < ActiveRecord::Base
  has_one :address
  has_many :orders
  belongs_to :role
end
Makros
class Client < ActiveRecord::Base
  has_one :address
  has_many :orders
  belongs_to :role
end




     class << self
       def has_something
         # macro definition
       end
     end
Hooks
$ ruby simple_test.rb
Hooks
$ ruby simple_test.rb




 at_exit do
   # shut down code
 end
Hooks
                 $ ruby simple_test.rb




                  at_exit do
                    # shut down code
                  end




inherited, included, method_missing, method_added,
method_removed, trace_var, set_trace_func, at_exit ...
Hooks
                      $ ruby simple_test.rb




                       at_exit do
                         # shut down code
                       end




set_trace_func proc { |event, file, line, id, binding, classname|
      inherited, included, method_missing, method_added,
  printf "%8s %s:%-2d trace_var, set_trace_func, line, id,...
      method_removed, %10s %8sn", event, file, at_exit classname
}
Core Extensions
     'text'.blank?
Core Extensions
               'text'.blank?




 class Object
   def blank?
     nil? || (respond_to?(:empty?) && empty?)
   end
 end
Core Extensions
               'text'.blank?




 class Object
   def blank?
     nil? || (respond_to?(:empty?) && empty?)
   end unless method_defined?(:blank?)
 end
Core Extensions
                  'text'.blank?




module MyGem
     class Object
  module CoreExtensions
    module blank?
       def Object
      defnil? || (respond_to?(:empty?) && empty?)
           blank?
       end unless method_defined?(:blank?)
         respond_to?(:empty?) ? empty? : !self
     end
      end
    end
  end
end
Object.send :include, MyGem::CoreExtensions::Object
Ruby techniques

✓Method Params    ✓Makros
✓Blocks           ✓Code generation
✓Instance Eval    ✓Hooks
✓Method Missing   ✓Core Extensions
External DSL
Ruby Tools:
 • Switch Cases
 • Regular Expressions
Ruby Parser:
 • Treetop
 • RACC
Links
★ Eloquent Ruby
★ Ruby Best Practices
★ Domain Specific Languages
★ Rebuil
★ Treetop
Over and Out
Over and Out

Mais conteúdo relacionado

Mais procurados

Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5Jason Austin
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Samuel Fortier-Galarneau
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallySean Cribbs
 
Business Rules with Brick
Business Rules with BrickBusiness Rules with Brick
Business Rules with Brickbrian d foy
 
Twig Brief, Tips&Tricks
Twig Brief, Tips&TricksTwig Brief, Tips&Tricks
Twig Brief, Tips&TricksAndrei Burian
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in PythonBen James
 
Python decorators
Python decoratorsPython decorators
Python decoratorsAlex Su
 
Erlang/OTP for Rubyists
Erlang/OTP for RubyistsErlang/OTP for Rubyists
Erlang/OTP for RubyistsSean Cribbs
 
WordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressWordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressAlena Holligan
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)RORLAB
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationJonathan Wage
 
DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopJeroen Keppens
 
Introduction to Perl Best Practices
Introduction to Perl Best PracticesIntroduction to Perl Best Practices
Introduction to Perl Best PracticesJosé Castro
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPWildan Maulana
 
Introduction to Python decorators
Introduction to Python decoratorsIntroduction to Python decorators
Introduction to Python decoratorsrikbyte
 

Mais procurados (19)

Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
Business Rules with Brick
Business Rules with BrickBusiness Rules with Brick
Business Rules with Brick
 
Twig Brief, Tips&Tricks
Twig Brief, Tips&TricksTwig Brief, Tips&Tricks
Twig Brief, Tips&Tricks
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in Python
 
Python decorators
Python decoratorsPython decorators
Python decorators
 
Erlang/OTP for Rubyists
Erlang/OTP for RubyistsErlang/OTP for Rubyists
Erlang/OTP for Rubyists
 
WordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressWordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPress
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
 
DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark Workshop
 
Introduction to Perl Best Practices
Introduction to Perl Best PracticesIntroduction to Perl Best Practices
Introduction to Perl Best Practices
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
Lettering js
Lettering jsLettering js
Lettering js
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Introduction to Python decorators
Introduction to Python decoratorsIntroduction to Python decorators
Introduction to Python decorators
 

Destaque

Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)Thomas Lundström
 
Bdd for Web Applications at TelecomCity DevCon 2010
Bdd for Web Applications at TelecomCity DevCon 2010Bdd for Web Applications at TelecomCity DevCon 2010
Bdd for Web Applications at TelecomCity DevCon 2010Thomas Lundström
 
Railsify your web development
Railsify your web developmentRailsify your web development
Railsify your web developmentThomas Lundström
 
Agile DSL Development in Ruby
Agile DSL Development in RubyAgile DSL Development in Ruby
Agile DSL Development in Rubyelliando dias
 
BDD approaches for web development at Agile Testing Days 2009
BDD approaches for web development at Agile Testing Days 2009BDD approaches for web development at Agile Testing Days 2009
BDD approaches for web development at Agile Testing Days 2009Thomas Lundström
 
The Hitchhiker’s Guide To Dsl
The Hitchhiker’s Guide To DslThe Hitchhiker’s Guide To Dsl
The Hitchhiker’s Guide To DslKoji SHIMADA
 

Destaque (6)

Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)Ruby for C#-ers (ScanDevConf 2010)
Ruby for C#-ers (ScanDevConf 2010)
 
Bdd for Web Applications at TelecomCity DevCon 2010
Bdd for Web Applications at TelecomCity DevCon 2010Bdd for Web Applications at TelecomCity DevCon 2010
Bdd for Web Applications at TelecomCity DevCon 2010
 
Railsify your web development
Railsify your web developmentRailsify your web development
Railsify your web development
 
Agile DSL Development in Ruby
Agile DSL Development in RubyAgile DSL Development in Ruby
Agile DSL Development in Ruby
 
BDD approaches for web development at Agile Testing Days 2009
BDD approaches for web development at Agile Testing Days 2009BDD approaches for web development at Agile Testing Days 2009
BDD approaches for web development at Agile Testing Days 2009
 
The Hitchhiker’s Guide To Dsl
The Hitchhiker’s Guide To DslThe Hitchhiker’s Guide To Dsl
The Hitchhiker’s Guide To Dsl
 

Semelhante a Dsl

Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the TrenchesXavier Noria
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101Nando Vieira
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2
name name2 n2name name2 n2
name name2 n2callroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.pptcallroom
 

Semelhante a Dsl (20)

Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Designing Ruby APIs
Designing Ruby APIsDesigning Ruby APIs
Designing Ruby APIs
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the Trenches
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Module Magic
Module MagicModule Magic
Module Magic
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 
test ppt
test ppttest ppt
test ppt
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt21
ppt21ppt21
ppt21
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt17
ppt17ppt17
ppt17
 
ppt30
ppt30ppt30
ppt30
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.ppt
 
ppt18
ppt18ppt18
ppt18
 

Último

ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
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 DiscoveryTrustArc
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
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.pdfsudhanshuwaghmare1
 
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 educationjfdjdjcjdnsjd
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 

Último (20)

ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
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
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
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
 
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
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 

Dsl

  • 1. Writing a DSL in Ruby Why Ruby makes it soooo easy!
  • 3. domain specific language TL;DR ➡ Customized to specific problem domain ➡ Evaluated in context of the domain ➡ Helps creating ubiquitous language
  • 4. internal vs. external „Internal DSLs are particular ways of using a host language to give the host language the feel of a particular language.“ „External DSLs have their own custom syntax and you write a full parser to process them.“
  • 5. internal vs. external „Internal DSLs are particular ways of using a host language to give the host language the feel of a particular language.“ „External DSLs have their own custom syntax and you write a full parser to process them.“
  • 6. internal vs. external „Internal DSLs are particular ways of using a host language to give the host language the feel of a particular language.“ er wl Fo tin ar „External DSLs have their own custom syntax M and you write a full parser to process them.“
  • 7. Rails, collection of DSLs • Routes • Tag- / Form-Helpers • Builder • Associations, Migrations, ... • Rake / Thor • Bundler • [...]
  • 8. all about API design Ruby makes it easy to create DSL: • expressive & concise syntax • open classes • mixins • operator overloading • [...]
  • 9.
  • 10.
  • 11. Gregory Brown Russ Olsen
  • 13. Method Params link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"
  • 14. Method Params link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article" def doit_with(some, parameters) # does it end
  • 15. Method Params link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article" def doit_with(some, parameters) def doit_with(mandatory, optional=nil, parameters=nil) # does it # does it end end
  • 16. Method Params link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article" def doit_with(some, parameters) def doit_with(mandatory, optional=nil, parameters=nil) # does it # does it end end def doit_with(options={:named => 'parameter'}) # does it end
  • 17. Method Params link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article" def doit_with(some, parameters) def doit_with(mandatory, optional=nil, parameters=nil) # does it # does it end end def doit_with(options={:named => 'parameter'}) def doit_with(mandatory, *optional_paramters) # does it # does it end end
  • 18. Method Params link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article" def doit_with(some, parameters) def doit_with(mandatory, optional=nil, parameters=nil) # does it # does it end end def doit_with(options={:named => 'parameter'}) def doit_with(mandatory, *optional_paramters) # does it # does it end end def doit_with(*args) options = args.pop if Hash === args.last name = args.first # [...] raise ArgumentError, 'Bad combination of parameters' unless args.size == 1 # does it end
  • 19. Blocks Twitter.configure do |config| config.consumer_key = YOUR_CONSUMER_KEY config.consumer_secret = YOUR_CONSUMER_SECRET end
  • 20. Blocks Twitter.configure do |config| config.consumer_key = YOUR_CONSUMER_KEY config.consumer_secret = YOUR_CONSUMER_SECRET end def doit_with(&explicit_block) explicit_block.call end
  • 21. Blocks Twitter.configure do |config| config.consumer_key = YOUR_CONSUMER_KEY config.consumer_secret = YOUR_CONSUMER_SECRET end def doit_with(&explicit_block) def doit_with_implicit_block explicit_block.call yield if block_given? end end
  • 22. Blocks Twitter.configure do |config| config.consumer_key = YOUR_CONSUMER_KEY config.consumer_secret = YOUR_CONSUMER_SECRET end def doit_with(&explicit_block) def doit_with_implicit_block explicit_block.call yield if block_given? end end def doit_with_block_for_configuration yield self end
  • 23. Blocks Twitter.configure do |config| config.consumer_key = YOUR_CONSUMER_KEY config.consumer_secret = YOUR_CONSUMER_SECRET end def doit_with(&explicit_block) def doit_with_implicit_block explicit_block.call yield if block_given? end end def doit_with_block_for_configuration yield self end def doit_with(&arity_sensitive_block) arity_sensitive_block.call 'foo', 'bar' if arity_sensitive_block.arity == 2 end
  • 24. Instance Eval Twitter.configure do |config| config.consumer_key = YOUR_CONSUMER_KEY config.consumer_secret = YOUR_CONSUMER_SECRET end
  • 25. Instance Eval Twitter.configure do |config| consumer_key = YOUR_CONSUMER_KEY config.consumer_key = YOUR_CONSUMER_KEY consumer_secret = YOUR_CONSUMER_SECRET config.consumer_secret = YOUR_CONSUMER_SECRET end
  • 26. Instance Eval Twitter.configure do |config| consumer_key = YOUR_CONSUMER_KEY config.consumer_key = YOUR_CONSUMER_KEY consumer_secret = YOUR_CONSUMER_SECRET config.consumer_secret = YOUR_CONSUMER_SECRET end def doit_with(&instance_eval_block) if instance_eval_block.arity == 0 # could also be class_eval, module_eval self.instance_eval(&instance_eval_block) else instance_eval_block.call self end end
  • 28. Method Missing Client.find_by_firstname_and_lastname_and_gender('uschi', 'mueller', :female) METHOD_PATTERN = /^find_by_/ def method_missing(method, *args, &block) if method.to_s =~ METHOD_PATTERN # finder magic else super end end
  • 29. Method Missing Client.find_by_firstname_and_lastname_and_gender('uschi', 'mueller', :female) METHOD_PATTERN = /^find_by_/ METHOD_PATTERN = /^find_by_/ def method_missing(method, *args, &block) if method.to_s =~ METHOD_PATTERN def method_missing(method, *args, &block) # finder magic if method.to_s =~ METHOD_PATTERN else # finder magic super else end end super end end respond_to?(method) def return true if method =~ METHOD_PATTERN super end
  • 30. Code Generation client.firstname = 'uschi' puts client.lastname
  • 31. Code Generation client.firstname = 'uschi' puts client.lastname def generate(name) self.class.send(:define_method, name){puts name} eval("def #{name}() puts '#{name}' end") def some_method(name) puts name end # [...] end
  • 32. Makros class Client < ActiveRecord::Base has_one :address has_many :orders belongs_to :role end
  • 33. Makros class Client < ActiveRecord::Base has_one :address has_many :orders belongs_to :role end class << self def has_something # macro definition end end
  • 35. Hooks $ ruby simple_test.rb at_exit do # shut down code end
  • 36. Hooks $ ruby simple_test.rb at_exit do # shut down code end inherited, included, method_missing, method_added, method_removed, trace_var, set_trace_func, at_exit ...
  • 37. Hooks $ ruby simple_test.rb at_exit do # shut down code end set_trace_func proc { |event, file, line, id, binding, classname| inherited, included, method_missing, method_added, printf "%8s %s:%-2d trace_var, set_trace_func, line, id,... method_removed, %10s %8sn", event, file, at_exit classname }
  • 38. Core Extensions 'text'.blank?
  • 39. Core Extensions 'text'.blank? class Object def blank? nil? || (respond_to?(:empty?) && empty?) end end
  • 40. Core Extensions 'text'.blank? class Object def blank? nil? || (respond_to?(:empty?) && empty?) end unless method_defined?(:blank?) end
  • 41. Core Extensions 'text'.blank? module MyGem class Object module CoreExtensions module blank? def Object defnil? || (respond_to?(:empty?) && empty?) blank? end unless method_defined?(:blank?) respond_to?(:empty?) ? empty? : !self end end end end end Object.send :include, MyGem::CoreExtensions::Object
  • 42. Ruby techniques ✓Method Params ✓Makros ✓Blocks ✓Code generation ✓Instance Eval ✓Hooks ✓Method Missing ✓Core Extensions
  • 43. External DSL Ruby Tools: • Switch Cases • Regular Expressions Ruby Parser: • Treetop • RACC
  • 44. Links ★ Eloquent Ruby ★ Ruby Best Practices ★ Domain Specific Languages ★ Rebuil ★ Treetop

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