2016-02-27 3 views
3

Как я могу иметь вспомогательные функции с тем же именем в разных задачах rake? Следующий код не работает:rake namespace vs. ruby ​​module

# 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 

(неправильно) Результат:

$ rake bar:bar 
foo bar 

Это потому, что пространство имена Грабель не работает, как модуль Ruby, поэтому функция бара во 2-й задаче переопределяет бар функции 1-й задачи.

Итак, какое хорошее решение имеет локальные вспомогательные функции в рейк-задачах?

+0

Ну, вы можете обернуть пространство имен в модуле. – BroiSatse

+0

Это не работает. Обертка всего в модуле приводит к: 'NoMethodError: undefined method 'namespace' для Foo: Module'. И оставляя пространство имен вне модуля, таким образом, только обертывая все внутри пространства имен в модуле, выдает «NoMethodError: undefined method« desc »для Foo: Module'. Поэтому я думаю, что рейк-задачи не могут быть в модуле. Я могу поместить свою вспомогательную функцию в модуль, но мне нужно будет вызвать бар с явным пространством имен (Foo :: bar в foo.rake и Bar :: bar в bar.rake). – thorstenhirsch

+0

вместо 'модуля Foo' try,' Module.new do'. Это будет оценивать блок внутри контекста анонимного модуля, не нарушая область поиска метода. – BroiSatse

ответ

2

Вы можете обернуть все определения в модуле, но вы должны продлить его с 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 
+0

Да, вот и все! Спасибо, BroiSatse! – thorstenhirsch

1

Больше предпочтений в стиле, но обычно я создам класс Task со статическими методами (или создадим экземпляр, если вам нужно управлять некоторым состоянием) и используйте их в задаче грабли. Таким образом, эти методы также легко проверяются. В вашем случае:

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 

Больше шаблона мне нравится следовать лично, но это создает хорошее разделение задач между заданиями.

(Это также важно require какой класс вы чего в)

2

другой способ иметь локальные функции помощников, чтобы иметь местные вспомогательные функции :)

namespace :bar do 

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

    helper.call 
    end 

end 
+0

Да ... но теперь это слишком локально. ;-) Я искал функции, которые являются локальными для файла rake (пространство имен rake) и может использоваться во всех задачах в этом файле рейка. – thorstenhirsch