thorstenhirsch
thorstenhirsch

Reputation: 198

rake namespace vs. ruby module

How can I have helper functions with the same name in different rake tasks? The following code does not work:

# bar.rake
namespace :bar do

  desc 'bar'
  task :bar => :environment do
    bar
  end

  def bar
    puts "bar bar"
  end

end

# foo.rake
namespace :foo do

  desc 'bar'
  task :bar => :environment do
    bar
  end

  def bar
    puts "foo bar"
  end

end

The (wrong) result is:

$ rake bar:bar
foo bar

That's because rake's namespace does not work like ruby's module, so the bar function in the 2nd task redefines the bar function of the 1st task.

So what's a good solution to have local helper functions in rake tasks?

Upvotes: 4

Views: 473

Answers (3)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

Another way to have local helper functions is to have local helper functions :)

namespace :bar do

  desc 'bar'
  task :bar => :environment do
    helper = -> {
      puts 'bar bar'
    }

    helper.call
  end

end

Upvotes: 2

BroiSatse
BroiSatse

Reputation: 44685

You can wrap the whole definition within a module, but you need to extend it with Rake DSL:

# bar.rake
Module.new do
  extend Rake::DSL

  namespace :bar do

    desc 'bar'
    task :bar => :environment do
      bar
    end

    def self.bar
      puts "bar bar"
    end

  end

# foo.rake
Module.new do
  extend Rake::DSL

  namespace :foo do

    desc 'bar'
    task :bar => :environment do
      bar
    end

    def self.bar
      puts "foo bar"
    end

  end
end

Upvotes: 4

Bobby Matson
Bobby Matson

Reputation: 1488

More of a style preference, but typically I will create a Task class with static methods (or build an instance if you need to manage some state) and use them within the rake task. This way, these methods are also easily testable. In your case:

namespace :bar do
  task :bar => :environment do
    StaticTask.fetch
  end
end

# OR

namespace :foo do
  task :bar => :environment do
    idea = AnotherIdea.new
    idea.fetch
  end
end

More of a pattern I like to follow personally, but it creates a nice separation of concerns between tasks.

(It's also crucial to require whichever class you're bringing in)

Upvotes: 2

Related Questions