6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

byebug と prepend で gem の中を探る

Last updated at Posted at 2015-10-19

モチベーション

rake db:migrate を実行するときに
ActiveRecord::ConnectionAdapters::Mysql2Adapter.initialize_schema_migrations_table がいったいどのようなタイミングで呼び出されるのか、知りたくなりました。

Rails 4.2.4 でのソースコードは https://github.com/rails/rails/blob/v4.2.4/activerecord/lib/active_record/migration.rb になるのですが、ちょっと追いづらい。

そこで prepend と byebug を使ってスタックトレースを表示してみることにしました。

実際のコード

config/initializers/ar_test.rb
ActiveSupport.on_load :active_record do
  module ActiveRecord::ConnectionAdapters
    module Mysql2AdapterExt
      def initialize_schema_migrations_table
        debugger
        super
      end
    end

    class Mysql2Adapter
      prepend Mysql2AdapterExt
    end
  end
end

prepend を使わずに、オープンクラスを使っても良かったのかもしれませんが、その後の実行もできるように今回は prepend にしてみました。

実行結果

rake db:migrate を実行してみます。

[1, 10] in /Users/../config/initializers/ar_test.rb
    1: ActiveSupport.on_load :active_record do
    2:   module ActiveRecord::ConnectionAdapters
    3:     module Mysql2AdapterExt
    4:       def initialize_schema_migrations_table
    5:         debugger
=>  6:         super
    7:       end
    8:     end
    9: 
   10:     class Mysql2Adapter
(byebug) 

無事に debugger を入れたところで止まります。ここで byebug の bt コマンドを使って、スタックトレースを表示してみます。

(byebug) bt
--> #0  ActiveRecord::ConnectionAdapters::Mysql2AdapterExt.initialize_schema_migrations_table at /Users/.../config/initializers/ar_test.rb:6
    #1  ActiveRecord::Migrator.initialize(direction#Symbol, migrations#Array, target_version#NilClass) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/activerecord-4.2.4/lib/active_record/migration.rb:922
    ͱ-- #2  Class.new(*args) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/activerecord-4.2.4/lib/active_record/migration.rb:820
    #3  #<Class:ActiveRecord::Migrator>.up(migrations_paths#Array, target_version#NilClass) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/activerecord-4.2.4/lib/active_record/migration.rb:820
    #4  #<Class:ActiveRecord::Migrator>.migrate(migrations_paths#Array, target_version#NilClass, &block#Proc) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/activerecord-4.2.4/lib/active_record/migration.rb:798
    #5  ActiveRecord::Tasks::DatabaseTasks.migrate at /Users/.../.rvm/gems/ruby-2.1.7@/gems/activerecord-4.2.4/lib/active_record/tasks/database_tasks.rb:137
    #6  block (2 levels) in <top (required)> at /Users/.../.rvm/gems/ruby-2.1.7@/gems/activerecord-4.2.4/lib/active_record/railties/databases.rake:44
    ͱ-- #7  Proc.call(*args) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/task.rb:240
    #8  block in Rake::Task.execute(args#Rake::TaskArguments) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/task.rb:240
    ͱ-- #9  Array.each at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/task.rb:235
    #10 Rake::Task.execute(args#Rake::TaskArguments) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/task.rb:235
    #11 block in Rake::Task.invoke_with_call_chain(task_args#Rake::TaskArguments, invocation_chain#Rake::InvocationChain::EmptyInvocationChain) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/task.rb:179
    #12 MonitorMixin.mon_synchronize at /Users/.../.rvm/rubies/ruby-2.1.7@/lib/ruby/2.1.0/monitor.rb:211
    #13 Rake::Task.invoke_with_call_chain(task_args#Rake::TaskArguments, invocation_chain#Rake::InvocationChain::EmptyInvocationChain) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/task.rb:172
    #14 Rake::Task.invoke(*args#Array) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/task.rb:165
    #15 Rake::Application.invoke_task(task_string#String) at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:150
    #16 block (2 levels) in Rake::Application.top_level at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:106
    ͱ-- #17 Array.each at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:106
    #18 block in Rake::Application.top_level at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:106
    #19 Rake::Application.run_with_threads at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:115
    #20 Rake::Application.top_level at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:100
    #21 block in Rake::Application.run at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:78
    #22 Rake::Application.standard_exception_handling at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:176
    #23 Rake::Application.run at /Users/.../.rvm/gems/ruby-2.1.7@/gems/rake-10.4.2/lib/rake/application.rb:75
    #24 <main> at /Users/.../bin/rake:4
(byebug)

よく理解できました。あとは byebug の c コマンドを使えば、そのまま実行を継続できます。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?