2011-05-30 108 views
7

我有一些解析器,我在使用耙子运行的项目中运行。当使用另一个rake中已经存在的方法名称,并且由于它们都使用相同的环境时,我会遇到冲突。围栏项目的围栏范围?

有没有办法限制其名称空间内的rake文件的范围?我认为这是命名空间的全部重点?

例子:

namespace :test do 
    task :test_task => :environment do 
     ... 
    end 

    def test_method(argument) 
    ... 
    end  
end 

namespace :other_test do 
    task :test_task => :environment do 
    ... 
    end 

    def test_method(argument, argument2) 
    ... 
    end 
end 

在这种情况下,运行rake test:test_task当我接收参数错误的无效的金额。另一方面,如果我在任务本身内定义方法,则必须按照顺序将方法保留在rake文件的顶部。这会让人感到困惑和丑陋。

这只是一个必要的邪恶?

谢谢!

回答

8

我看到rake任务的命名空间与文件系统中的目录具有相同的用途:它们关于组织而不是封装。这就是为什么数据库任务是db:,Rails的在rails:任务等。所以你要问自己,你要添加test_method当你瑞克命名空间中定义它是什么类

耙命名空间是不是类。答案是Object。所以,当你第二次执行任务时,Object已经有一个方法需要一个参数,Ruby正确地投诉。

最好的解决方案是让你的Rake任务非常简单(就像控制器一样),并将某些支持方法(如test_method)关闭在某个合理的库文件中。 Rake任务通常只需要做一些设置,然后调用一个库方法来完成真正的工作(即与控制器相同的总体布局)。

执行摘要:将所有实际工作和繁重工作放在库文件的某处,并使您的Rake任务为您的库提供精简的包装。这应该通过正确的代码组织让您的问题消失。

+0

跟进的问题:HTTP://计算器。com/questions/6183367/dynamic-namespace-rakes-and-parser-classes-with-rails – 2011-05-31 06:28:26

+0

你有机会看看吗? – 2011-06-02 21:45:52

0
module Anonymous 
    namespace :test do 
    # brabra 
    end 
end 
self.class.send(:remove_const, :Anonymous) 

module Anonymous 
    namespace :another_test do 
    # brabra 
    end 
end 
self.class.send(:remove_const, :Anonymous) 

Module.new do end块需要你self::之前的任何定义。为了避免这种情况,您需要命名模块并将其删除。

0

我已经想出了一种在Rake任务中命名空间方法的方法,所以相同名字的方法不会发生冲突。

  1. 将每个外部名称空间包裹在一个唯一命名的模块中。
  2. extend Rake::DSL
  3. 将您的方法更改为类方法(使用self.)。

我测试过了,它仍然允许一个rake任务调用或依赖另一个模块中的另一个rake任务。

例子:

module Test 
    extend Rake::DSL 

    namespace :test do 
    task :test_task => :environment do 
     ... 
    end 

    def self.test_method(argument) 
     ... 
    end  
    end 
end 

module OtherTest 
    extend Rake::DSL 

    namespace :other_test do 
    task :test_task => :environment do 
     ... 
    end 

    def self.test_method(argument, argument2) 
     ... 
    end 
    end 
end