首页 > 解决方案 > 在 Ruby 中编写模块方法的正确方法

问题描述

什么是编写模块的正确方法?它只是用来存储一些和平的代码以最小化行数,还是比这更重要的东西

我已经使用并看到了编写模块的方式,我正在努力建立正确的方式来定义和标准化模块。这个例子是我们在 rails 中使用的一种控制器代码

方式1: -

module B
  extend ActiveSupport::Concern

  def process_items
    # do somthing...
    @items.pluck(:names)
  end
end


Class A
  include B
  
  def index
    @items = Item.all
    @item_names = process_items
  end
end

方式2: -

module B
  extend ActiveSupport::Concern

  def process_items(items)
    # do somthing...
    items.pluck(:names)
  end
end


Class A
  include B
  
  def index
    @items = Item.all
    @item_names = process_items(@items)
  end
end

方式1: -

  1. 当我独立看到这个时,它的可读性并不高,因为我不知道@items 在这个方法中是如何出现的
  2. 单元测试对于方法来说很难,因为它是依赖的

方式2: -

  1. 查看方法,我可以看到输入即将到来,我们正在处理它并将其返回(可读性很好)
  2. 单元测试很容易,我们将调用方法传递它所需要和期望的

我看到模块的方式应该是独立的,不言自明的,它应该是通用的,以便可以在任何类中使用,类型的助手。但其他方式可能取决于我们在哪里使用模块

我们正在使用像 rails 这样的模块

  1. 我们在模型中使用关注点,当我们调用模块方法时,我们可以使用self.<field>我们不需要传递任何东西,因为实例变量应该在每个实例方法中都是可访问的
  2. 视图助手是模块,我看到他们将逻辑放入其中,很难理解变量的来源可能是实例变量或参数,如何让它接受某物并将其返回的方法
  3. 对控制器的担忧,比如我给出的例子

我想对此有想法,最好的方法是什么?它是可以标准的还是更具情境性的,或者我还不知道:)

注意: - 我正在查看这个问题,但在这个问题上给出的答案不再有效,因为引用的链接不起作用。 使用模块的正确方法

标签: ruby-on-railsruby

解决方案


这里的区别实际上是学术上的,就好像你同时拥有attr_reader :x两者@x并且x将具有相同的含义。

可以理解,在 mixin 模块中,您将引用作为“混入”的类或模块的一部分的方法和/或变量。因此,看到@x,或者在你的情况下,@items,不应该是一个真正的惊喜。

如果您想将其添加为显式参数,那么您首先会错过很多使用 mixin 的好处。你根本不需要混合它,你可以像使用它一样使用它B.process_items(...)。换句话说,你的第二种方法是有身份危机。它是无缘无故包含 Concern 的独立模块,还是弱 mixin?

在进行测试时,您必须在实现所需功能的模块或类中测试 mixin。在这种情况下,您需要一个@items变量或一个items方法,并且它必须具有预期类型的​​值。

为了清楚起见,这应该在某处记录,但实际上是与使用此模块的任何人的隐含合同。


推荐阅读