Yippee! [cling cheers cling skål* *cling santé cling]
Thanks Magnus for all the hard work bringing Camping to 2.0.
_why must be proud!
Philippe
On 4/9/2010 8:47 AM, Magnus Holm wrote:
require uri;require rack;class Object;def meta_def m,b;(classself;self
end).send:define_method,m,b end end;module Camping;C=self;S=IO.read(__FILE__
)rescue nil;P=h1Cam\ping Problem!/h1h2%s/h2;U=Rack::Utils;Apps=[]
class HHash;def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.
to_s]:super end;undef id,type if ??==63;end;module Helpers;def R c,*g;p,h=
/\(.+?\)/,g.grep(Hash);g-=h;raisebad routeunless u=c.urls.find{|x|break x if
x.scan(p).size==g.size/^#{x}\/?$/=~(x=g.inject(x){|x,a|x.sub p,U.escape((a[
a.class.primary_key]rescue a))})};h.any?? u+?+U.build_query(h[0]):u end;def
/ p;p[0]==?/?...@root + p : p end;def URL c='/',*a;c=R(c, *a) if c.respond_to?(
:urls);c=self/c;c...@request.url[/.{8,}?(?=\/)/]+c if c[0]==?/;URI c end end
module Base;attr_accessor:env,:request,:root,:input,:cookies,:state,:status,
:headers,:body;def render v,*a,b;mab(/^_/!~v.to_s){send(v,*a,b)} end;def
mab l=nil,b;m=Mab.new({},self);s=m.capture(b);s=m.capture{layout{s}} if l
m.respond_to?(:layout);s end;def r s,b,h={};b,h=h,b if Hash===b;@status=s;
@headers.merge!(h);@body=b;end;def redirect *a;r 302,'','Location'=URL(*a).
to_s;end;def r404 p;P%#{p} not foundend;def r500 k,m,e;raise e;end;def r501 m
P%#{m.upcase} not implementedend;def
to_a;@env['rack.session']...@state;r=Rack::
Response.new(@body,@status,@headers);@cookies.each{|k,v|next if @old_cookies[
k]==v;v={:value=v,:path=self//} if String===v;r.set_cookie(k,v)};r.to_a;end
def initialize(env,m) r...@request=rack::Request.new(@env=env);@root,@input,
@cookies,@state,@headers,@status,@method=r.script_name.sub(/\/$/,''),n(r.params
),h...@old_cookies = r.cookies],H[r.session],{},m=~/r(\d+)/?$1.to_i: 200,m
end;def
n h;Hash===h ?h.inject(H[]){|m,(k,v)|m[k]=n(v);m}: h end;def service *a;r=catch(
:halt){send(@method,*a)};@body||=r;self;end;end;module Controllers;@r=[];class
self;def r;@r end;def R
*u;r...@r;Class.new{meta_def(:urls){u};meta_def(:inherited
){|x|rx}}end;def D p,m;p='/'if !p||!p[0];r.map{|k|k.urls.map{|x|return(k.
instance_method(m)rescue nil)?[k,m,*$~[1..-1]]:[I,'r501',m]if p=~/^#{x}\/?$/}}
[I,'r404',p] end;N=H.new{|_,x|x.downcase}.merge! N='(\d+)',X='([^/]+)',
Index='';def M;def M;end;constants.map{|c|k=const_get(c);k.send:include,C,
Base,Helpers,Models;@r=[k]+r if r-[k]==r;k.meta_def(:urls){ [ /#{c.scan(
/.[^A-Z]*/).map(N.method(:[]))*'/'}]}if !k.respond_to?:urls}end end;I=R()
end;X=Controllers;classself;def goes m;Appseval(S.gsub(/Camping/,m.to_s),
TOPLEVEL_BINDING) end;def call e;X.M;p=e['PATH_INFO']=U.unescape(e['PATH_INFO'])
k,m,*a=X.D p,e['REQUEST_METHOD'].downcase;k.new(e,m).service(*a).to_a;rescue
r500(:I,k,m,$!,:env=e).to_a;end;def method_missing m,c,*a;X.M;h=Hash===a[-1]?
a.pop: {};e=H[Rack::MockRequest.env_for('',h.delete(:env)||{})];k=X.const_get(c
).new(e,m.to_s);h.each{|i,v|k.send#{i}=,v};k.service(*a);end;def use*a,b;m=a.
shift.new(method(:call),*a,b);meta_def(:call){|e|m.call(e)}end end;module Views
include X,Helpers end;module Models;autoload:Base,
'camping/ar';end;autoload:Mab,'camping/mab';C end
---
Wow. After 199 commits, 11875 lines of diff and 1284 days, it's an honor to
present a new, freshly baked version of the microframework; now built upon
Rack and weighing only 3072 tiny bytes. (That's exactly 3k!)
gem install camping
Home: http://whywentcamping.com/ (currently only redirects to the docs)
Docs: http://camping.rubyforge.org/
Code/wiki/bugs: http://github.com/camping/camping
Mailing list: http://rubyforge.org/mailman/listinfo/camping-list
~ Wait a second, you're not _why!
Well, no. He went camping, so we decided to commandeer and steer this ship
back on course. I'm merely a scoutmaster; it's the community who's in charge.
Want to have an impact on Camping? Just join the mailing list, and your voice
will be heard.
~ What's new?
Let's start with Rack.
Every Camping app is now a Rack app. This is your config.ru:
require 'blog'
run Blog
If your app requires a middleware, you can inject it inside your app:
module Blog
use Rack::MethodOverride
end
Sessions are now simply a wrapper around env['rack.session'], so it's easy as
pie to `use Other::SessionBackends`.
Ironicly, the methods Rack stole from Camping are no longer in Camping, since
it's shorter to simply call those in Rack :-)
Next up: The book - http://camping.rubyforge.org/book.html
Not really a book, but it should get you started with Camping pretty quick. It's
far from complete, but in the end you should know plenty about both Camping,
Rack, HTTP and other frameworks. Web development is a huge field in Ruby and can
be a little confusing for newcomers. This book should give you a gentle
introduction together with pointers to where you could go for more.
This book isn't written yet. Let me repeat that: This book isn't
written yet. Nothing