Scope of rakes in a rails project?

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

I have a number of parsers I run with rakes in a project I'm working on. When using a method name that already exists in another rake, and because they both use the same environment, I get a conflict.

Is there a way to limit the scope of rake files within their namespace? I thought that was the whole point of the namespace?

Example:

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 

In this case, when running rake test:test_task I'll receive an invalid amount of arguments error. On the other hand, if I define the method within the task itself, I have to keep the method at the top of the rake file in order. This gets kind of confusing and ugly.

Is that just a necessary evil?

Thanks!

回答1:

I see the namespaces for rake tasks as serving the same purpose as directories in a file system: they're about organization rather than encapsulation. That's why database tasks are in db:, Rails tasks in rails:, etc.

Rake namespaces are not classes so you need to ask yourself what class you're adding test_method to when you define it within a Rake namespace. The answer is Object. So, when you hit your second task, Object already has a test_method method that takes one parameter and Ruby rightly complains.

The best solution is to make your Rake tasks very thin (just like controllers) and put any supporting methods (such as test_method) off in some library file somewhere sensible. A Rake task should usually just do a bit of set up and then call a library method to do the real work (i.e. the same general layout as a controller).

Executive summary: put all the real work and heavy lifting somewhere in your library files and make your Rake tasks thin wrappers for your libraries. This should make your problem go away through proper code organization.



回答2:

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 block needs you self:: before any definition. To avoid this, you need to name the module and remove it.



回答3:

I've figured out a way to namespace the methods in Rake tasks so same-named methods don't collide.

  1. Wrap each outer namespace in a uniquely-named module.
  2. extend Rake::DSL
  3. Change your methods to class methods (with self.).

I've tested this, and it still allows one rake task to invoke or depend on another rake task that is in a different module.

Example:

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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!