ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

rubyの定数が定義されているかをdefined?で確認して三項演算子に格納するときに()の有無でハマった

はじめに

チューニングパラメータとして別ファイルに定数を定義して、読み込むということはまぁよくある。

定義ファイルに定義されていればその値を入れ、定義がなければdefault値を使うというものだ。

動かしてみる

動作確認をしたrubyのversionは2.0

MacBook-Air:~ take$ ruby -v
ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin15]

三項演算子を使ってデフォルト値か定数値どちらかを変数に格納しようとしてみる。

irb(main):001:0> CONST = "hoge"
=> "hoge"
irb(main):002:0> name = defined? CONST ? CONST : "default"
=> "expression"

...expression??

defined? CONSTは"constance"を返すので、三項演算子を使わなければ素直に動く。

irb(main):001:0> CONST = "hoge"
=> "hoge"
irb(main):002:0> name = defined? CONST
=> "constant"

三項演算子が"expression"を返しているわけでもない。

irb(main):004:0> true ? "hoge" : "poge"
=> "hoge"

いろいろ試してみると、defined?で()をつけると正常に動いた。

irb(main):005:0> defined?(CONST) ? CONST : "default"
=> "hoge"

defined?の返却値

クラス/メソッドの定義 (Ruby 1.9.3)

大文字で始まるメソッド名に対しては () を明示しなければ定数の判定 を行ってしまいます。

これは関係ない気がする。

もしかしてdefinedで評価しているのが、defined? CONST ? CONST : "default"の場合defined? [CONST ? CONST : "default"] この部分だったりするのか。

irb(main):001:0> CONST = "hoge"
=> "hoge"
irb(main):002:0> CONST ? CONST : "default"
=> "hoge"
irb(main):003:0> defined?(CONST ? CONST : "default")
=> "expression"

なるほど、三項演算子は確かに式だ。。。

まとめ

rubyはちょいちょいこういう()の有無によって挙動が違うことがある気がする。極力()は使わないようにしているんだけどこういうのは困るなぁ。。。