2012-08-15 102 views
1

在Rails应用程序中,我想检查是否定义了一个常量,并在必要时自动加载它。 defined?运算符返回false直到自动加载发生。定义?用于自动加载类

defined? Foo # => false :(
Foo # => Foo 
defined? Foo # => true 

我目前的解决方法是这样的:

begin 
    Foo # try to autoload 
    true 
rescue NameError 
    false 
end 

是否有更好的方法来检查,如果一个常量的定义,但如果需要也自动加载它?


的理由要求:

为Rails的Konacha JS测试框架应自动拿起灯具ruby文件(如果存在)。加载应该在Rails的自动加载机制中发生,所以它受益于自动加载(使用config.cache_classes = false)。

+0

您可能会从解释*为什么*您试图执行此操作中受益。它可能会给你一个更好的答案。 – deefour 2012-08-15 16:52:00

+0

完成。 :) ......... – 2012-08-15 17:14:16

回答

1

听起来好像您正在尝试创建一个could_be_defined?方法,该方法尝试自动加载,然后按照您的指示返回truefalse

在您尝试使用它之前,无法确定某个类是否存在。这是高度动态语言的优势之一。不利因素是不确定性。

您的强制加载和测试方法是确定知道的唯一方法。一些模块可能不会通过autoload进行声明,但实际上可以根据需要生成。试图预测可能存在或可能不存在的东西最多是不可靠的。

+0

有趣,谢谢。在我的代码中仍然困扰着我的是NameError过于广泛的救援。如果加载'Foo'会导致模块定义中的某个NameError,它将不会传播。我不确定是否有更好的方法(检查异常消息之后)。 – 2012-08-15 17:50:06

+0

如果加载模块导致异常,我不确定那是你的问题。这是一个错误。你不可能为此承担责任。 – tadman 2012-08-15 18:35:03

0

我有一个类似的问题,我根据约定加载推断的常量。我遇到的问题是,这些类的定义中的任何错误都被吞噬了。

我想出了这一点:

def const_presence(const_name) 
    const_name.constantize 
rescue NameError => e 
    raise e unless e.message =~ /uninitialized constant #{const_name}/ 
end 

这将返回零,如果没有定义的常量或常量,如果它是,但重要的是允许在加载后提出的不断遇到的任何错误。