Skip to content

Commit

Permalink
* lib/camping.rb: experimenting with Camping.method_missing as an an…
Browse files Browse the repository at this point in the history
…swer to #33.

   (stuff like Tepee.get(:Index) or Blog.post(:Delete, id) and so on.)
  • Loading branch information
_why committed Jul 6, 2006
1 parent c1f6e46 commit 1109984
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 21 deletions.
18 changes: 17 additions & 1 deletion lib/camping-unabridged.rb
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,12 @@ def qs_parse(qs, d = '&;')
# Parses a string of cookies from the <tt>Cookie</tt> header.
def kp(s); c = qs_parse(s, ';,'); end
def method_missing(m, c, *a)
k = X.const_get(c)
k.send :include, C, Base, Models
k.allocate.method(m, *a)
end
# Fields a request through Camping. For traditional CGI applications, the method can be
# executed without arguments.
#
Expand Down Expand Up @@ -626,11 +632,21 @@ def kp(s); c = qs_parse(s, ';,'); end
#
def run(r=$stdin,e=ENV)
k, a = Controllers.D un("/#{e['PATH_INFO']}".gsub(%r!/+!,'/'))
k.send :include, C, Base, Models
i k
k.new(r,e,(m=e['REQUEST_METHOD']||"GET")).service(*a)
rescue Exception => x
Controllers::ServerError.new(r,e,'get').service(k,m,x)
end
def method_missing(m, c, *a)
k = Controllers.const_get(c)
i k
k.new(nil,H['HTTP_HOST','','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s).service(*a)
end
def i k
k.send(:include, C, Base, Models) if !(k<C)
end
end
# Models is an empty Ruby module for housing model classes derived
Expand Down
43 changes: 23 additions & 20 deletions lib/camping.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
%w[active_record markaby metaid tempfile uri].each{|l|require l}
module Camping;Apps=[];C=self;S=IO.read(__FILE__).sub(/S=I.+$/,'')
P="Cam\ping Problem!"
module Helpers;def R c,*args;p=/\(.+?\)/;args.inject(c.urls.find{|x|x.scan(p).
size==args.size}.dup){|str,a|str.sub(p,C.escape((a.__send__(a.class.primary_key
)rescue a)))} end;def URL c='/',*a;c=R(c,*a)if c.respond_to?:urls;c=self/c;c=
"//"+@env.HTTP_HOST+c if c[/^\//];URI(c) end;def / p;p[/^\//]?@root+p : p end
def errors_for o;ul.errors{o.errors.each_full{|x|li x}}if o.errors.any? end end
module Base;include Helpers;attr_accessor :input,:cookies,:env,:headers,:body,
:status,:root;def method_missing m,*a,&b;s=m==:render ? markaview(*a,&b):eval(
"markaby.#{m}(*a,&b)");s=markaview(:layout){s} if Views.method_defined?:layout
s end;def r s,b,h={};@status=s;@headers.merge!(h);@body=b end;def
redirect *a;r 302,'','Location'=>URL(*a) end;def initialize r,e,m;e=H[e.to_hash]
@status,@method,@env,@headers,@root=200,m.downcase,e,{'Content-Type'=>"text/htm\
l"},e.SCRIPT_NAME.sub(/\/$/,'');@k=C.kp e.HTTP_COOKIE;q=C.qs_parse e.QUERY_STRING
@in=r;if %r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n.match e.CONTENT_TYPE;b=
P="Cam\ping Problem!";module Helpers;def R c,*args;p=/\(.+?\)/;args.inject(c.
urls.find{|x|x.scan(p).size==args.size}.dup){|str,a|str.sub(p,C.escape((a.
__send__(a.class.primary_key)rescue a)))}end;def URL c='/',*a;c=R(c,*a)if c.
respond_to?:urls;c=self/c;c="//"+@env.HTTP_HOST+c if c[/^\//];URI(c) end;def / p
p[/^\//]?@root+p : p end;def errors_for o;ul.errors{o.errors.each_full{|x|li x}
}if o.errors.any?end end;module Base;include Helpers;attr_accessor :input,
:cookies,:env,:headers,:body,:status,:root;def method_missing m,*a,&b
s=m==:render ? markaview(*a,&b):eval("markaby.#{m}(*a,&b)");s=markaview(:layout
){s} if Views.method_defined?:layout;s end;def r s,b,h={};@status=s;@headers.
merge! h;@body=b end;def redirect *a;r 302,'','Location'=>URL(*a)end;def
initialize r,e,m;e=H[e.to_hash];@status,@method,@env,@headers,@root=200,m.
downcase,e,{'Content-Type'=>"text/html"},e.SCRIPT_NAME.sub(/\/$/,'')
@k=C.kp e.HTTP_COOKIE;q=C.qs_parse e.QUERY_STRING;@in=r
if %r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n.match e.CONTENT_TYPE;b=
/(?:\r?\n|\A)#{Regexp::quote("--#$1")}(?:--)?\r$/;until @in.eof?;fh=H[];for l in
@in;case l;when "\r\n":break;when /^Content-Disposition: form-data;/:fh.u H[*$'.
scan(/(?:\s(\w+)="([^"]+)")/).flatten];when /^Content-Type: (.+?)(\r$|\Z)/m;fh[
Expand All @@ -27,23 +27,26 @@ module Base;include Helpers;attr_accessor :input,:cookies,:env,:headers,:body,
|k,v|[*v].map{|x|"#{k}: #{x}"}}*"\r\n"}\r\n\r\n#{@body}" end;def markaby;Mab.new(
instance_variables.map{|iv|[iv[1..-1],instance_variable_get(iv)]}) end;def
markaview m,*a,&b;h=markaby;h.send m,*a,&b;h.to_s end end
module Controllers;class NotFound;def get p;r(404,div{h1 P
X=module Controllers;class NotFound;def get p;r(404,div{h1 P
h2 p+" not found"}) end end;class ServerError;include Base;def get k,m,e;r(500,
Mab.new{h1 P;h2 "#{k}.#{m}";h3 "#{e.class} #{e.message}:";ul{
e.backtrace.each{|bt|li(bt)}}}.to_s)end end;class<<self;def R *urls;Class.new{
meta_def(:urls){urls}}end;def D path;constants.inject(nil){|d,c|k=const_get c
k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to? :urls;d||([k,$~[1..-1]]if k.urls.find{
|x|path=~/^#{x}\/?$/})}||[NotFound,[path]] end end end;class<<self;def goes m
|x|path=~/^#{x}\/?$/})}||[NotFound,[path]] end end;self;end;class<<self;def goes m
eval(S.gsub(/Camping/,m.to_s),TOPLEVEL_BINDING);Apps<<const_get(m);end
def escape(s)s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr(' ','+')end
def un(s)s.tr('+',' ').gsub(/%([\da-f]{2})/in){[$1].pack('H*')} end
def qs_parse q,d='&;';m=proc{|_,o,n|o.u(n,&m)rescue([*o
]<<n)};q.to_s.split(/[#{d}] */n).inject(H[]){|h,p|k,v=un(p).split('=',2)
h.u k.split(/[\]\[]+/).reverse.inject(v){|x,i|H[i,x]},&m}end;def kp(s);c=
qs_parse(s,';,')end;def run r=$stdin,e=ENV;k,a=Controllers.D un("/#{e['PATH_INFO']
}".gsub(/\/+/,'/'));k.send:include,C,Base,Models;k.new(r,e,(m=e['REQUEST_METHOD'
]||"GET")).service *a;rescue Exception=>x;Controllers::ServerError.new(r,e,'get').service(
k,m,x)end end;module Views;include Controllers,Helpers end;module Models;A=
qs_parse(s,';,')end;def run r=$stdin,e=ENV;k,a=X.D un("/#{e['PATH_INFO']
}".gsub(/\/+/,'/'));i k;k.new(r,e,(m=e['REQUEST_METHOD'
]||"GET")).service *a;rescue Exception=>x;X::ServerError.new(r,e,'get').service(
k,m,x)end;def method_missing m,c,*a;k=X.const_get c;i k;k.new('',
H['HTTP_HOST','','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s).service *a;end
def i k;k.send(:include,C,Base,Models)if !(k<C) end
end;module Views;include X,Helpers end;module Models;A=
ActiveRecord;Base=A::Base;def Base.table_name_prefix;"#{name[/\w+/]}_".
downcase.sub(/^(#{A}|camping)_/i,'')end end;class Mab<Markaby::Builder;include \
Views;def tag! *g,&b;h=g[-1];[:href,:action,:src].map{|a|(h[a]=self/h[a])rescue
Expand Down

0 comments on commit 1109984

Please sign in to comment.