Thor intends for your classes to subclass the Thor class. The Thor class then includes and extends modules allowing their methods to be class methods. If you look at the source, for example Actions.rb, you will see what I mean:
# thor/lib/thor/actions.rb
class Thor
module Actions
# this is the interesting part and answers your question
def self.included(base) #:nodoc:
base.extend ClassMethods
end
module ClassMethods
This is a common Ruby idiom that uses a mixin to define class methods (as opposed to instance methods) on its inclusor.
As an example,
[2] pry(main)> class Klass
[2] pry(main)* module Mod
[2] pry(main)* def self.included(base)
[2] pry(main)* base.extend ClassMethods
[2] pry(main)* end
[2] pry(main)* module ClassMethods
[2] pry(main)* def act_as_class_method
[2] pry(main)* puts "Im a class method now!!!"
[2] pry(main)* end
[2] pry(main)* end
[2] pry(main)* end
[2] pry(main)* end
=> nil
Now calling
Klass::Mod.act_as_class_method
results in the same error you had
NoMethodError: undefined method `act_as_class_method' for Klass::Mod:Module
from (pry):26:in `__pry__'
But if you subclass Klass and include Klass::Mod the included call back extends the ClassMethod module, letting you use the methods defined in ClassMethods as class methods
[4] pry(main)> class Example < Klass
[4] pry(main)* include Klass::Mod
[4] pry(main)* self.act_as_class_method
[4] pry(main)* end
=> Im a class method now!!!
=> nil
This took me a while to figure out at first, so don't feel bad and no, its not that simple or obvious.