ruby - 整理猴子补丁

标签 ruby oop monkeypatching

我读了一篇blog post建议为您的猴子补丁命名,以便可以轻松查看和包含它们。

例如:

module CoreExtensions
  module DateTime
    module BusinessDays
      def weekday?
        !sunday? && !saturday?
      end
    end
  end
end

将进入:lib/core_extensions/class_name/group.rb 文件。

可以使用 Module#include 实例方法将其包含在 DateTime 类中(该类继承该方法,因为 Class 是一个 Module )

# Actually monkey-patch DateTime
DateTime.include CoreExtensions::DateTime::BusinessDays

我的问题是 include 语句去哪里?有约定吗?

例如:

我有以下猴子补丁:

# http://www.justinweiss.com/articles/3-ways-to-monkey-patch-without-making-a-mess/
module CoreExtensions
  module String
    module Cases
      def snakecase
        return self if self !~ /[A-Z]+.*/
        # http://rubular.com/r/afGWPWLRBB
        underscored = gsub(/(.)([A-Z])/, '\1_\2')
        underscored.downcase
      end

      def camelcase
        return self if self !~ /_/ && self =~ /[A-Z]+.*/
        split('_').map{ |e| e.capitalize }.join
      end
    end
  end
end

它位于 lib/core_extensions/string/cases.rb 文件内。

我应该将 String.include CoreExtensions::String::Cases 语句放在哪里?

另外要明确的是,这只是一个 ruby​​ 项目,这有什么区别吗?

我尝试将其放入lib/devify.rb

require 'devify/version'
require 'devify/some_dir'
require 'devify/scaffold'
require 'devify/tree_cloner'
require 'devify/renderer'
require 'devify/project'

require 'devify/tasks/some_task'
require 'devify/tasks/bootstrap'

require 'core_extensions/string/cases'

module Devify
  String.include CoreExtensions::String::Cases
end

这很有效,而且它为什么有效也是有道理的。这是因为我的整个应用程序都位于 Devify 模块或命名空间内。

这种方式也很好,因为我没有污染全局命名空间,对吗?因为我只是猴子修补 Devify 中的 String

只是不确定这是否是正确的方法。

最佳答案

include 调用放在哪里并不重要。

调用String.include总是会猴子修补整个对象空间中所有字符串使用的一个String类。因此最好将指令放在顶层,以免误导代码读者。

猴子补丁始终是全局的。

这是一个强大的功能,可以永久使用。

如果您正在创作 gem,请注意您正在与其他人共享全局命名空间。对于顶级模块甚至 gem 名称也是如此。共享命名空间只是共享代码的现实。

如果您正在寻找词法范围的猴子补丁,请查看 Ruby 2 中引入的新细化功能。

改进是取自 Smalltalk 类框的想法。不过,细化也有其自身的问题,例如它们缺乏对内省(introspection)和反射(reflection)的支持。因此本质上使它们变得隐秘并且不适合生产使用。

如果您希望将猴子补丁限制为仅某些字符串对象,请考虑子类化String或在实例上调用extend

关于ruby - 整理猴子补丁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41497350/

相关文章:

python - re.RegexObject 不存在(引发 AttributeError)

ruby - 循环中的哈希数组,在每次迭代期间重写哈希值

javascript - 如何在 JavaScript 和 Ruby 中对原始 URL 进行编码/解码以在两者中获得相同的值?

java - 关于通过java实现的反射的工厂设计模式

VB.Net 类型转换

python - 为什么我不能从子类访问 XGBClassifier feature_importances_?

python - 如何检查是否可以在 Python 对象中设置(修补)属性

javascript - 将 rails 变量传递给 js 函数

ruby-on-rails - 在 ruby​​ on Rails 中立即为所有用户创建出勤情况

python - pymongo + gevent : throw me a banana and just monkey_patch?