如何在加载文件时禁用重新定义常量的警告

发布于 2025-01-04 07:44:47 字数 45 浏览 1 评论 0原文

有没有办法在加载特定文件时禁用警告:已初始化常量

Is there a way to disable warning: already initialized constant when loading particular files?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

感性 2025-01-11 07:44:47

问题的解决方案取决于问题的原因。

1 - 您正在更改代码中某个位置之前设置的常量的值,或者尝试定义与现有类或模块同名的常量。解决办法:如果事先知道常量的值会改变,就不要使用常量;不要定义与类/模块同名的常量。

2 - 您处于这样一种情况,您想要出于充分的理由重新定义常量,而不会收到警告。有两种选择。

首先,您可以在重新定义常量之前取消定义该常量(这需要一个辅助方法,因为 remove_const 是一个私有函数):

Object.module_eval do
  # Unset a constant without private access.
  def self.const_unset(const)
    self.instance_eval { remove_const(const) }
  end
end

或者,您可以直接告诉 Ruby 解释器关闭(这会抑制 所有警告):

# Runs a block of code without warnings.
def silence_warnings(&block)
  warn_level = $VERBOSE
  $VERBOSE = nil
  result = block.call
  $VERBOSE = warn_level
  result
end

3 - 您需要一个外部库来定义一个类/模块,其名称与您正在创建的新常量或类/模块发生冲突。解决方案:将代码包装在顶级模块命名空间中以防止名称冲突。

class SomeClass; end
module SomeModule
   SomeClass = '...' 
end

4 - 与上面相同,但是您绝对需要定义一个与 gem/library 的类同名的类。解决方案:您可以将库的类名分配给一个变量,然后将其清除以供以后使用:

require 'clashing_library'
some_class_alias = SomeClass
SomeClass = nil
# You can now define your own class:
class SomeClass; end
# Or your own constant:
SomeClass = 'foo'

The solution to your problem depends on what is causing it.

1 - You are changing the value of a constant that was set before somewhere in your code, or are trying to define a constant with the same name as an existant class or module. Solution: don't use constants if you know in advance that the value of the constant will change; don't define constants with the same name as class/modules.

2 - You are in a situation where you want to redefine a constant for good reasons, without getting warnings. There are two options.

First, you could undefine the constant before redefining it (this requires a helper method, because remove_const is a private function):

Object.module_eval do
  # Unset a constant without private access.
  def self.const_unset(const)
    self.instance_eval { remove_const(const) }
  end
end

Or, you could just tell the Ruby interpreter to shut up (this suppresses all warnings):

# Runs a block of code without warnings.
def silence_warnings(&block)
  warn_level = $VERBOSE
  $VERBOSE = nil
  result = block.call
  $VERBOSE = warn_level
  result
end

3 - You are requiring an external library that defines a class/module whose name clashes with a new constant or class/module you are creating. Solution: wrap your code inside a top-level module-namespace to prevent the name clash.

class SomeClass; end
module SomeModule
   SomeClass = '...' 
end

4 - Same as above, but you absolutely need to define a class with the same name as the gem/library's class. Solution: you can assign the library's class name to a variable, and then clear it for your later use:

require 'clashing_library'
some_class_alias = SomeClass
SomeClass = nil
# You can now define your own class:
class SomeClass; end
# Or your own constant:
SomeClass = 'foo'
陌生 2025-01-11 07:44:47

试试这个:

Kernel::silence_warnings { MY_CONSTANT = 'my value '}

Try this :

Kernel::silence_warnings { MY_CONSTANT = 'my value '}
倾城花音 2025-01-11 07:44:47

要抑制警告,请在脚本顶部使用以下代码:

$VERBOSE = nil

To suppress warnings, use the following code at the top of the script:

$VERBOSE = nil
紫竹語嫣☆ 2025-01-11 07:44:47

这个问题的接受答案很有帮助。我查看了 Rails 源代码,得到了以下信息。在加载文件之前和之后,我可以插入这些行:

# Supress warning messages.
original_verbose, $VERBOSE = $VERBOSE, nil
    load(file_in_question)
# Activate warning messages again.
$VERBOSE = original_verbose

The accepted answer to this question was helpful. I looked at the Rails source to get the following. Before and after loading the file, I can insert these lines:

# Supress warning messages.
original_verbose, $VERBOSE = $VERBOSE, nil
    load(file_in_question)
# Activate warning messages again.
$VERBOSE = original_verbose
愁杀 2025-01-11 07:44:47

使用user2398029的回复对我来说删除警告的最简单方法是添加这一行:

before { described_class.instance_eval { remove_const(:CONSTANT_NAME) } }

Using user2398029's reply the simplest way for me to remove warnings was to add this line:

before { described_class.instance_eval { remove_const(:CONSTANT_NAME) } }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文