在Ruby中定义模块时,我已经看到了模块期望要包含的类的示例,以便具有特定的定义和功能。
例如,模块可能会调用一个本身不包含期望的方法,其中包含的类包含该方法定义。
对我来说,这是一种与强类型语言背景不同的范例,它缺乏包含任意逻辑集的能力(Ruby作为一个整体是完全不同的范例)。
根据红宝石标准,这是否是一种可接受的风格,或者至少在成熟的代码库中经常被认为是“正常”?
我意识到这是一个有点主观的问题,但是我想看看这是否经常发生,如果他们要构建一个模块,那么就会被认为是“规范”。
答案 0 :(得分:2)
由于Ruby的类型非常松散,因此更多地依赖于响应方法的能力,即所谓的duck typing,而不是类,很难对这些事情负责。
如果您的模块包含在不兼容的上下文中,那么作为一个模块,您的工作就不是它的任务。事先,如果任何给定的方法调用成功或失败,你都无法知道,因为在你的模块被包含之后,可能还会发生其他事情会使某种验证过早。
鉴于这些限制,尝试构建事物以避免这种模糊性非常重要。
以Enumerable为例。为了使它在包含时正常工作,必须在包含它的上下文中定义许多方法。如果没有定义这些,模块将无法工作,但此失败的责任不是可枚举,而是包含它的模块。
基本上,在你include SomeModule
之前,你应该确定满足包含该模块的依赖关系(如果有的话)。作为包含者,您还要对可能导致的任何冲突承担全部责任。
其他语言有更严格的方法来验证完整性,例如Objective C的协议功能或C ++中基类的存在。由于Ruby没有这个,为了确保一切正常,我们采用了自动化测试套件。您可能会注意到Ruby社区非常面向测试,这种模糊性是造成这种情况的众多原因之一。
答案 1 :(得分:1)
是的,这是可以接受的。即使在核心库中,您经常会看到非常这样的事情,其中包含Comparable
和Enumerable
等模块,这两个模块都期望在包含的内容中实现某些方法类。
这种期望可以与Java中的接口进行比较,只与鸭子与结构类型进行比较。
除了这些广泛适用的模块之外,您还可以通过复杂的类来看到这一点,这些类可以分解为更小的模块化问题。这些模块仍然希望在包含类的上下文中运行,但是代码被分解成多个部分,使关注点变得可插入,并且包含类可以更容易管理。
这种模式:
lib/
someclass.rb
someclass/
concern_a.rb
concern_b.rb
...其中concern_a
和concern_b
是someclass
中包含的模块,非常常见,我认为这很直观,您不会想知道{中的方法是什么{1}}正在做。
当然,这种灵活性并非没有代价。特别是在Rails中,考虑到丰富的动态定义方法(包括greps)和魔术自动加载,找到你正在寻找的代码有时会很困难,特别是在处理你继承的不那么出色的遗留代码时,例如。