ランプの中身(Ruby on Railsのシステム開発)
ランプの中身(Ruby on Railsのシステム開発)では、株式会社ケイビーエムジェイのRuby on Railsエンジニアが蓄積したノウハウを公開しています。Ruby on Railに関する技術解説や実践的なノウハウなど、開発現場の技術に則したコンテンツを随時追加していきます。 初心者の方でもわかりやすい技術解説を心がけています。リクエスト、ご質問も受け付けいますので、ご気軽にコメントを記述して下さい。

< Scaffoldはどこからくるの? 前編... | メイン | Linuxとかのbashで使えるショート... >

zenpouの中身(Ruby
2008.01.29

Scaffoldはどこからくるの? 後編


こんにちは。
KBMJのエンジニアの高瀬です。

大分間が空いてしまいましたが、前回の続きを書く事にします。
前回は、http://doruby.kbmj.com/zenpou_on_rails/20071227/Scaffold___

前回はscaffoldを作って以下の様なファイルが出来ました。


     create  app/views/members
      create  app/views/members/index.html.erb
      create  app/views/members/show.html.erb
      create  app/views/members/new.html.erb
      create  app/views/members/edit.html.erb
      create  app/views/layouts/members.html.erb
      create  public/stylesheets/scaffold.css
      create    app/models/member.rb
      create    test/unit/member_test.rb
      create    test/fixtures/members.yml
      create    db/migrate
      create    db/migrate/001_create_members.rb
      create  app/controllers/members_controller.rb
      create  test/functional/members_controller_test.rb
      create  app/helpers/members_helper.rb

こちら、どこから来るのかを調べて行こうと思います。

結論を先に述べると、以下のパスにテンプレートが存在します。
{railsのインストール先}/lib/rails_generator/generators/components/scaffold/
これがどのような仕組みになっているかを追いかけて行きます。

前回、scaffoldは以下のコマンドによって生成されました。

      ruby script/generate scaffold Member name:string discription:text birthday:datetime

rubyの構文はruby --helpによって出してみたところ
    Usage: ruby [switches] [--] [programfile] [arguments]

      -0[octal]       specify record separator (\0, if no argument)
      -a              autosplit mode with -n or -p (splits $_ into $F)
      -c              check syntax only
      -Cdirectory     cd to directory, before executing your script
      -d              set debugging flags (set $DEBUG to true)
      -e 'command'    one line of script. Several -e's allowed. Omit [programfile]
      -Fpattern       split() pattern for autosplit (-a)
      -i[extension]   edit ARGV files in place (make backup if extension supplied)
      -Idirectory     specify $LOAD_PATH directory (may be used more than once)
      -Kkcode         specifies KANJI (Japanese) code-set
      -l              enable line ending processing
      -n              assume 'while gets(); ... end' loop around your script
      -p              assume loop like -n but print line also like sed
      -rlibrary       require the library, before executing your script
      -s              enable some switch parsing for switches after script name
      -S              look for the script using PATH environment variable
      -T[level]       turn on tainting checks
      -v              print version number, then turn on verbose mode
      -w              turn warnings on for your script
      -W[level]       set warning level; 0=silence, 1=medium, 2=verbose (default)
      -x[directory]   strip off text before #!ruby line and perhaps cd to directory
      --copyright     print the copyright
      --version       print the version


となっています。
今回の場合、

 

      "script/generate"[

 

がprogramfileで

 

      "scaffold Member name:string discription:text birthday:datetime"

がargumentsになります。


というわけで、プログラムファイルの内容を見て見ましょう。
script/generateの中身はこんな内容になっています。

 

      #!/usr/bin/env ruby
      require File.dirname(__FILE__) + '/../config/boot'
      require 'commands/generate'


require は、ライブラリの呼び出しを行います。
ここで、

 

      require File.dirname(__FILE__) + '/../config/boot'


は、プロジェクトのrailsの呼び出しを行っているRailsの基本的な所ですので、

 

      require 'commands/generate'


を見てみる事にします。
{Railsのインストール先}/lib/commands/generate.rb
を参照しましょう。

 

      require "#{RAILS_ROOT}/config/environment"
      require 'rails_generator'
      require 'rails_generator/scripts/generate'
      
      ARGV.shift if ['--help', '-h'].include?(ARGV[0])
      Rails::Generator::Scripts::Generate.new.run(ARGV)


Railsのenvironment(環境の設定等)を呼び出し、rails_generatorとrails_generator/scripts/generateを呼び出して、
います。

ちょっと文章がソースばかりになるので、省略しますが、

 

      require 'rails_generator'


のrails_generator.rbにて、

 

      require 'rails_generator/base'
      require 'rails_generator/lookup'
      require 'rails_generator/commands'
      require 'rails_generator/simple_logger'


など、generatorのファイルを呼び出しています。
そして、lookupによって下記のフォルダにあるファイルをgeneratorのコマンドに取り込んでいます。

 

      #{::RAILS_ROOT}/lib/generators
      #{::RAILS_ROOT}/vendor/generators
      #{::RAILS_ROOT}/vendor/plugins/*/**/generators
      #{::RAILS_ROOT}/vendor/plugins/*/**/rails_generators
      #{Dir.user_home}/.rails/generators
      #{File.dirname(__FILE__)}/generators/components


そして実行段階。/lib/commands/generate.rbの中で実行されていたrunコマンドを見てみます。

 

      Rails::Generator::Scripts::Generate.new.run(ARGV)


クラス名Rails::Generator::Scripts::Generateなのでrails_generator/scripts/generate.rbを見に行きます。
/lib/commands/generate.rbで3行目でrequireされてましたね。
見てみると

 

      require File.dirname(__FILE__) + '/../scripts'
      
      module Rails::Generator::Scripts
        class Generate < Base
          mandatory_options :command => :create
        end
      end

 

というコードになっています。
run呼び出してるのにrunがない……。
Rails::Generator::Scriptsを拡張してるみたいです。
いったりきたりで大変ですね。

というわけでrails_generator/scripts.rbにいきます。

 

        def run(args = [], runtime_options = {})
          begin
            parse!(args.dup, runtime_options)
          rescue OptionParser::InvalidOption => e
            # Don't cry, script. Generators want what you think is invalid.
          end

          # Generator name is the only required option.
          unless options[:generator]
            usage if args.empty?
            options[:generator] ||= args.shift
          end

          # Look up generator instance and invoke command on it.
          Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke!
        rescue => e
          puts e
          puts "  #{e.backtrace.join("\n  ")}\n" if options[:backtrace]
          raise SystemExit
        end

長いのでrunのコードだけ採用しています。
Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke!
にてジェネレータを見つけ、lookupでロードしたgenaratorの manifestを呼び出しています。
ここに関するコマンドはlib/rails_generator/commands.rbなどに定義されているのでそこから掘っていってください。

というわけで、送った"scaffold Member name:string discription:text birthday:datetime"の最初のscaffoldの指定により、
scaffoldを呼び出します。

ということで、lookupの中のソースコード一覧の中で、scaffoldのソースコードが存在するのは
{railsのインストール先}/lib/rails_generator/generators/components/scaffold/
でしたので、scafolldはここから来ている事がわかりました。

今回、
Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke!
を検索している際、ヒットした
http://d.hatena.ne.jp/elm200/20070718/1184736852を途中から参考にさせていただきました。

というか、既にこちらのエントリがあったという事で、今回のエントリは二番煎じだったかな……と思いましたが、

 

とりあえず後悔公開CHUです。

コメント (0)  |トラックバック (0)

ブックマークに追加する Subscribe with livedoor Reader あとで読む

トラックバック URL

この記事にコメントする

ニックネーム:
メールアドレス:
URL:


KBMJのWebソリューション
Ruby on Rails Summer Festival 2008開催決定!!

TOPICS

2008/06/25
ZD Net Builder」の連載記事です。第四回は「Rubyでどう書く?:重複したRSSをまとめる」が掲載されました。

2008/05/30
ZD Net Builder」の連載記事です。第三回は「Rubyでどう書く?:Rubyで特定URLの画像パス一覧を表示する」が掲載されました。

2008/05/07
ZD Net Builder」に連載を始めました。第二回は「Rubyでどう書く?:RubyでPDF履歴書を作成する」が掲載されました。

2008/04/24
アットマーク・アイティ」に『 Rubyを使ってPaSoRi経由でSuicaの乗車履歴を取得し、GoogleMapsやGoogleEarthで表示する』が掲載されました。

全体のRoR最新ブログ一覧

プロフィール

  • zenpou
  • 1. 名前: たかせゆういち
    2. blog: http://d.hatena.ne.jp/zenpou
    3. 年齢: 24くらい

    Railsについて

    1. KBMJでRailsの開発をやっています。
    2. 小江戸らぐというユーザーグループで、毎月Railsの勉強会の講師をしています。。

    開発環境とか

    1. Windows Vista(ノート) と Windows XP(デスクトップ)を2台並べてます。(synergyで連動)
    2. でも、実際に開発する場合、ネットに繋がってたらLinuxにPuttyで接続して開発。
    3. ネットに繋がってない場所だと、ローカルのcoLinux上にPuttyで接続して開発。
    4. 開発に使うLinuxは、ディストリは余り気にしないけど、debianとCentOSとFedora。
    5. Linux上でzsh + screen で開発します。screenで画面切り替えながらログをtail -fしたり、ruby script/consoleしたり、mysqlしたり。
    6. エディタはvim使ってます。

ブログの購読

RSS

timelog
株式会社ケイビーエムジェイロゴ