LoginSignup
4
4

More than 5 years have passed since last update.

Symbol.all_symbols.include?は常に真を返すこととその回避策

Last updated at Posted at 2015-03-18

現象

Symbol.all_symbols.include? :hogefugafoobar
# => true

!?
これではシンボルが実行環境に存在するかどうか確認できない…

理由

include?の引数が評価されるタイミングで引数のシンボルが実行環境に登録されてしまうようです。

【追記】
正確には、スクリプトの構文解析のタイミングでシンボルテーブルにシンボルが追加されるようです。
【追記終わり】

回避策

【追記】
以下の方法はirbでのみ有効です。
【追記終わり】

シンボルが評価された時点で実行環境に登録されることは回避できないので、配列をfreezeすることで回避します。

symbols = Symbol.all_symbols.freeze
symbols.include? :hogefugahogefuga
# => false

【追記】
以下の方法は通常のスクリプトでも有効です。

シンボルとして構文解析させてはダメなので、直前まで文字列として評価されるような方法であればうまくいきます。例えば、

# 文字列をto_sym
Symbol.all_symbols,include? 'hogefoo'.to_sym
# => false

# 文字列をeval
eval 'Symbol.all_symbols,include? :foofoobarbar'
# => false

【追記終わり】

やったね!

4
4
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4