如何将块移动到lib

时间:2016-08-05 14:56:58

标签: ruby

让我们有一些提供API的模块或gem(或它们的池)。 Teese API我们无法修改。 API具有需要blok的界面。让API调用MyClass并使用方法foo来重新阻止阻塞。我们需要编写足够的代码来阻止内容。我们需要编写这些块的nubmer。因此,我们拥有许多具有此类API的模块,这些模块需要块的实现以及API的块实现数量。我们将块代码称为some code。这种情况的完整代码示例如下所示:

MyClass.foo do
  some code
end

在这个简短的示例中,我们可以看到使用方法MyClass的课程foo,并在其中阻止我们的some code

让我们想要在块或整个块中轻松替换类和方法以及代码。我们需要为块实现的每个变体重构移动块到lib (或移动到gem)。

我在回答之后写了问题,问题无法回答,所以我需要使用...而不是问ruby sintax。没有阻塞或没有我们的实现的重构代码some come(它移动到lib)看起来像这样:

MyClass.foo ...

现在在重构期间创建了新库,其中要求ruby代码未知并表示为...。看起来像这样:

lib/Lib.rb

...
  some code
...

在库中我们可以看到我们的实现some code或阻塞我们的some code,并且需要查看另一个解决任务所需的ruby特定sintax。

在上面的示例中,我需要编写的内容代替...。我想知道进行此类重构的所有可能的躲闪,笔触,方法和接收,以及此任务的所有可能解决方案,以便轻松组合给定的API和现成的实现。

1 个答案:

答案 0 :(得分:1)

答案在很大程度上取决于some codeLib.rb的存储方式。我假设它不是像脚本中那样的独立代码,而是包含在Proc,函数或(类/模块)方法中。您可以做的只是将原始块中的some code更改为对相应对象的调用,如下所示:

适用于任何类型的Proc

Lib.rb

some_code = proc { some code }  # or
some_code = Proc.new { some code }  # or
some_code = lambda { some code }  # or
some_code = -> { some code }

电话:

MyClass.foo do
  some_code.call  # or
  some_code[]  # or
  some_code.()
end

例如方法

Lib.rb

def SomeClass
  def some_code
    some code
  end
end

电话:

# Somewhere else
some_instance = SomeClass.new

MyClass.foo do
  some_instance.some_code
end

对于类(或模块)方法

Lib.rb

class SomeClass
  def self.some_code
    some code
  end
end

电话:

MyClass.foo do
  SomeClass::some_code
end

替代方案:明确传递块

一个有趣的替代方法是将事物作为显式参数传递,然后Ruby将其解释为块。接受块的每个函数f都可以这样调用:

f(other, parameters, &something)

&前面的something指示Ruby在to_proc上调用Proc(如果它还不是something)并传递结果作为f期望的块。

something重新审视的方式取决于Lib.rb

对于Proc s

MyClass.foo(&some_code)

例如方法

MyClass.foo(&some_instance.method(:some_code))

使用Object#method

对于类/模块方法

这个很棘手,因为它们实际上基本上是元类的实例方法,你可以这样得到:

SomeMetaClass = class << SomeClass; self; end

然后你可以按照上面的步骤继续:

MyClass.foo(SomeMetaClass.method(:some_code))