gem-thor でコマンドを外部で定義する

やりたかったこと

require "thor"

# 外部クラスでコマンドを定義する
class Hello
    desc "hello NAME", "hello to NAME"
    def hello name
        puts "Hello, #{name}"
    end
end

class CLI < Thor
    # 外部で定義したコマンドを include したい
    include Hello
end

CLI.start(%(hello homu))

上のコードのように外部で定義したコマンドを include で組み込むようなことをしたかった。
もちろん、上のコードではうまく動作しませんでした。

Thor::Group と register を使う

次のように Thor::Group を継承したクラスで処理を定義し、register メソッドで追加すればよいみたいです。

require "thor"

class Hello < Thor::Group
    # コマンドの引数を定義
    argument :name

    # このクラス内で定義したメソッドが上から順番に呼ばれる
    def hello
        puts "Hello, #{name}"
    end
end


class CLI < Thor
    # Hello クラスをサブコマンドとして追加する
    register Hello, "hello", "hello NAME", "hello to NAME"
end

argv = %w(hello homu)

CLI.start argv
# => Hello, homu

今回はサブコマンドを直接追加したかったので Thor::Group を使いましたが Thor を継承した場合はサブコマンドのサブコマンドみたいなのを定義することもできます。

参照