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中的getpostput等方法是class方法,但是你在创建实例 具有这些名称的方法。为了拦截方法,您需要在 Sinatra::Base 单例 class.

前面加上

试试这个:

::Sinatra::Base.singleton_class.prepend Restman::Patches::Sinatra_Base_Patch