【问题标题】:Ruby using prepend to patch a class doesn't workRuby 使用 prepend 来修补类不起作用
【发布时间】:2015-05-11 18:19:09
【问题描述】:

我正在尝试修补 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

我正在考虑尝试改进,这可能会更好......也许?

【问题讨论】:

  • 您能否以不需要我们编写 Sinatra Web 应用程序来调试您的代码的方式重现该问题?目前我什至没有安装 Sinatra。 stackoverflow.com/help/mcve
  • 您确定monkeypatch 应用正确吗?添加一些 puts 语句以了解发生了什么
  • 老实说,我不知道,prepend 应该允许我在不直接打开原始类的情况下进行猴子补丁,我按照示例进行操作,但它没有像我期望的那样工作(请参阅操作编辑这个补丁做了什么)。我确实尝试过使用 put,但该函数根本没有被调用,所以没有输出任何东西。不过奇怪的是,我使用prepend 进行的其他类修补工作了;我知道它确实如此,因为我有一个类使用了修补的类方法,并且它不会抛出一个嘶嘶作响的说法,说该方法不存在(如果修补失败,它会这样)。

标签: ruby monkeypatching prepend


【解决方案1】:

Sinatra 中的get、post、put 等方法是类方法,但您正在使用这些名称创建instance 方法。为了拦截方法,您需要在 Sinatra::Base 单例类之前添加。

试试这个:

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

【讨论】:

  • 我试过使用define_singleton_method 没有效果,但明天我也会试试这个。
  • 这有效,我不知道为什么define_singleton_method 没有但我不在乎,singleton_class.prepend 有效,这对我来说已经足够了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
相关资源
最近更新 更多