メソッドが定義されているか確認したい場合のdefined? | rails commit log流し読みを読んでみた

f:id:sktktk1230:20180726121250p:plain

1. 概要

@y_yagiさんのrails commit log流し読みを読んでいてわからなかったこと調べてみました

2. 読んだエントリ

y-yagi.hatenablog.com

3. わからなかったこと

PRの中の処理に書かれていたdefined? ってなんだろう?

対象のPR

github.com

記述内容

def config_target_version
  defined?(@config_target_version) ? @config_target_version : Rails::VERSION::STRING.to_f
end

4. 調べてみた

defined?が分からなかった為、どんなメソッドなのか調べてみました

文法:
defined?

式が定義されていなければ、偽を返します。定義されていれば式の種別 を表す文字列を返します。

定義されていないメソッド、undef されたメソッド、Module#remove_method により削除されたメソッドのいずれに対しても defined? は偽を返します。

特別な用法として以下があります。

defined? yield

yield の呼び出しが可能なら真(文字列 "yield")を返します。 Kernel.#block_given? と同様にメソッドがブロック付きで呼ばれたか を判断する方法になります。

defined? super

super の実行が可能なら真(文字列 "super")を返します。

defined? a = 1
p a # => nil

引用:Rubyリファレンス2.5.0:defined?

式が定義されているかを確認するメソッドのようです
式が定義されていない場合は、nilを戻り値とします
定義されている場合の戻り値は以下となります

以下は、defined? が返す値の一覧です。

  • "super"
  • "method"
  • "yield"
  • "self"
  • "nil"
  • "true"
  • "false"
  • "assignment"
  • "local-variable"
  • "local-variable(in-block)"
  • "global-variable"
  • "instance-variable"
  • "constant"
  • "class variable"
  • "expression"

引用:Rubyリファレンス2.5.0:defined?

5. ちょっと思ったこと

こんな書き方

def config_target_version
  @config_target_version || Rails::VERSION::STRING.to_f
end

もありなのかなと思ったのですが、 defined? は式が定義されている場合のみ戻り値があるので、 少し挙動が変わってしまうので、同じ動きはしないので、これはダメそうでした