Faking Sinatra with Rack and Metaprogramming

by Charles Max Wood on September 24, 2010

Sinatra has a really nice DSL. You can fake the basics of the DSL with some simple Rack middleware created by metaprogramming.

If you like the screencasts, please give $5 to help me get to RubyConf Click here to lend your support to: Send Charles to RubyConf and make a donation at www.pledgie.com !

Download (64.2 MB)
Download iPhone & iPod (35.6 MB)

  • Pingback: Ruby: simulare sinatra con rack e un pizzico di metaprogrammazione « Il metaprogrammatore

  • Pingback: Особое программирование » Post Topic » Building your own Fake Sinatra with Rack and Metaprogramming

  • harisamin

    Really good stuff. Quick comment on the audio for the screencast, the audio is in mono for the whole screencast (except for the intro and the outro) :)

    • http://teachmetocode.com Charles Max Wood

      Yeah, someone else pointed that out. I’m attempting to balance it out so it comes in on both the left and right channels.

  • harisamin

    Really good stuff. Quick comment on the audio for the screencast, the audio is in mono for the whole screencast (except for the intro and the outro) :)

    • http://teachmetocode.com Charles Max Wood

      Yeah, someone else pointed that out. I’m attempting to balance it out so it comes in on both the left and right channels.

  • Anonymous

    Hi Charles, thanks for the screencast. Could you explain a little bit more what happens when you do “use middleware” ?

    Why do you prefer the middleware.send(:define_method, ‘call’) {} syntax as oppsed to
    def middleware.call()
    end ?

    • http://teachmetocode.com Charles Max Wood

      If you watch http://teachmetocode.com/screencasts/rack-basics/ you’ll see me
      set up some middleware there with an explicitly defined class. In this
      example, we’re doing the same thing except we’re defining the class through
      meta-programming.

      So, instead of calling ‘use MiddlewareClass’, we’re calling ‘use middleware’
      where middleware references our anonymous (or unnamed) class.

    • http://teachmetocode.com Charles Max Wood

      As for your other question. ‘call’ needs to be an instance method, not a class method. I could have done that for middleware.path= and middleware.path as those were assigning class variables and reference the class, not the instance.calling ‘use middleware’ actually instantiates a new object with ‘middleware.new(app)’ and then delegates to call on that instance when moving up or down the middleware stack.

      • Anonymous

        ah, I didn’t realize that Class.new wasn’t returning an instance (duh). Thanks :)

  • Anonymous

    Hi Charles, thanks for the screencast. Could you explain a little bit more what happens when you do “use middleware” ?

    Why do you prefer the middleware.send(:define_method, ‘call’) {} syntax as oppsed to
    def middleware.call()
    end ?

    • http://teachmetocode.com Charles Max Wood

      If you watch http://teachmetocode.com/screencasts/rack-basics/ you’ll see me
      set up some middleware there with an explicitly defined class. In this
      example, we’re doing the same thing except we’re defining the class through
      meta-programming.

      So, instead of calling ‘use MiddlewareClass’, we’re calling ‘use middleware’
      where middleware references our anonymous (or unnamed) class.

    • http://teachmetocode.com Charles Max Wood

      As for your other question. ‘call’ needs to be an instance method, not a class method. I could have done that for middleware.path= and middleware.path as those were assigning class variables and reference the class, not the instance.calling ‘use middleware’ actually instantiates a new object with ‘middleware.new(app)’ and then delegates to call on that instance when moving up or down the middleware stack.

      • Anonymous

        ah, I didn’t realize that Class.new wasn’t returning an instance (duh). Thanks :)

  • http://twitter.com/rubiii Daniel Harrington

    hey charles. good screencast. i thought this link to the textmate shortcuts for changing the indent level might be interesting for you: http://manual.macromates.com/en/working_with_text#increase_decrease_indent_level

    • http://teachmetocode.com Charles Max Wood

      Thanks for the tip. I know some of this. I was being lazy. :P

      • Anonymous

        np. by letting the editor do what it does best, you (and me) can be even lazier ;)

  • Daniel Harrington

    hey charles. good screencast. i thought this link to the textmate shortcuts for changing the indent level might be interesting for you: http://manual.macromates.com/en/working_with_text#increase_decrease_indent_level

    • http://teachmetocode.com Charles Max Wood

      Thanks for the tip. I know some of this. I was being lazy. :P

      • Daniel Harrington

        np. by letting the editor do what it does best, you (and me) can be even lazier ;)

  • http://remi.org remi

    I have a series of popular screencasts test-driving the creation of a Sinatra clone (using Rack and metaprogramming) that viewers of this screencast would likely be very interested in!

    http://remi.org/2009/03/30/building-your-own-sinatra-clone-part-1

    • Joon

      I’m a big fan of Remi’s screencasts although he hasn’t release anything lately… :P

      In any case, please purchase his screencast.

  • http://remi.org remi

    I have a series of popular screencasts test-driving the creation of a Sinatra clone (using Rack and metaprogramming) that viewers of this screencast would likely be very interested in!

    http://remi.org/2009/03/30/building-your-own-sinatra-clone-part-1

    • Joon

      I’m a big fan of Remi’s screencasts although he hasn’t release anything lately… :P

      In any case, please purchase his screencast.

  • http://twitter.com/bmabey Ben Mabey

    FYI, Class.new can take a block that would remove the need for the separate define_method and instance_eval calls:

    i.e.

    anon_class = Class.new do
    def self.im_a_class_method
    “hello”
    end
    def im_a_instance_method
    “cheers”
    end
    end

    • http://teachmetocode.com Charles Max Wood

      Great tip! Thanks, Ben.

    • Joon

      But instance_eval is so cool… ;)

  • http://twitter.com/bmabey Ben Mabey

    FYI, Class.new can take a block that would remove the need for the separate define_method and instance_eval calls:

    i.e.

    anon_class = Class.new do
    def self.im_a_class_method
    “hello”
    end
    def im_a_instance_method
    “cheers”
    end
    end

    • http://teachmetocode.com Charles Max Wood

      Great tip! Thanks, Ben.

    • Joon

      But instance_eval is so cool… ;)

  • Stefanos

    You don’t have to pass ‘path’ and ‘request_method’ as class variables. Block has the scope of the context that it’s created so these two ‘general_request_method’ parameters are visible to ‘call’ body.
    Thanks for sharing

  • Stefanos

    You don’t have to pass ‘path’ and ‘request_method’ as class variables. Block has the scope of the context that it’s created so these two ‘general_request_method’ parameters are visible to ‘call’ body.
    Thanks for sharing

Previous post:

Next post: