method_missing
を定義するとRubocopに逮捕されるぞ!!
Rubyで method_missing
を定義すると、以下のようにRubocopに逮捕される。
このコードはLoggerをラップするコードで
- LoggerインスタンスをSingletonにしたい
- Loggerインスタンスを作る時に設定ファイルで制御したい
- クラスメソッドでログ出力したい
という目的で実装しています。なので Hound::Logger.debug('debug message')
とすればログ出力できます。
# LoggerクラスをWrapして使う
require 'logger'
module Hound
class Logger
@logger = nil
class << self
def logger
return @logger unless @logger.nil?
# 本来はここで config ファイルをロードして出力先やログレベルを変更する
# ここでは割愛
@logger = Logger.new(STDOUT)
@logger.level = :debug
@logger
end
def method_missing(method, *args)
if method =~ /^(debug|info|warn|error|fatal|unknown)$/
logger.send(method, *args)
else
super
end
end
end
end
end
この時、以下のようにRubocopに逮捕されてしまいます。
When using `method_missing`, define `respond_to_missing?`.Style/MissingRespondToMissing
method_missing
メソッドを定義する時には、合わせて respond_to_missing?
メソッドも定義しましょう、という内容です。
This cop checks for the presence of
method_missing
without also definingrespond_to_missing?
.
Class: RuboCop::Cop::Style::MissingRespondToMissing
修正されたコード
module Hound
class Logger
@logger = nil
class << self
# def logger は割愛
def respond_to_missing?(symbol, include_private)
return true if symbol =~ /^(debug|info|warn|error|fatal|unknown)$/
false
end
def method_missing(method, *args)
if method =~ /^(debug|info|warn|error|fatal|unknown)$/
logger.send(method, *args)
else
super
end
end
end
end
end
responde_to_missing?
メソッドを実装しましょう。コードの中身がなくてもRubocopのチェックはパスできます。でもちゃんと実装しましょう。
method_missing ってなに?