您可以在调用之前修改超级方法变量吗?

时间:2018-08-17 04:47:28

标签: ruby

我需要猴子修补一些代码,我想知道是否可以在调用它之前在super中编辑一行(特定方法变量赋值)?

class Test_class

  def test
    res = "AAAAAA"
    puts res
  end

end

module TestExtensions

  def test
    # do some Ruby magic here to change res = "BBBBB" ?
    super
  end

end

class Test_class
  prepend TestExtensions
end

Test_class.new.test

---
Output is: AAAAAA

因此,在这个愚蠢的示例中,我可以在调用super之前编辑res的值并进行更改吗?在我想打补丁的原始类方法中,我只需要更改方法中的20行代码中的一行即可。我希望不复制整个方法并进行一行更改,而是希望在调用super之前仅编辑特定行。

8月20日更新:

下面是我要修补的确切代码。

https://github.com/chef/chef/blob/master/lib/chef/provider/remote_directory.rb#L206

只想更改行

res = Chef::Resource::CookbookFile.new(target_path, run_context)

代替

res = Chef::Resource::Template.new(target_path, run_context)

如果我不仅可以替换super方法中的这一行,也许我可以暂时为Chef::Resource::CookbookFile = Chef::Resource::Template加上别名,因此在调用super时它会返回正确的对象,但是我不知道不知道这是否可能。

1 个答案:

答案 0 :(得分:1)

  

只想更改行

res = Chef::Resource::CookbookFile.new(target_path, run_context)
     

代替

res = Chef::Resource::Template.new(target_path, run_context)
     

[...]我只是想知道是否还有更多忍者Ruby方式[...]

这是超级肮脏的黑客。假设该行是对Chef::Resource::CookbookFile的唯一引用,您可以(我不说您应该)在引用替换类的接收方下定义一个具有相同名称的常量:

class Chef
  class Provider
    class RemoteDirectory

      class Chef
        class Resource
          CookbookFile = ::Chef::Resource::Template
        end
      end

    end
  end
end

现在Chef::Resource::CookbookFile中的Chef::Provider::RemoteDirectory将解析为返回::Chef::Resource::Template的新常量,所以

res = Chef::Resource::CookbookFile.new(target_path, run_context)

有效地变为:

res = ::Chef::Resource::Template.new(target_path, run_context)