경고없이 Ruby 상수를 재정의하는 방법은 무엇입니까?
날짜가 변경 될 때마다 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?
-
Steve 덕분에 해결책 :
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
And as an example of using it
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
Gives the following output
Foo is ABC
Bar is DEF
Foo is GHI
Bar is JKL
Forgive me if i've broken any ruby taboos here as I am still getting my head around some of the Module:Class:Eigenclass structure within Ruby
If you want to redefine a value then don't use constants, use a global variable instead ($tau = 2 * Pi), but that's not a good practice too. You should make it an instance variable of a suitable class.
For the other case, Tau = 2 * Pi unless defined?(Tau) is perfectly alright and the most readable, therefore the most elegant solution.
Another approach, using $VERBOSE, to suppress warnings, is discussed here: http://mentalized.net/journal/2010/04/02/suppress_warnings_from_ruby/
Unless the values of the constants are pretty weird (i.e. you have constants set to nil or false), the best choice would be to use the conditional assignment operator: Tau ||= 2*Pi
This will set Tau to 2π if it is nil, false or undefined, and leave it alone otherwise.
ReferenceURL : https://stackoverflow.com/questions/3375360/how-to-redefine-a-ruby-constant-without-warning
'Program Club' 카테고리의 다른 글
| IE8에서 호환성보기를 사용하지 * 않도록 * 강제 (0) | 2021.01.08 |
|---|---|
| 자신을 피클하는 방법? (0) | 2021.01.08 |
| io 리디렉션을 사용하지 않고 명령 줄에서 파일에 텍스트 추가 (0) | 2021.01.08 |
| 1024 미만의 포트에 권한이 부여되는 이유는 무엇입니까? (0) | 2021.01.08 |
| 플라스크에서 g.user global을 사용하는 방법 (0) | 2021.01.08 |