Ruby 使用前缀修补 class 不起作用
Ruby using prepend to patch a class doesn't work
我正在尝试修补 sinatra 中的动词方法,以便在它之前添加一个额外的函数调用。我在使用别名链来保留原始方法时遇到了问题,但我发现前置可以让我做我想做的事而无需使用这种 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 动词方法并检查一个符号是否被传递给它,如果一个是然后它将符号传递给一个方法 returns 一个映射和从映射中取出 url,然后将其传递给 sinatra 的普通 HTTP 动词方法。
这样我就可以拥有:
Restman::Routes.define do
map :root, to: '/'
end
然后
get :root do
'hello world!'
end
我正在考虑尝试改进,这可能会更好..也许吧?
Sinatra中的get
、post
、put
等方法是class方法,但是你在创建实例 具有这些名称的方法。为了拦截方法,您需要在 Sinatra::Base
单例 class.
前面加上
试试这个:
::Sinatra::Base.singleton_class.prepend Restman::Patches::Sinatra_Base_Patch
我正在尝试修补 sinatra 中的动词方法,以便在它之前添加一个额外的函数调用。我在使用别名链来保留原始方法时遇到了问题,但我发现前置可以让我做我想做的事而无需使用这种 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 动词方法并检查一个符号是否被传递给它,如果一个是然后它将符号传递给一个方法 returns 一个映射和从映射中取出 url,然后将其传递给 sinatra 的普通 HTTP 动词方法。
这样我就可以拥有:
Restman::Routes.define do
map :root, to: '/'
end
然后
get :root do
'hello world!'
end
我正在考虑尝试改进,这可能会更好..也许吧?
Sinatra中的get
、post
、put
等方法是class方法,但是你在创建实例 具有这些名称的方法。为了拦截方法,您需要在 Sinatra::Base
单例 class.
试试这个:
::Sinatra::Base.singleton_class.prepend Restman::Patches::Sinatra_Base_Patch