How to redefine a Ruby constant without warning?

后端 未结 4 1526
眼角桃花
眼角桃花 2020-12-23 15:57

I\'m running some Ruby code which evals a Ruby file every time its date changes. In the file, I have constant definitions, like

Tau = 2 * Pi
<
相关标签:
4条回答
  • 2020-12-23 16:36

    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.

    0 讨论(0)
  • 2020-12-23 16:40

    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.

    0 讨论(0)
  • 2020-12-23 16:44

    Another approach, using $VERBOSE, to suppress warnings, is discussed here: http://mentalized.net/journal/2010/04/02/suppress_warnings_from_ruby/

    Update 2020/5/6: In response to the comment that the link is now dead, I am pasting an example here from my old project, though I can't say whether and in what circumstances it is a good approach:

    original_verbose = $VERBOSE
    $VERBOSE = nil # suppress warnings
    # do stuff that raises warnings you don't care about
    $VERBOSE = original_verbose
    
    0 讨论(0)
  • 2020-12-23 16:47

    The following module may do what you want. If not it may provide some pointers to your solution

    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

    0 讨论(0)
提交回复
热议问题