简体   繁体   English

如何monkeypatch现有的宝石(Rails引擎)?

[英]How to monkeypatch an existing gem (Rails engine)?

I'm getting started with Ruby and Rails 3. There is a Rails Engine (packaged as a Gem) that I would like to use but it doesn't work exactly as I would like it to. 我开始使用Ruby和Rails 3.我想使用Rails引擎(打包为Gem),但它并不像我希望的那样完全正常工作。 I want to make some slight modifications but don't want to have to create my own forked version. 我想做一些细微的修改,但不想创建自己的分叉版本。 I think this is where monkey patching becomes useful. 我认为这是猴子修补变得有用的地方。

Being new to Ruby (and coming from a PHP background) monkey patching is a new concept to me. 作为Ruby的新手(来自PHP背景)猴子修补对我来说是一个新概念。 How would I go about monkey patching an existing gem, and how would I go about organizing my modifications? 我将如何修补猴子修补现有的宝石,我将如何组织我的修改? I'm looking for some "best practice" approaches to this. 我正在寻找一些“最佳实践”方法。

This is a very broad question because you didn't mention what gem or how you wanted to modify the behavior, but... 这是一个非常广泛的问题,因为你没有提到什么宝石或你想如何修改行为,但......

In general, the way to approach this (one way to approach this) is open the gem up. 一般来说,接近这种方法(解决这个问题的一种方法)就是打开宝石。 Use an editor that can open all the files so you can easily flip from one to another. 使用可以打开所有文件的编辑器,以便您可以轻松地从一个文件切换到另一个文件。 When looking at the gem, figure out which class contains the functionality you want to change. 查看gem时,找出哪个类包含您要更改的功能。

So, you go to your test or spec directory and write a test like: 所以,你去你的测试或spec目录并写一个测试,如:

# Write tests to your API the way you want to write
# your code, not how you expect you *will* write that
# code.

def test_it_spits_out_my_awesome_error_message
  # some setup code
  assert_equal my_obj.spit_out_error_message, "some expected error message"
end

and run your tests. 并运行您的测试。 Of course they fail because your new functionality is not in place. 当然,它们会失败,因为您的新功能尚未到位。

Now, say your change goes in spit_out_error_message in class AwesomeAuthentication . 现在,假设您的更改位于spit_out_error_message类中的AwesomeAuthentication You can create a class in your project -- probably in lib/awesome_auth.rb or something like that. 您可以在项目中创建一个类 - 可能在lib / awesome_auth.rb或类似的东西中。 In it, you do as described here: Rails 3: alias_method_chain still used? 在其中,您按照此处的描述执行: Rails 3:仍然使用alias_method_chain? . You'll also want to read this: http://yehudakatz.com/2009/03/06/alias_method_chain-in-models/ , as it describes modifying an existing class using this technique (scroll to the bottom). 您还需要阅读:http: //yehudakatz.com/2009/03/06/alias_method_chain-in-models/ ,因为它描述了使用此技术修改现有类(滚动到底部)。

So you create a new spit_out_error_message , cobble it in as described above and rerun the tests. 因此,您创建一个新的spit_out_error_message ,如上所述拼凑它并重新运行测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM