Sorceryのコードを読んでみる
Sorceryの過去のバグ修正を見かけた時にoptions
の定義場所が分からなかったので調べてみた。
def tableized_model_class
options[:model] ? options[:model].gsub(/::/, '').tableize : 'users'
end
Sorceryにはソースコードのgeneratorがあり、自動でいくつかのファイルを作成してくれるのだが、その際に渡したオプションをテーブル名に変換するメソッドっぽい。
Sorcery内
上のファイル/lib/generators/sorcery/helpers.rb
内をチェックしたところ、他にoptions
という変数やメソッドは定義されていなかった。
options[:model]
はHelpers
というmoduleの中に定義されていたので、Helpers
を利用している箇所を調べてみる。
唯一/lib/generators/sorcery/install_generator.rb
の中でだけincludeされ利用されていた。
このファイルの中でも同様にoptions[:migrations]
のようにoptions
が利用されているが、定義は存在しない。
moduleをincludeしているクラスはInstallGenerator
であり、このクラスはRails::Generators::Base
を継承しているので、options
の定義はSorcery内ではなくRails側にありそう
Rails内
Rails::Generators::Base
クラスはここに定義はされている
が、ここでもoptions
は利用されているだけであり、定義されてないので、さらに継承ツリーを辿る。
class Base < Thor::Group
とある通り、Rails::Generators::Base
はThor
というgemのGroupクラスを継承していた。
ここでThorについて軽く調べると、CLI作成時に利用できるgemらしいというのがわかった。
Thor内
上でRails::Generators::Base
が継承していたGroupクラスはここにあった
が、この中でもoptions
について定義している箇所はない。
そしてThor::Group
は他のクラスを継承していない(正確には書かれていないだけでObject
クラスを継承している)
よく見ると、かなり下の方でinclude Thor::Base
という記述があり、Baseモジュールをincludeしていたので確認してみる。
35行目に
attr_accessor :options, :parent_options, :args
という記述があった。おそらくこれ?
※ attr_accessor
って何だ? という人へ
Thor::Base
のドキュメントにはoptions
インスタンスメソッドについて記載がある
まとめ
SorceryはRailsを継承していて、さらにRailsはThorを継承していて、そのThorの中に定義されていた。
1. 一番最初に書いたoptions
があるモジュールは、SorceryのInstallGenerator
クラスが唯一includeしている
2. SorceryのInstallGenerator
はRailsのRails::Generators::Base
クラスを継承している
3. Rails::Generators::Base
はThorのThor::Group
クラスを継承している
4. Thor::Group
はThor::Base
モジュールをincludeしている
5. Thor::Base
の中で、options
が定義されていた。
optionsメソッドは何をしているのか?
CLIのオプションで設定した値を取得できる。
Railsガイドに詳しく書かれているので以下引用
Railsのジェネレータは、カスタムのコマンドライン引数を与えることで簡単に挙動を変更できます。この機能はThorを利用しています。
class_option :scope, type: :string, default: 'read_products'
これで、ジェネレータを以下のように呼び出せます。
rails generate initializer --scope write_products
このコマンドライン引数は、ジェネレータクラス内ではoptionsメソッドでアクセスできます。
@scope = options['scope']
thanks
分からない箇所はstack overflowで@nekketsuuuさんがサポートしてくださいました。
その他
まだ理解しきれておらず、もしかしたら間違えているかもしれないので何かあればコメント頂ければ幸いです
Discussion