Rails チュートリアル 1章 勉強メモ9
Rails チュートリアルの勉強メモ
1章続き rails new 何やってんの?
create_config_files
271: def create_config_files => 272: build(:config) 273: end
いつもの
97: def config => 98: empty_directory "config" 99: 100: inside "config" do 101: template "routes.rb" 102: template "application.rb" 103: template "environment.rb" 104: template "secrets.yml" 105: template "cable.yml" unless options[:skip_action_cable] 106: template "puma.rb" unless options[:skip_puma] 107: template "spring.rb" if spring_install? 108: 109: directory "environments" 110: directory "initializers" 111: directory "locales" 112: end 113: end
- empty_directory は ディレクトリ作成
- inside は初めてなので読む
169: def inside(dir = "", config = {}, &block) => 170: verbose = config.fetch(:verbose, false) 171: pretend = options[:pretend] 172: 173: say_status :inside, dir, verbose 174: shell.padding += 1 if verbose 175: @destination_stack.push File.expand_path(dir, destination_root) 176: 177: # If the directory doesnt exist and we're not pretending 178: if !File.exist?(destination_root) && !pretend 179: require "fileutils" 180: FileUtils.mkdir_p(destination_root) 181: end 182: 183: if pretend 184: # In pretend mode, just yield down to the block 185: block.arity == 1 ? yield(destination_root) : yield 186: else 187: require "fileutils" 188: FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield } 189: end 190: 191: @destination_stack.pop 192: shell.padding -= 1 if verbose 193: end
- say_status は verbose が true なら詳細が表示されるのだろう
- @destination_stack に config が push
- 178: config が作られてなかったら mkdir するってこと?
empty_directory
で作ってるんじゃないのか・・・?(pretend は dry_run - 188: config に cd して yield
- template と directory をそれぞれ実行(directory は ディレクトリを作って中身を template
create_boot_file
- rails/generators/rails/app/app_generator.rb @ line 288 Rails::Generators::AppGenerator#create_boot_file: 287: def create_boot_file => 288: template "config/boot.rb" 289: end
- config/boot.rb を生成
create_active_record_files
- rails/generators/rails/app/app_generator.rb @ line 292 Rails::Generators::AppGenerator#create_active_record_files: 291: def create_active_record_files => 292: return if options[:skip_active_record] 293: build(:database_yml) 294: end
- skip_active_record なら skip
- rails/generators/rails/app/app_generator.rb @ line 155 Rails::AppBuilder#database_yml: 154: def database_yml => 155: template "config/databases/#{options[:database]}.yml", "config/database.yml" 156: end
- options[:database] は設定しているデータベース(例: "database"=>"sqlite3"
create_db_files
- rails/generators/rails/app/app_generator.rb @ line 297 Rails::Generators::AppGenerator#create_db_files: 296: def create_db_files => 297: return if options[:skip_active_record] 298: build(:db) 299: end
- rails/generators/rails/app/app_generator.rb @ line 159 Rails::AppBuilder#db: 158: def db => 159: directory "db" 160: end
- db ディレクトリ以下を生成
create_lib_files
- rails/app/app_generator.rb @ line 302 Rails::Generators::AppGenerator#create_lib_files: 301: def create_lib_files => 302: build(:lib) 303: end
- rails/app/app_generator.rb @ line 163 Rails::AppBuilder#lib: 162: def lib => 163: empty_directory "lib" 164: empty_directory_with_keep_file "lib/tasks" 165: empty_directory_with_keep_file "lib/assets" 166: end
- lib 以下を生成
create_log_files, create_public_files, create_test_files, create_system_test_files, create_tmp_files, create_vendor_files
def log empty_directory_with_keep_file "log" end def public_directory directory "public", "public", recursive: false end def test empty_directory_with_keep_file "test/fixtures" empty_directory_with_keep_file "test/fixtures/files" empty_directory_with_keep_file "test/controllers" empty_directory_with_keep_file "test/mailers" empty_directory_with_keep_file "test/models" empty_directory_with_keep_file "test/helpers" empty_directory_with_keep_file "test/integration" template "test/test_helper.rb" end def system_test empty_directory_with_keep_file "test/system" template "test/application_system_test_case.rb" end def tmp empty_directory_with_keep_file "tmp" empty_directory "tmp/cache" empty_directory "tmp/cache/assets" end def vendor empty_directory_with_keep_file "vendor" unless options[:skip_yarn] template "package.json" end end
- 他も全部同じような感じ
- skip_yarn なら package.json は skip
delete_app_assets_if_api_option, delete_app_helpers_if_api_option, delete_application_layout_file_if_api_option, delete_public_files_if_api_option
def delete_app_assets_if_api_option if options[:api] remove_dir "app/assets" remove_dir "lib/assets" remove_dir "tmp/cache/assets" end end def delete_app_helpers_if_api_option if options[:api] remove_dir "app/helpers" remove_dir "test/helpers" end end def delete_application_layout_file_if_api_option if options[:api] remove_file "app/views/layouts/application.html.erb" end end def delete_public_files_if_api_option if options[:api] remove_file "public/404.html" remove_file "public/422.html" remove_file "public/500.html" remove_file "public/apple-touch-icon-precomposed.png" remove_file "public/apple-touch-icon.png" remove_file "public/favicon.ico" end end
残りの delete 系
- delete_js_folder_skipping_javascript - delete_assets_initializer_skipping_sprockets - delete_application_record_skipping_active_record - delete_action_mailer_files_skipping_action_mailer - delete_action_cable_files_skipping_action_cable - delete_non_api_initializers_if_api_option - delete_api_initializers - delete_new_framework_defaults - delete_bin_yarn_if_skip_yarn_option
- 今回は skip true なものはないためほとんど skip
- delete_api_initializers と delete_new_framework_defaults は api = false だと実行
def delete_api_initializers unless options[:api] remove_file "config/initializers/cors.rb" end end def delete_new_framework_defaults unless options[:update] remove_file "config/initializers/new_framework_defaults_5_1.rb" end end
- 内容はどちらも remove_file
finish_template
- rails/app/app_generator.rb @ line 418 Rails::Generators::AppGenerator#finish_template: 416: def finish_template 417: binding.pry => 418: build(:leftovers) 419: end
- leftovers, 追えなかった
- grep しても見つからず・・・
- 出力も特にないのでわからない
apply_rails_template
- rails/generators/app_base.rb @ line 163 Rails::Generators::AppBase#apply_rails_template: 161: def apply_rails_template # :doc: => 162: apply rails_template if rails_template 163: rescue Thor::Error, LoadError, Errno::ENOENT => e 164: raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}" 165: end
run_bundle
- rails/generators/app_base.rb @ line 417 Rails::Generators::AppBase#run_bundle: 415: def run_bundle => 416: bundle_command("install") if bundle_install? 417: end
- bundle_install? = true なので
bundle install
を実行
run_webpack
- rails/generators/app_base.rb @ line 421 Rails::Generators::AppBase#run_webpack: 419: def run_webpack => 420: if !(webpack = options[:webpack]).nil? 421: rails_command "webpacker:install" 422: rails_command "webpacker:install:#{webpack}" unless webpack == "webpack" 423: end 424: end
!(webpack = options[:webpack]).nil?
が false なので skip
generate_spring_binstubs
- rails/generators/app_base.rb @ line 428 Rails::Generators::AppBase#generate_spring_binstubs: 426: def generate_spring_binstubs => 427: if bundle_install? && spring_install? 428: bundle_command("exec spring binstub --all") 429: end 430: end
bundle exec spring binstub --all
を実行
run_after_bundle_callbacks
- 最後のメソッド
- これを実行してついに rails new は終わり
rails/app/app_generator.rb @ line 424 Rails::Generators::AppGenerator#run_after_bundle_callbacks: 423: def run_after_bundle_callbacks => 424: @after_bundle_callbacks.each(&:call) 425: end
&:call
は { |after_bundle_callback| after_bundle_callback.call } 的な意らしい?(違ってたら教えてください- @after_bundle_callbacks = [] なのでなしってこと?
at_exit
- ここ以降は exit 処理だと思います
- 一応追えるとこまで追いましたがよくわからなかった
- concurrent/utility/at_exit.rb @ line 49 Concurrent::AtExitImplementation#install: # install `Kernel#at_exit` callback to execute added handlers 46: def install 47: synchronize do 48: @installed ||= begin => 49: at_exit { runner } 50: true 51: end 52: self 53: end 54: end
- concurrent-ruby、並行処理 gem らしい
- @after_bundle_callbacks.each(&:call) これが並行処理なのかも (each(&:call) だし・・・(違ってたらry
- ちなみに Thread.list してみたが Thread は最初のスレッドひとつだった
[2] pry(#<Rails::Generators::AppGenerator>)> Thread.list => [#<Thread:0x00007ff5f705bfa0 run>]
at_exit { runner }
- 実行しているスレッドに
Kernel#at_exit
callback を実行するハンドラを入れる?
- 実行しているスレッドに
runnner
- concurrent/utility/at_exit.rb @ line 88 Concurrent::AtExitImplementation#runner: 87: def runner => 88: run if synchronize { @enabled } 89: end
- run は [ ]
- synchronize
- concurrent/synchronization/mutex_lockable_object.rb @ line 38 Concurrent::Synchronization::MutexLockableObject#synchronize: 37: def synchronize => 38: if @__Lock__.owned? 39: yield 40: else 41: @__Lock__.synchronize { yield } 42: end 43: end
- mutex 理解してないが 所有権を持っていないらしいので @Lock.synchronize { yield }
- @enabled は true のため run 実行
- run
- concurrent/utility/at_exit.rb @ line 69 Concurrent::AtExitImplementation#run: 68: def run => 69: handlers, _ = synchronize { handlers, @handlers = @handlers, {} } 70: handlers.each do |_, handler| 71: begin 72: handler.call 73: rescue => error 74: Concurrent.global_logger.call(ERROR, error) 75: end 76: end 77: handlers.keys 78: end
- @Lock.synchronize { yield }
- yield は handlers, @handlers = @handlers, {}
- { } を返している
- handlers = {} なので何事もなく終了?ってこと
- 流石にこのあたりは読めない・・・