【问题标题】:How do I add a method to a ruby gem without editing the gem source?如何在不编辑 gem 源的情况下向 ruby​​ gem 添加方法?
【发布时间】:2010-12-19 19:04:12
【问题描述】:

我正在使用 acts_as_taggable_on gem 并想向其中一个 gem 源文件 (tag.rb) 添加方法,但我不想以任何方式更改 gem 源。

我尝试在/app/models 目录或/lib 目录中创建自己的 tag.rb 文件,然后将所需的方法添加到该文件中,期望 ruby​​ 将合并两个 tag.rb 文件

但是当我这样做时,我会得到一个NoMethodError: undefined method ...

我错过了什么?

【问题讨论】:

  • 为我没有受过教育的回答道歉,我点击了“删除”,所以希望它会死得很惨。我不知道在 Ruby 中重新开放课程的可能性,因此我的回答。

标签: ruby-on-rails ruby metaprogramming


【解决方案1】:

我认为重新打开 Tag 类是正确的方法是正确的。除非它对您的代码真正有意义,否则我不会引入另一个级别的继承。

我不知道为什么重新打开 Tag 类不起作用。一些想法:

1 - 当您编写自己的 Tag 类时,它是否源自 ActiveRecord::Base? Tag 类在充当可标记时确实如此,我可以看到忽略它可能会搞砸事情。

2 - 如果我需要一个地方来放置重新打开单个方法的插件类的代码,我可能会将它放在一个初始化程序文件中(例如 config/initializers/tag_patch.rb)。只是为了保持清洁。

3 - 如果所有其他方法都失败并且您仍然无法正确重新打开 Tag 类(无论出于何种原因),您可能会尝试添加其他元编程技术。例如:

Tag.send(:define_method, “method_name”) do 
  #code for your method
end

【讨论】:

  • 这似乎有效。我猜你的第 2 点是魔法。将代码放入初始化程序可能是我需要的(尽管我认为我也可以将 tag.rb 放入 /lib 中)。
  • class_eval 有什么问题,似乎是一种更好、更清晰的重新开课方式。
  • 我认为 railsninja 是对的,Tag.class_eval 可能是最清晰的方法。当我写出 define_method 示例时,我没有想到。
  • 谢谢。我将class Aaaa::Bbbb ; def my_method_name ; 'something to do and return' ; end ; end 的相似性添加到config/initializers/appropriate_name.rb,并且重新启动应用服务器后我能够通过Aaaa::Bbbb.my_method_name 使用我的新方法 - (如果你也重新启动rails console)重新使用)。
【解决方案2】:

等等,你不应该将方法添加到 file,而是添加到 class。你熟悉reopening the class这个概念吗?您不能仅通过将文件命名为与定义原始类的文件相同的名称来添加方法。幸运的是。 :)

【讨论】:

    猜你喜欢
    • 2013-05-24
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 2014-11-20
    • 2022-07-22
    相关资源
    最近更新 更多