Ruby 组织猴子补丁
我读了一篇文章,其中建议给你的猴子补丁命名,这样它们就可以很容易地查看和包含 例如:Ruby 组织猴子补丁,ruby,oop,monkeypatching,Ruby,Oop,Monkeypatching,我读了一篇文章,其中建议给你的猴子补丁命名,这样它们就可以很容易地查看和包含 例如: module CoreExtensions module DateTime module BusinessDays def weekday? !sunday? && !saturday? end end end end 将进入:lib/core\u extensions/class\u name/group.rb文件 它可以通过模
module CoreExtensions
module DateTime
module BusinessDays
def weekday?
!sunday? && !saturday?
end
end
end
end
将进入:lib/core\u extensions/class\u name/group.rb
文件
它可以通过模块#include
实例方法包含在DateTime类中(类继承该方法是因为类
是模块
)
我的问题是include语句去哪里了?有会议吗
例如:
module CoreExtensions
module DateTime
module BusinessDays
def weekday?
!sunday? && !saturday?
end
end
end
end
我有以下猴子补丁:
# 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\u extensions/string/cases.rb
文件中
我应该把我的String.include CoreExtensions::String::Cases
语句放在哪里
同样需要说明的是,这只是一个ruby项目,这会有什么不同吗
我试着把它放在lib/device.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
模块或名称空间中
这种方法也很好,因为我没有污染全局名称空间,对吗?因为我是唯一一个住在device
里面的猴子补丁String
s
只是不确定这样做是否正确。尽管ruby提供了许多动态更改类或方法内容的方法,但是猴子补丁可能会导致大问题和奇怪的bug。我读了这篇文章()关于为什么使用猴子补丁是个坏主意 总之,他说的很多话都有道理。当您创建一个monkey补丁时,您假设它只在该项目中起作用,并且,当有更多具有类似用途的库放在一起时,您可能会产生冲突和不可见的副作用 在某些情况下,猴子补丁的好处是惊人的,比如ActiveSupport通过使用
ago
或from\u now
方法,或者作为到\u json
的方法,对Fixnum类进行猴子补丁来处理日期操纵。但是,应避免使用猴子修补
要点是:Ruby是一种面向对象的语言,您可以使用对象组合或任何其他模式来实现您的目标。在某种程度上,Monkey patching会将您引向与面向对象哲学相反的方向,因为您会为一个预先存在的类添加更多的职责,并增加它的公共接口以提供新的功能
此外,该类的行为和可用的公共方法并不明确。通过查看类定义,您无法知道它是什么,它在系统中的角色是什么,以及它如何与其他对象交互。它使一项简单的任务最终变得更加困难
显然,猴子补丁使一切都变得更小、更简单,但避免它会使代码更易于维护、更易于调试、阅读和测试,并且更优雅,因为它符合“OOP”模式。将
include
调用放在何处并不重要
调用String.include
将始终对整个对象空间中所有字符串所使用的String
类进行猴子补丁。因此,最好将指令放在顶层,以免误导代码的读者
猴子修补总是全球性的
这是一个强大的功能,可以长期使用
如果您正在编写gem,请注意您正在与其他人共享一个全局名称空间。顶级模块甚至gem名称也是如此。共享名称空间只是共享代码的现实
如果您正在寻找词汇范围的monkey补丁,请查看Ruby 2引入的新细化功能
改进是从Smalltalk的类框中提取的想法。然而,改进并非没有自身的问题,例如,它们缺乏对内省和反思的支持。因此,从本质上说,它们是隐形的,不适合生产使用
如果您只想将猴子补丁限制到某个字符串对象,请考虑子类<代码>字符串或在实例上调用<代码>扩展< /代码>。< /p>如果您编写“代码>字符串”,请包含< /代码>您正在污染全局命名空间的任何地方。您可以通过将该调用放入一个方法来延迟它。但是,一旦调用该方法,所有字符串都将被修补。仔细阅读作为一个不太干扰的替代方案的改进。我添加了几个例子。顺便说一下,这个文件命名约定对于Ruby编程来说是一个很好的实践。它可以帮助自动加载依赖项-例如,如果您正在使用该模式,您可以说
Dir.glob(“./***/.rb”)。按{path{124; path.count(“/”)对u进行排序。每个{124; path{124;都需要path}
,它将加载所有文件,按照文件名中/
的计数排序(考虑您的常量层次结构)