[ANN] Camping 2.0 - miniature rails for stay-at-home moms AND dads :-)

Philippe Monnet ruby at monnet-usa.com
Fri Apr 9 11:18:02 EDT 2010

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!


On 4/9/2010 8:47 AM, Magnus Holm wrote:
> require "uri";require "rack";class Object;def meta_def m,&b;(class<<self;self
> end).send:define_method,m,&b end end;module Camping;C=self;S=IO.read(__FILE__
> )rescue nil;P="<h1>Cam\ping Problem!</h1><h2>%s</h2>";U=Rack::Utils;Apps=[]
> class H<Hash;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;raise"bad route"unless 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 found"end;def r500 k,m,e;raise e;end;def r501 m
> P%"#{m.upcase} not implemented"end;def to_a;@env['rack.session']=@state;r=Rack::
> Response.new(@body, at status, at 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, at input,
> @cookies, at state, at headers, at status, at 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|r<<x}}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;class<<self;def goes m;Apps<<eval(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 is set in stone. These are basically just some of mine
> ideas - what I wish was there some years ago. But I'm neither the author nor
> the reader, so I want YOU to tell me how it really should be. It's open-source
> after all.
> Being open-source means you are free to do whatever you want. Does that
> sentence suck? That paragraph is badly phrased? That chapter doesn't belong
> there? Rewrite it! Reorganize the whole book! Just make sure to tell the rest
> why it's better.
> Being open-source ALSO means you sometimes have to give up your perfect
> chapter. Realize it wasn't as good as you thought. It's tough, but that's how
> it's going to be.
> Okay, now: Simpler routes
> The most used line is Camping apps has to be:
>      class Index<  R '/'
> So _why commited and now you can write:
>      class Index  # matches /
>      class Posts  # matches /posts
>      class PostX  # matches /post/([^/]+)
>      class UserN  # matches /user/(\d+)
> ~>  Interesting.  Is 1.5 still supported?  What should I do to upgrade my app?
> No more development will be done for 1.5, so we recommend that you upgrade
> your app to 2.0. Rack::Adapter::Camping will be removed in the next release of
> Rack, so if you're using it you should absolutely switch to Camping 2.0.
> Plese read http://camping.rubyforge.org/book/51_upgrading.html#from-15-to-20
> for upgrade notes and if you still have any problems, please let us know and
> we'll update it.
> ~>  What will we see 2.1?
> That's up to you! What would you like to see? You don't necessarily have to
> implement it yourself, just tell the rest on the mailing list and maybe
> someone else helps out.
> Sean Busbey is trying to make migrations suck less, and I want to make it even
> more Rackified. And we'll all be smashing bugs.
> ~>  Help, I'm stuck!  Where should I go?
> The mailing list: http://rubyforge.org/mailman/listinfo/camping-list
> You can also try #camping on irc.freenode.net:
> http://java.freenode.net/?channel=camping
> // Magnus Holm
> _______________________________________________
> Camping-list mailing list
> Camping-list at rubyforge.org
> http://rubyforge.org/mailman/listinfo/camping-list

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/camping-list/attachments/20100409/3f670f67/attachment.html>

More information about the Camping-list mailing list