Magnus Holm
2010-Apr-09 14:47 UTC
[ANN] Camping 2.0 - minature rails for stay-at-home moms
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
Philippe Monnet
2010-Apr-09 15:18 UTC
[ANN] Camping 2.0 - miniature rails for stay-at-home moms AND dads :-)
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;(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>
Good job. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/camping-list/attachments/20100409/37bfe300/attachment.html>
David Susco
2010-Apr-09 17:55 UTC
[ANN] Camping 2.0 - minature rails for stay-at-home moms
Indeed, congratulations everyone. And thank you to all those who made the 199 commits. On Fri, Apr 9, 2010 at 12:14 PM, John Beppu <john.beppu at gmail.com> wrote:> Good job. > > _______________________________________________ > Camping-list mailing list > Camping-list at rubyforge.org > http://rubyforge.org/mailman/listinfo/camping-list >-- Dave