Faking Sinatra with Rack and Metaprogramming

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)

{ 30 comments… read them below or add one }

harisamin September 28, 2010 at 2:20 pm

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) :)

Reply

Charles Max Wood September 28, 2010 at 2:40 pm

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

Reply

harisamin September 28, 2010 at 2:20 pm

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) :)

Reply

Charles Max Wood September 28, 2010 at 2:40 pm

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

Reply

Anonymous September 28, 2010 at 3:34 pm

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 ?

Reply

Charles Max Wood September 28, 2010 at 4:47 pm

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.

Reply

Charles Max Wood September 28, 2010 at 4:50 pm

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.

Reply

Anonymous September 28, 2010 at 5:08 pm

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

Reply

Anonymous September 28, 2010 at 3:34 pm

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 ?

Reply

Charles Max Wood September 28, 2010 at 4:47 pm

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.

Reply

Charles Max Wood September 28, 2010 at 4:50 pm

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.

Reply

Anonymous September 28, 2010 at 5:08 pm

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

Reply

Daniel Harrington September 28, 2010 at 5:53 pm

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

Reply

Charles Max Wood September 30, 2010 at 3:46 pm

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

Reply

Anonymous October 18, 2010 at 8:32 pm

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

Reply

Daniel Harrington September 28, 2010 at 5:53 pm

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

Reply

Charles Max Wood September 30, 2010 at 3:46 pm

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

Reply

Daniel Harrington October 18, 2010 at 8:32 pm

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

Reply

remi September 29, 2010 at 12:12 pm

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

Reply

Joon October 5, 2010 at 1:22 am

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

In any case, please purchase his screencast.

Reply

remi September 29, 2010 at 12:12 pm

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

Reply

Joon October 5, 2010 at 1:22 am

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

In any case, please purchase his screencast.

Reply

Ben Mabey September 30, 2010 at 3:38 pm

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

Reply

Charles Max Wood September 30, 2010 at 3:45 pm

Great tip! Thanks, Ben.

Reply

Joon October 5, 2010 at 1:23 am

But instance_eval is so cool… 😉

Reply

Ben Mabey September 30, 2010 at 3:38 pm

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

Reply

Charles Max Wood September 30, 2010 at 3:45 pm

Great tip! Thanks, Ben.

Reply

Joon October 5, 2010 at 1:23 am

But instance_eval is so cool… 😉

Reply

Stefanos October 12, 2010 at 12:13 am

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

Reply

Stefanos October 12, 2010 at 12:13 am

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

Reply

Leave a Comment

{ 2 trackbacks }