日付が変わるたびにRubyファイルを評価するRubyコードを実行しています。ファイルには、次のような定数の定義があります
Tau = 2 * Pi
そして、もちろん、インタープリターに不要な「すでに初期化された定数」警告を毎回表示させるので、次の機能が必要です。
def_if_not_defined(:Tau, 2 * Pi)
redef_without_warning(:Tau, 2 * Pi)
このような定数定義をすべて書くことで、警告を回避できます。
Tau = 2 * Pi unless defined?(Tau)
しかし、それはエレガントではなく、少し濡れています( [〜#〜] dry [〜#〜] ではありません)。
def_if_not_defined
へのより良い方法はありますか?そして、どのようにredef_without_warning
?
-
スティーブのおかげで解決策:
class Object
def def_if_not_defined(const, value)
mod = self.is_a?(Module) ? self : self.class
mod.const_set(const, value) unless mod.const_defined?(const)
end
def redef_without_warning(const, value)
mod = self.is_a?(Module) ? self : self.class
mod.send(:remove_const, const) if mod.const_defined?(const)
mod.const_set(const, value)
end
end
A = 1
redef_without_warning :A, 2
fail 'unit test' unless A == 2
module M
B = 10
redef_without_warning :B, 20
end
fail 'unit test' unless M::B == 20
-
この質問は古いです。上記のコードはRuby 1.8にのみ必要です。 Ruby 1.9では、P3t3rU5の答えは警告を出さず、単に優れています。
次のモジュールはあなたが望むことをするかもしれません。そうでない場合、ソリューションへのポインタを提供する可能性があります
module RemovableConstants
def def_if_not_defined(const, value)
self.class.const_set(const, value) unless self.class.const_defined?(const)
end
def redef_without_warning(const, value)
self.class.send(:remove_const, const) if self.class.const_defined?(const)
self.class.const_set(const, value)
end
end
そして、それを使用する例として
class A
include RemovableConstants
def initialize
def_if_not_defined("Foo", "ABC")
def_if_not_defined("Bar", "DEF")
end
def show_constants
puts "Foo is #{Foo}"
puts "Bar is #{Bar}"
end
def reload
redef_without_warning("Foo", "GHI")
redef_without_warning("Bar", "JKL")
end
end
a = A.new
a.show_constants
a.reload
a.show_constants
次の出力を提供します
Foo is ABC
Bar is DEF
Foo is GHI
Bar is JKL
Ruby内のModule:Class:Eigenclass構造のいくつかについてまだ頭を悩ませているので、ここでRubyタブーを破った場合はご容赦ください
値を再定義し、定数を使用しない場合は、代わりにグローバル変数($ tau = 2 * Pi)を使用しますが、これも良い方法ではありません。適切なクラスのインスタンス変数にする必要があります。
その他の場合、Tau = 2 * Pi unless defined?(Tau)
は完全に問題なく、最も読みやすく、したがって最もエレガントなソリューションです。
警告を抑制するために$ VERBOSEを使用する別のアプローチについては、ここで説明します。 http://mentalized.net/journal/2010/04/02/suppress_warnings_from_Ruby/
定数の値が非常に奇妙でない限り(つまり、nil
またはfalse
に設定された定数がある場合)、最良の選択は条件付き代入演算子を使用することです:Tau ||= 2*Pi
これにより、Tauがnil
、false
、または未定義の場合は2πに設定され、それ以外の場合はそのままになります。