我试图在sinatra中修补动词方法,在它之前添加额外的函数调用。我在使用别名链来保留原始方法时遇到了问题,但我发现prepend可以让我在不使用这种hacky方法的情况下做我想做的事情。
但是我的前置函数没有被调用,只是被忽略了。 发生了什么事?
这是我的补丁:
if defined? Sinatra::Base
module Restman
module Patches
module Sinatra_Base_Patch
[:get, :post, :put, :delete, :head, :options, :patch, :link, :unlink].each do |func_name|
define_method func_name do |*args,&block|
if args.first.class == Symbol
super(Restman::Routes.get(args.first)[:uri],*block)
else
super(*args,*block)
end
end
end
end
end
end
::Sinatra::Base.prepend Restman::Patches::Sinatra_Base_Patch
end
编辑:(解释)
补丁非常简单,它会覆盖sinatra的普通HTTP动词方法,并检查符号是否传递给它,如果有符号,则将符号传递给返回映射的方法并获取url离开映射,然后将其传递给sinatra的普通HTTP动词方法。
我可以这样:
Restman::Routes.define do
map :root, to: '/'
end
然后再做
get :root do
'hello world!'
end
我想要尝试改进,这可能会更好......也许?
答案 0 :(得分:1)
Sinatra中的get
,post
,put
等方法是类方法,但您正在创建实例方法用这些名字。为了拦截你需要预先添加Sinatra::Base
单例类的方法。
试试这个:
::Sinatra::Base.singleton_class.prepend Restman::Patches::Sinatra_Base_Patch