1

I have a lot of utility functions in my rake files, some of which create rake tasks. I want to move these utility functions into a module to avoid name clashes, but when I do the rake methods are no longer available.

require 'rake'

directory 'exampledir1'

module RakeUtilityFunctions
    module_function
    def createdirtask dirname
        directory dirname
    end
end

['test1', 'test2', 'test3'].each { |dirname|
    RakeUtilityFunctions::createdirtask dirname
}

The error I get is:

$ rake
rake aborted!
undefined method `directory' for RakeUtilityFunctions:Module
C:/dev/rakefile.rb:8:in `createdirtask'
C:/dev/rakefile.rb:13:in `block in <top (required)>'
C:/dev/rakefile.rb:12:in `each'
C:/dev/rakefile.rb:12:in `<top (required)>'

As far as I can tell the directory method is placed on the ruby top-level by the following code in Rake:

# Extend the main object with the DSL commands. This allows top-level
# calls to task, etc. to work from a Rakefile without polluting the
# object inheritance tree.
self.extend Rake::DSL

Is there a simple way of call functions that have been placed on the top-level like this?

Eoghan
  • 83
  • 5

2 Answers2

1

When you define a Module, the code within that module has a new scope.

So directory within RakeUtilityFunctions is in a different scope to the top-level code.

As you haven't defined directory within RakeUtilityFunctions you get an undefined method error.

Have a look at the Scope Gate section of this article.

ReggieB
  • 8,100
  • 3
  • 38
  • 46
  • Thanks for the reply @ReggieB. With your help I found another question about a similar problem, see my answer. – Eoghan Sep 09 '15 at 14:50
1

I have figured it out now. With help from @ReggieB, I discovered this question: ways to define a global method in ruby.

It contained an excerpt from the rake change log.

If you need to call 'task :xzy' inside your class, include Rake::DSL into the class.

So, the easiest way to do this is to extend the module with Rake::DSL:

require 'rake'

directory 'exampledir1'

module RakeUtilityFunctions
    self.extend Rake::DSL     ### This line fixes the problem!
    module_function

    def createdirtask dirname
        directory dirname
    end
end

['test1', 'test2', 'test3'].each { |dirname|
    RakeUtilityFunctions.createdirtask dirname
}
Community
  • 1
  • 1
Eoghan
  • 83
  • 5