是否可以在不污染全局范围的情况下将模块包含在 rake 任务中?

Is it possible to include a module in rake tasks without polluting the global scope?

我想知道 — 是否可以为 rake 任务创建私有助手,无论我如何尝试,它们最终都可以在全局范围内使用,并且还可以作为任何对象的方法使用。例如:

## this is what I need

module MyRakeHelpers
  def helper_1
  end

  def helper_2
  end
end

include RakeHelpers

task :sometask do
  helper_1
  helper_2
end

## And this should not work:

# global scope
helper_1

"a random object".helper_1

class RandomClass
  def foo
    helper_1
  end
end

我想你可以这样写你的 rake 任务:

module MyRakeHelpers
  def helper_1
  end

  def helper_2
  end
end

task :sometask do
  include RakeHelpers
  helper_1
  helper_2
end   

第一位回答者: 这是您要找的吗?

module MyRakeHelpers
  def self.helper_1
    puts 'helper_1'
  end

  def self.helper_2
    puts 'helper_2'
  end
end

task :sometask do
  MyRakeHelpers.helper_1
  MyRakeHelpers.helper_2
end

第二个回答: 我唯一能想到的就是这样

module MyRakeHelpers
  def helper_1
    puts 'helper_1'
  end

  def helper_2
    puts 'helper_2'
  end
end

task :sometask do |t|
  t.extend MyRakeHelpers
  t.helper_1
end

但是你必须在所有地方添加 t

以下是对我有用的方法:

module MyRakeHelpers
  def helper
    puts 'foo'
  end
end

module MyRakeTasks
  extend Rake::DSL
  extend MyRakeHelpers

  task :some_task do
    helper
  end
end

简而言之,您可以通过包含(或扩展)Rake::DSL 在不同的范围内使用 Rake DSL。来自 source:

DSL is a module that provides #task, #desc, #namespace, etc. Use this when you'd like to use rake outside the top level scope. For a Rakefile you run from the command line this module is automatically included.

task 在后台使用 Rake::Task#define_task,您也可以使用它来编写自己的 DSL。

感谢 How To Build Custom Rake Tasks; The Right Way 关于 define_task 的提示。