我读了一篇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/