直近のプロジェクトでは、Rails5を使っているのですが、利用しているgem関連で下記のような警告が大量に出力されるので、少し調べてみました。
(「./bin/rails c」や「./bin/bundle exec rspec」を実行すると大量に出力されます。)
DEPRECATION WARNING: alias_method_chain is deprecated.
これは、Rails5からはActiveSupportの「alias_method_chain」がdeprecatedになり、代わりに「Module#prepend」を使うように促しています。alias_method_chainとは
まず、deprecatedになった「alias_method_chain」ですが、下記のように利用します。
class HelloUser
def hello
puts 'Hello'
end
def hello_with_world
hello_without_world
puts 'World'
end
alias_method_chain :hello, :world
end
上記のコードは、「alias_method」を使った場合は、下記と同等になります。
class HelloUser
def hello
puts 'Hello'
end
def hello_with_world
hello_without_world
puts 'World'
end
alias_method :hello_without_world, :hello
alias_method :hello, :hello_with_world
end
helloメソッドがhello_with_worldメソッドに置き換わり、元々のhelloメソッドはhello_without_worldメソッドとして使えるようになります。実行結果を下記に記載しますが、置き換わっているのがわかると思います。
[1] pry(main)> hello_user = HelloUser.new
[2] pry(main)> hello_user.hello
Hello
World
[3] pry(main)> hello_user.hello_without_world
Hello
Module#prependとは
早速、「Module#prepend」の使い方ですが下記のように使います。
class HelloUser
def hello
puts 'Hello'
end
end
module HelloWithWorld
def hello
super
puts 'World'
end
end
HelloUser.prepend(HelloWithWorld)
prependされたHelloWithWorldモジュールは継承関係上で、HelloUserクラスより手前に位置することになり、helloメソッドを
オーバーライドしたような形になります。そのため、HelloWithWorldモジュールのメソッド内でsuperを呼び出すことで元々のメソッドを呼び出すことができます。
実行結果とancestorsメソッドで継承関係を表示しておきます。HelloWithWorldがHelloUserの前にあるのがわかると思います。
[1] pry(main)> hello_user = HelloUser.new
[2] pry(main)> hello_user.hello
Hello
World
[3] pry(main)> HelloUser.ancestors
=> [HelloWithWorld,
HelloUser,
ActiveSupport::ToJsonWithActiveSupportEncoder,
Object,
PP::ObjectMixin,
RequireAll,
ActiveSupport::Dependencies::Loadable,
JSON::Ext::Generator::GeneratorMethods::Object,
ActiveSupport::Tryable,
Kernel,
BasicObject]
モンキーパッチなどを書くときに利用することになると思います。(モンキーパッチなんて書かずに、githubにプルリクする方がよいですが)とりあえず、DEPRECATION WARNINGの出力をなくしたい
Rails5にしたものの、全てのgemに対して、この警告を消すための書き換えの対応をしていくのは大変。
ただ、この出力が目障りという方は、「config/application.rb」に下記を書けば、消すことができますが、自己責任でお願いしますね。
require_relative 'boot'
require 'rails/all'
# TODO: DEPRECATION WARNING: alias_method_chain is deprecated
ActiveSupport::Deprecation.silenced = true
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
...
...
deprecatedなメソッドは、今後のアップデートで利用できなくなることもありますので、しっかりと理解した上で利用し、可能であれば、置き換えていくようにしましょう。
0 件のコメント:
コメントを投稿