rack和actionpack的map对比

本文介绍了Rack的简单配置方法及路由映射原理,对比Rails中的复杂路由设置,展示了Rack配置的简洁性及其在轻量级应用中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单的rackup配置

infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, env.inspect]}
use Rack::CommonLogger
use Rack::ShowExceptions

map '/' do
run infinity
end

map '/version' do
map '/' do
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "infinity 0.1"] }
end

map '/last' do
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, Rack::Request.new(env).params.inspect] }
end
end

执行先安装rack gem install rack
使用 rackup -R infinity.ru -p 3000

其中map的写法和routes.rb中做法差不多,回顾一下routes.rb中的写法。

ActionController::Routing::Routes.draw do |map|
map.connect ':controller/:action/:id'
end

routes.rb里面发生了什么呢?很不幸、里面过程错综复杂,横跨了至少四个类Builder,Mapper,Route,RouteSet,我只能告诉你结果,一句map.connect生成了一个Route对象。

rack代码则简单的我可以轻易的讨论。

module Rack
...

class Builder
def initialize(&block)
@ins = []
instance_eval(&block) if block_given?
end

...
def map(path, &block)
if @ins.last.kind_of? Hash
@ins.last[path] = self.class.new(&block).to_app
else
@ins << {}
map(path, &block)
end
end

def to_app
@ins[-1] = Rack::URLMap.new(@ins.last) if Hash === @ins.last
inner_app = @ins.last
@ins[0...-1].reverse.inject(inner_app) { |a, e| e.call(a) }
end
...

end
end

module Rack
...

class URLMap
def initialize(map)
@mapping = map.map { |location, app|
if location =~ %r{\Ahttps?://(.*?)(/.*)}
host, location = $1, $2
else
host = nil
end

unless location[0] == ?/
raise ArgumentError, "paths need to start with /"
end
location = location.chomp('/')

[host, location, app]
}.sort_by { |(h, l, a)| [-l.size, h.to_s.size] } # Longest path first
end

...
end
end



注意[0...-1]是不包含-1这个元素的,所以to_app只执行了前两句。map最终生成了一个url和Rack::URLMap对象的Hash。而在rails当中,url被切割成了多个segments。Rails这样作也自有其用处,常见的redirect_to :action => 'action'就是这样构造出url的,但是对于轻量级应用,就有一点大炮打蚊子了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值