Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby使用prepend修补类不';行不通_Ruby_Monkeypatching_Prepend - Fatal编程技术网

Ruby使用prepend修补类不';行不通

Ruby使用prepend修补类不';行不通,ruby,monkeypatching,prepend,Ruby,Monkeypatching,Prepend,我正在尝试修补sinatra中的动词方法,以便在其之前添加额外的函数调用。我在使用别名链来保留原始方法时遇到了问题,但我发现prepend允许我在不使用这种黑客方法的情况下做我想做的事情 然而,我的前置函数没有被调用,只是被忽略了。 发生什么事了 这是我的补丁: if defined? Sinatra::Base module Restman module Patches module Sinatra_Base_Patch

我正在尝试修补sinatra中的动词方法,以便在其之前添加额外的函数调用。我在使用别名链来保留原始方法时遇到了问题,但我发现prepend允许我在不使用这种黑客方法的情况下做我想做的事情

然而,我的前置函数没有被调用,只是被忽略了。 发生什么事了

这是我的补丁:

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中的方法是类方法,但您正在使用这些名称创建实例方法。为了拦截这些方法,您需要在
Sinatra::Base
singleton类前面加上前缀

试试这个:

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

您能否以一种不需要我们编写Sinatra web应用程序来调试代码的方式重现问题?我现在甚至没有安装Sinatra。你确定monkeypatch应用正确吗?添加一些puts语句以了解发生了什么我不知道老实说,prepend应该允许我在不直接打开原始类的情况下运行monkey patch,我遵循了示例,但它的工作方式与我预期的不一样(请参阅op edit了解此补丁的功能)。我确实尝试过使用put,但是函数根本没有被调用,所以没有输出任何get。奇怪的是,另一个使用
prepend
的类补丁确实有效;我知道是这样的,因为我的一个类使用了一个修补过的类方法,它不会发出嘶嘶的声音说这个方法不存在(如果修补失败,它会这样)。我尝试过使用
define\u singleton\u method
没有效果,但我明天也会尝试。这很有效,我不知道为什么
define\u singleton\u method
没有,但我不在乎,
singleton\u类。prepend
有效,这对我来说已经足够了!