SlideShare ist ein Scribd-Unternehmen logo
1 von 71
Downloaden Sie, um offline zu lesen
All I Really Need to Know*
I Learned by Writing My
Own Web Framework
Ben Scofield               7 November 2008
                                  Rubyconf




* about Ruby and the web
DSLs
                  DSL




                        Intimidate
                            and
                         Frighten
ïŹ‚ickr: cwsteeds
Rails
Rails




        your custom
         framework
Starter Projects
Hello World
main() {
    printf(quot;hello, worldnquot;);
}


-module(hello).

-export([hello/0]).

hello() ->
   io:format(quot;Hello World!~nquot;, []).


      PROGRAM HELLO
      PRINT*, 'Hello World!'
      END
main = putStrLn quot;Hello Worldquot;

Imports System.Console

Class HelloWorld

    Public Shared Sub Main()
        WriteLine(quot;Hello, world!quot;)
    End Sub

End Class

!greeting.
+!greeting : true <- .print(quot;Hello Worldquot;).
Applications
To-do lists
DIY Blog
Frameworks?
PHP Framework   (based on Rails)
NOT FOR PRODUCTION!
well, maybe for production
but really:

NOT FOR PRODUCTION!
Frameworks
ActionMailer
   ActionPack
  ActiveRecord
Ruby on Rails
ActiveResource
 ActiveSupport
    Railties
request => response
Sequel
   ActiveRecord
persistence layer
    DataMapper
        Og
ERB
     Liquid
    Amrita2
templating layer
     Erubis
    Markaby
      HAML
Ramaze
       Waves
   ActionPack
the middle layer
    Merb Core
     Sinatra
     Camping
ActionMailer
 Merb Helpers
   utilities
ActiveSupport
   Railties
Tools
Rack
Mack
   CGI
            Coset
  SCGI
          Camping
  LSWS
          Halcyon
Mongrel
          Maveric
WEBrick
          Sinatra
FastCGI
          Vintage
 Fuzed
           Ramaze
  Thin
            Waves
   Ebb
             Merb
mod_rack
Rack::Lint
    Rack::URLMap
   Rack::Deflater
 Rack::CommonLogger
   middlewares
Rack::ShowExceptions
   Rack::Reloader
    Rack::Static
     Rack::Cache
Rack::Request
     utility
Rack::Response
Other Layers
Sequel
   ActiveRecord
persistence layer
    DataMapper
        Og
ERB
     Liquid
    Amrita2
templating layer
     Erubis
    Markaby
      HAML
Start at the End
Vision
REST and Resources
fully-formed web applications
       built on resources
fully-formed        web applications
     built on resources
Birth of Athena
Dionysus
ask me after if you don’t get the joke
Project
Extraction   ïŹ‚ickr: 95579828@N00
class Habit < Athena::Resource
  def get
    @habit = Habit.find(@id)
  end

  # ...
end


RouteMap = {
  :get => {
     //habit/new/ => {:resource => :habit, :template => :new},
     //habit/(d+)/ => {:resource => :habit},
     //habit/(d+)/edit/ => {:resource => :habit, :template => :edit}
  },
  :put => {
     //habit/(d+)/ => {:resource => :habit}
  },
  :delete => {
     //habit/(d+)/ => {:resource => :habit}
  },
  :post => {
     //habit// => {:resource => :habit}
  }
}
Results
puts quot;Starting Athena applicationquot;

require 'active_record'
require File.expand_path(File.join('./vendor/athena/lib/athena'))
puts quot;... Framework loadedquot;

Athena.require_all_libs_relative_to('resources')
puts quot;... Resources loadedquot;

use Rack::Static, :urls => ['/images', '/stylesheets'], :root => 'public'
run Athena::Application.new
puts quot;... Application startednnquot;

puts quot;^C to stop the applicationquot;
module Athena
  class Application
    def self.root
      File.join(File.dirname(__FILE__), '..', '..', '..', '..')
    end

    def self.route_map
      @route_map ||= {
        :get     => {},
        :post    => {},
        :put     => {},
        :delete => {}
      }
      @route_map
    end

    def call(environment)
      request = Rack::Request.new(environment)
      request_method = request.params['_method'] ? # ...

      matching_route = Athena::Application.route_map # ...

      if matching_route
        resource = matching_route.last[:class].new(request, request_method)
        resource.template = matching_route.last[:template]
        return resource.output
      else
        raise Athena::BadRequest
      end
    end
  end
end
module Athena
  class Resource
    extend Athena::Persistence
    attr_accessor :template

    def self.inherited(f)
      unless f == Athena::SingletonResource
        url_name = f.name.downcase
        routing = url_name + id_pattern
        url_pattern = /^/#{routing}$/

        Athena::Application.route_map[:get][/^/#{routing}/edit$/] = # ...
        Athena::Application.route_map[:post][/^/#{url_name}$/]     = # ...
        # ...
      end
    end

    def self.default_resource
      Athena::Application.route_map[:get][/^/$/] = {:class => # ...
    end

    def self.id_pattern
      '/(d+)'
    end

    def   get;      raise   Athena::MethodNotAllowed;   end
    def   put;      raise   Athena::MethodNotAllowed;   end
    def   post;     raise   Athena::MethodNotAllowed;   end
    def   delete;   raise   Athena::MethodNotAllowed;   end

    # ...
  end
end
class Habit < Athena::Resource
  persist(ActiveRecord::Base) do
    validates_presence_of :name
  end

  def get
    @habit = Habit.find_by_id(@id) || Habit.new_record
  end

  def post
    @habit = Habit.new_record(@params['habit'])
    @habit.save!
  end

  def put
    @habit = Habit.find(@id)
    @habit.update_attributes!(@params['habit'])
  end

  def delete
    Habit.find(@id).destroy
  end
end
class Habits < Athena::SingletonResource
  default_resource

  def get
    @habits = Habit.all
  end

  def post
    @results = @params['habits'].map do |hash|
      Habit.new_record(hash).save
    end
  end

  def put
    @results = @params['habits'].map do |id, hash|
      Habit.find(id).update_attributes(hash)
    end
  end

  def delete
    Habit.find(:all,
      :conditions => ['id IN (?)', @params['habit_ids']]
    ).map(&:destroy)
  end
end
module Athena
  module Persistence
    def self.included(base)
      base.class_eval do
        @@persistence_class = nil
      end
    end

    def persist(klass, &block)
      pklass = Class.new(klass)

     pklass.class_eval(&block)
     pklass.class_eval quot;set_table_name '#{self.name}'.tableizequot;
     eval quot;Persistent#{self.name} = pklassquot;

      @@persistence_class = pklass
      @@persistence_class.establish_connection(
        YAML::load(IO.read(File.join(Athena::Application.root, # ...
      )
    end

    def new_record(*args)
      self.persistence_class.new(*args)
    end

    def persistence_class
      @@persistence_class
    end

   # ...
Lessons About the Web
HTTP status codes   http://thoughtpad.net/alan-dean/http-headers-status.gif
207
Multi-Status
207
sucks
 Multi-Status
rack::cache
http://tomayko.com/src/rack-cache/
Lessons About Ruby
module Athena
    class Application
      # ...

      def process_params(params)
        nested_pattern = /^(.+?)[(.*])/
        processed = {}
        params.each do |k, v|
          if k =~ nested_pattern
            scanned = k.scan(nested_pattern).flatten
            first = scanned.first
            last = scanned.last.sub(/]/, '')
            if last == ''
              processed[first] ||= []
              processed[first] << v
            else
              processed[first] ||= {}
              processed[first][last] = v
              processed[first] = process_params(processed[first])
            end
          else
            processed[k] = v
          end
        end
        processed.delete('_method')
        processed
      end

      # ...
    end


Form Parameters
  end
module Athena
     module Persistence
       def self.included(base)
         base.class_eval do
           @@persistence_class = nil
         end
       end

       def persist(klass, &block)
         pklass = Class.new(klass)

        pklass.class_eval(&block)
        pklass.class_eval quot;set_table_name '#{self.name}'.tableizequot;
        eval quot;Persistent#{self.name} = pklassquot;

         @@persistence_class = pklass
         @@persistence_class.establish_connection(
           YAML::load(IO.read(File.join(Athena::Application.root, # ...
         )
       end

       def new_record(*args)
         self.persistence_class.new(*args)
       end

       def persistence_class
         @@persistence_class
       end

      # ...

Dynamic class creation
Tangled classes   ïŹ‚ickr: randomurl
module Athena
     module Persistence
       # ...

       def method_missing(name, *args)
         return self.persistence_class.send(name, *args)
       rescue ActiveRecord::ActiveRecordError => e
         raise e
       rescue
         super
       end
     end
   end




Exception Propagation
this session has been a LIE
More to learn   ïŹ‚ickr: glynnis
... always   ïŹ‚ickr: mointrigue
http://github.com/bscofield/athena
           (under construction)
Thank you!
    Questions?

 Ben Scofield
 Development Director, Viget Labs

 http://www.viget.com/extend | http://www.culann.com
 ben.scofield@viget.com      | bscofield@gmail.com

Weitere Àhnliche Inhalte

Was ist angesagt?

symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
With a Mighty Hammer
With a Mighty HammerWith a Mighty Hammer
With a Mighty HammerBen Scofield
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...Codemotion
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overviewjsmith92
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Using Ruby on Rails with legacy Oracle databases
Using Ruby on Rails with legacy Oracle databasesUsing Ruby on Rails with legacy Oracle databases
Using Ruby on Rails with legacy Oracle databasesRaimonds Simanovskis
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportBen Scofield
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecordscalaconfjp
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your AppLuca Mearelli
 
Django - æŹĄăźäž€æ­© gumiStudy#3
Django - æŹĄăźäž€æ­© gumiStudy#3Django - æŹĄăźäž€æ­© gumiStudy#3
Django - æŹĄăźäž€æ­© gumiStudy#3makoto tsuyuki
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019BalĂĄzs TatĂĄr
 
More tips n tricks
More tips n tricksMore tips n tricks
More tips n tricksbcoca
 
Ansible leveraging 2.0
Ansible leveraging 2.0Ansible leveraging 2.0
Ansible leveraging 2.0bcoca
 
How to develop modern web application framework
How to develop modern web application frameworkHow to develop modern web application framework
How to develop modern web application frameworktechmemo
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019BalĂĄzs TatĂĄr
 

Was ist angesagt? (20)

Lithium Best
Lithium Best Lithium Best
Lithium Best
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
With a Mighty Hammer
With a Mighty HammerWith a Mighty Hammer
With a Mighty Hammer
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...And now you have two problems. Ruby regular expressions for fun and profit by...
And now you have two problems. Ruby regular expressions for fun and profit by...
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Using Ruby on Rails with legacy Oracle databases
Using Ruby on Rails with legacy Oracle databasesUsing Ruby on Rails with legacy Oracle databases
Using Ruby on Rails with legacy Oracle databases
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack Support
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecord
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
Django - æŹĄăźäž€æ­© gumiStudy#3
Django - æŹĄăźäž€æ­© gumiStudy#3Django - æŹĄăźäž€æ­© gumiStudy#3
Django - æŹĄăźäž€æ­© gumiStudy#3
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019
 
More tips n tricks
More tips n tricksMore tips n tricks
More tips n tricks
 
Ansible leveraging 2.0
Ansible leveraging 2.0Ansible leveraging 2.0
Ansible leveraging 2.0
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
How to develop modern web application framework
How to develop modern web application frameworkHow to develop modern web application framework
How to develop modern web application framework
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019
 

Ähnlich wie All I Need to Know I Learned by Writing My Own Web Framework

Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amfrailsconf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With RubyamfTony Hillerson
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
DataMapper
DataMapperDataMapper
DataMapperYehuda Katz
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous MerbMatt Todd
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slidesharetomcopeland
 
é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„
é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„
é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„Hisateru Tanaka
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers StealBen Scofield
 
Ruby Isn't Just About Rails
Ruby Isn't Just About RailsRuby Isn't Just About Rails
Ruby Isn't Just About RailsAdam Wiggins
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2rubyMarc Chung
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3Nate Abele
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesSiarhei Barysiuk
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Express Presentation
Express PresentationExpress Presentation
Express Presentationaaronheckmann
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 

Ähnlich wie All I Need to Know I Learned by Writing My Own Web Framework (20)

Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
DataMapper
DataMapperDataMapper
DataMapper
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous Merb
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Railsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshareRailsconf2011 deployment tips_for_slideshare
Railsconf2011 deployment tips_for_slideshare
 
é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„
é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„
é–ąè„żPHPć‹‰ćŒ·äŒš php5.4ă€ăŸăżăă„
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
Ruby Isn't Just About Rails
Ruby Isn't Just About RailsRuby Isn't Just About Rails
Ruby Isn't Just About Rails
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 

Mehr von Ben Scofield

How to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 StepsHow to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 StepsBen Scofield
 
Building Cloud Castles - LRUG
Building Cloud Castles - LRUGBuilding Cloud Castles - LRUG
Building Cloud Castles - LRUGBen Scofield
 
Thinking Small
Thinking SmallThinking Small
Thinking SmallBen Scofield
 
Open Source: A Call to Arms
Open Source: A Call to ArmsOpen Source: A Call to Arms
Open Source: A Call to ArmsBen Scofield
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud CastlesBen Scofield
 
Intentionality: Choice and Mastery
Intentionality: Choice and MasteryIntentionality: Choice and Mastery
Intentionality: Choice and MasteryBen Scofield
 
Mastery or Mediocrity
Mastery or MediocrityMastery or Mediocrity
Mastery or MediocrityBen Scofield
 
Mind Control - DevNation Atlanta
Mind Control - DevNation AtlantaMind Control - DevNation Atlanta
Mind Control - DevNation AtlantaBen Scofield
 
Understanding Mastery
Understanding MasteryUnderstanding Mastery
Understanding MasteryBen Scofield
 
Mind Control: Psychology for the Web
Mind Control: Psychology for the WebMind Control: Psychology for the Web
Mind Control: Psychology for the WebBen Scofield
 
The State of NoSQL
The State of NoSQLThe State of NoSQL
The State of NoSQLBen Scofield
 
NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010Ben Scofield
 
NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)Ben Scofield
 
Charlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is HardCharlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is HardBen Scofield
 
The Future of Data
The Future of DataThe Future of Data
The Future of DataBen Scofield
 
WindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is HardWindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is HardBen Scofield
 
"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative Databases"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative DatabasesBen Scofield
 
Mind Control on the Web
Mind Control on the WebMind Control on the Web
Mind Control on the WebBen Scofield
 
How the Geeks Inherited the Earth
How the Geeks Inherited the EarthHow the Geeks Inherited the Earth
How the Geeks Inherited the EarthBen Scofield
 

Mehr von Ben Scofield (20)

How to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 StepsHow to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 Steps
 
Building Cloud Castles - LRUG
Building Cloud Castles - LRUGBuilding Cloud Castles - LRUG
Building Cloud Castles - LRUG
 
Thinking Small
Thinking SmallThinking Small
Thinking Small
 
Open Source: A Call to Arms
Open Source: A Call to ArmsOpen Source: A Call to Arms
Open Source: A Call to Arms
 
Ship It
Ship ItShip It
Ship It
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud Castles
 
Intentionality: Choice and Mastery
Intentionality: Choice and MasteryIntentionality: Choice and Mastery
Intentionality: Choice and Mastery
 
Mastery or Mediocrity
Mastery or MediocrityMastery or Mediocrity
Mastery or Mediocrity
 
Mind Control - DevNation Atlanta
Mind Control - DevNation AtlantaMind Control - DevNation Atlanta
Mind Control - DevNation Atlanta
 
Understanding Mastery
Understanding MasteryUnderstanding Mastery
Understanding Mastery
 
Mind Control: Psychology for the Web
Mind Control: Psychology for the WebMind Control: Psychology for the Web
Mind Control: Psychology for the Web
 
The State of NoSQL
The State of NoSQLThe State of NoSQL
The State of NoSQL
 
NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010
 
NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)
 
Charlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is HardCharlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is Hard
 
The Future of Data
The Future of DataThe Future of Data
The Future of Data
 
WindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is HardWindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is Hard
 
"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative Databases"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative Databases
 
Mind Control on the Web
Mind Control on the WebMind Control on the Web
Mind Control on the Web
 
How the Geeks Inherited the Earth
How the Geeks Inherited the EarthHow the Geeks Inherited the Earth
How the Geeks Inherited the Earth
 

KĂŒrzlich hochgeladen

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
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 slidevu2urc
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
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 AutomationSafe Software
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
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 Processorsdebabhi2
 
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 Scriptwesley chun
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
[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.pdfhans926745
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
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 2024The Digital Insurer
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 

KĂŒrzlich hochgeladen (20)

Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
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
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
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
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
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
 
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
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
[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
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
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
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 

All I Need to Know I Learned by Writing My Own Web Framework

  • 1. All I Really Need to Know* I Learned by Writing My Own Web Framework Ben Scofield 7 November 2008 Rubyconf * about Ruby and the web
  • 2.
  • 3.
  • 4. DSLs DSL Intimidate and Frighten ïŹ‚ickr: cwsteeds
  • 5.
  • 7. Rails your custom framework
  • 10. main() { printf(quot;hello, worldnquot;); } -module(hello). -export([hello/0]). hello() -> io:format(quot;Hello World!~nquot;, []). PROGRAM HELLO PRINT*, 'Hello World!' END
  • 11. main = putStrLn quot;Hello Worldquot; Imports System.Console Class HelloWorld Public Shared Sub Main() WriteLine(quot;Hello, world!quot;) End Sub End Class !greeting. +!greeting : true <- .print(quot;Hello Worldquot;).
  • 16. PHP Framework (based on Rails)
  • 18. well, maybe for production
  • 19. but really: NOT FOR PRODUCTION!
  • 21. ActionMailer ActionPack ActiveRecord Ruby on Rails ActiveResource ActiveSupport Railties
  • 23. Sequel ActiveRecord persistence layer DataMapper Og
  • 24. ERB Liquid Amrita2 templating layer Erubis Markaby HAML
  • 25. Ramaze Waves ActionPack the middle layer Merb Core Sinatra Camping
  • 26. ActionMailer Merb Helpers utilities ActiveSupport Railties
  • 27. Tools
  • 28. Rack
  • 29. Mack CGI Coset SCGI Camping LSWS Halcyon Mongrel Maveric WEBrick Sinatra FastCGI Vintage Fuzed Ramaze Thin Waves Ebb Merb
  • 31. Rack::Lint Rack::URLMap Rack::Deflater Rack::CommonLogger middlewares Rack::ShowExceptions Rack::Reloader Rack::Static Rack::Cache
  • 32. Rack::Request utility Rack::Response
  • 34. Sequel ActiveRecord persistence layer DataMapper Og
  • 35. ERB Liquid Amrita2 templating layer Erubis Markaby HAML
  • 39. fully-formed web applications built on resources
  • 40. fully-formed web applications built on resources
  • 41.
  • 43. Dionysus ask me after if you don’t get the joke
  • 45. Extraction ïŹ‚ickr: 95579828@N00
  • 46.
  • 47. class Habit < Athena::Resource def get @habit = Habit.find(@id) end # ... end RouteMap = { :get => { //habit/new/ => {:resource => :habit, :template => :new}, //habit/(d+)/ => {:resource => :habit}, //habit/(d+)/edit/ => {:resource => :habit, :template => :edit} }, :put => { //habit/(d+)/ => {:resource => :habit} }, :delete => { //habit/(d+)/ => {:resource => :habit} }, :post => { //habit// => {:resource => :habit} } }
  • 49.
  • 50.
  • 51. puts quot;Starting Athena applicationquot; require 'active_record' require File.expand_path(File.join('./vendor/athena/lib/athena')) puts quot;... Framework loadedquot; Athena.require_all_libs_relative_to('resources') puts quot;... Resources loadedquot; use Rack::Static, :urls => ['/images', '/stylesheets'], :root => 'public' run Athena::Application.new puts quot;... Application startednnquot; puts quot;^C to stop the applicationquot;
  • 52. module Athena class Application def self.root File.join(File.dirname(__FILE__), '..', '..', '..', '..') end def self.route_map @route_map ||= { :get => {}, :post => {}, :put => {}, :delete => {} } @route_map end def call(environment) request = Rack::Request.new(environment) request_method = request.params['_method'] ? # ... matching_route = Athena::Application.route_map # ... if matching_route resource = matching_route.last[:class].new(request, request_method) resource.template = matching_route.last[:template] return resource.output else raise Athena::BadRequest end end end end
  • 53. module Athena class Resource extend Athena::Persistence attr_accessor :template def self.inherited(f) unless f == Athena::SingletonResource url_name = f.name.downcase routing = url_name + id_pattern url_pattern = /^/#{routing}$/ Athena::Application.route_map[:get][/^/#{routing}/edit$/] = # ... Athena::Application.route_map[:post][/^/#{url_name}$/] = # ... # ... end end def self.default_resource Athena::Application.route_map[:get][/^/$/] = {:class => # ... end def self.id_pattern '/(d+)' end def get; raise Athena::MethodNotAllowed; end def put; raise Athena::MethodNotAllowed; end def post; raise Athena::MethodNotAllowed; end def delete; raise Athena::MethodNotAllowed; end # ... end end
  • 54. class Habit < Athena::Resource persist(ActiveRecord::Base) do validates_presence_of :name end def get @habit = Habit.find_by_id(@id) || Habit.new_record end def post @habit = Habit.new_record(@params['habit']) @habit.save! end def put @habit = Habit.find(@id) @habit.update_attributes!(@params['habit']) end def delete Habit.find(@id).destroy end end
  • 55. class Habits < Athena::SingletonResource default_resource def get @habits = Habit.all end def post @results = @params['habits'].map do |hash| Habit.new_record(hash).save end end def put @results = @params['habits'].map do |id, hash| Habit.find(id).update_attributes(hash) end end def delete Habit.find(:all, :conditions => ['id IN (?)', @params['habit_ids']] ).map(&:destroy) end end
  • 56. module Athena module Persistence def self.included(base) base.class_eval do @@persistence_class = nil end end def persist(klass, &block) pklass = Class.new(klass) pklass.class_eval(&block) pklass.class_eval quot;set_table_name '#{self.name}'.tableizequot; eval quot;Persistent#{self.name} = pklassquot; @@persistence_class = pklass @@persistence_class.establish_connection( YAML::load(IO.read(File.join(Athena::Application.root, # ... ) end def new_record(*args) self.persistence_class.new(*args) end def persistence_class @@persistence_class end # ...
  • 58. HTTP status codes http://thoughtpad.net/alan-dean/http-headers-status.gif
  • 63. module Athena class Application # ... def process_params(params) nested_pattern = /^(.+?)[(.*])/ processed = {} params.each do |k, v| if k =~ nested_pattern scanned = k.scan(nested_pattern).flatten first = scanned.first last = scanned.last.sub(/]/, '') if last == '' processed[first] ||= [] processed[first] << v else processed[first] ||= {} processed[first][last] = v processed[first] = process_params(processed[first]) end else processed[k] = v end end processed.delete('_method') processed end # ... end Form Parameters end
  • 64. module Athena module Persistence def self.included(base) base.class_eval do @@persistence_class = nil end end def persist(klass, &block) pklass = Class.new(klass) pklass.class_eval(&block) pklass.class_eval quot;set_table_name '#{self.name}'.tableizequot; eval quot;Persistent#{self.name} = pklassquot; @@persistence_class = pklass @@persistence_class.establish_connection( YAML::load(IO.read(File.join(Athena::Application.root, # ... ) end def new_record(*args) self.persistence_class.new(*args) end def persistence_class @@persistence_class end # ... Dynamic class creation
  • 65. Tangled classes ïŹ‚ickr: randomurl
  • 66. module Athena module Persistence # ... def method_missing(name, *args) return self.persistence_class.send(name, *args) rescue ActiveRecord::ActiveRecordError => e raise e rescue super end end end Exception Propagation
  • 67. this session has been a LIE
  • 68. More to learn ïŹ‚ickr: glynnis
  • 69. ... always ïŹ‚ickr: mointrigue
  • 70. http://github.com/bscofield/athena (under construction)
  • 71. Thank you! Questions? Ben Scofield Development Director, Viget Labs http://www.viget.com/extend | http://www.culann.com ben.scofield@viget.com | bscofield@gmail.com