Rails.env.production?の正体
2022/01/20
環境によって処理を分ける時によく使う Rails.env.production?
だったり、Rails.env.development?
ってやつ
Rails.env.production?
#=> true
タイポしてもエラーにならないから、何事だ!と思い少し調べた
Rails.env.productio?
#=> false
そもそも String
じゃなかった
Rails.env
がただの Stirng
かと思ったら、ActiveSupport::EnvironmentInquirer
だった
Rails.env
#=> "production"
Rails.env.class
#=> ActiveSupport::EnvironmentInquirer
ActiveSupport::EnvironmentInquirer
とは
ごにょごにょ書いてあるけど、一旦ここでは ActiveSupport::StringInquirer
を継承しているとだけ
module ActiveSupport
class EnvironmentInquirer < StringInquirer # :nodoc:
DEFAULT_ENVIRONMENTS = ["development", "test", "production"]
def initialize(env)
super(env)
DEFAULT_ENVIRONMENTS.each do |default|
instance_variable_set :"@#{default}", env == default
end
end
DEFAULT_ENVIRONMENTS.each do |env|
class_eval "def #{env}?; @#{env}; end"
end
end
end
ActiveSupport::StringInquirer
とは
String
を継承して、method_missing
をオーバーライドしている
module ActiveSupport
class StringInquirer < String
private
def respond_to_missing?(method_name, include_private = false)
method_name.end_with?("?") || super
end
def method_missing(method_name, *arguments)
if method_name.end_with?("?")
self == method_name[0..-2]
else
super
end
end
end
end
最後に ?
が付く存在しないメソッドが呼ばれた時、 ?
の前までの文字列と自身の文字列が一致しているかを比較するようになっている
vehicle = ActiveSupport::StringInquirer.new('car')
#=> "car"
vehicle.car? # "car" == "car"
#=> true
vehicle.bike? # "car" == "bike"
#=> false
これが Rails.env.production?
の正体だった
補足
String#inquiry
メソッドとは
文字列をStringInquirerオブジェクトに変換するメソッド
Railsであればすぐに使える、Active Supportの String
拡張
'production'.inquiry.production?
#=> true
'production'.inquiry.class
#=> ActiveSupport::StringInquirer