在Ruby中使用类文件时,是否将'requires'语句放在文件的顶部或类定义中?
答案 0 :(得分:51)
从技术上讲,这并不重要。 require
只是一个普通的方法调用,它调用的范围不会影响它的工作方式。唯一不同的位置是,当它被放置的任何代码被评估时它将被执行。
实际上,您应该将它们置于最顶层,以便人们可以一目了然地看到文件的依赖关系。这是传统的地方。
答案 1 :(得分:21)
在顶部。
require 'rubygems'
require 'fastercsv'
class MyClass
# Do stuff with FasterCSV
end
答案 2 :(得分:14)
我可以看到没有在文件顶部放置require
的可能原因:加载昂贵并且不总是执行。我遇到的一种情况是,例如,代码及其测试位于同一个文件中,特别是对于小型库代码,我不时喜欢这样做。然后我可以从我的编辑器运行该文件并运行测试。在这种情况下,当文件从其他地方require
进入时,我不希望加载test/unit
。
有点像这样:
def some_useful_library_function()
return 1
end
if __FILE__ == $0
require 'test/unit'
class TestUsefulThing < Test::Unit::TestCase
def test_it_returns_1
assert_equal 1, some_useful_library_function()
end
end
end
答案 3 :(得分:10)
将它们放在哪里并不重要,但是如果你把它们放在里面一个class
或module
表达式,那么它看起来像是在导入任何东西在require
d文件中进入类的命名空间,这不是真的:一切都以全局命名空间(或者库中定义的任何命名空间)结束。
所以,最好把它们放在顶部以避免混淆。
答案 4 :(得分:4)
在文件的顶部,大多数(但不是全部)语言以这种方式处理导入。我发现它更清洁,更容易处理它们。
我认为这种方式才有意义......就像你在文件中途那样:
class Foo
def initialize(init_value)
@instance_var = init_value
# some 500 lines of code later....
end
end
class Bar
# oh look i need an import now!
require 'breakpoint'
正如您所看到的,跟踪它们非常困难。更不用说如果你想在你的代码中使用导入的函数 ,你可能需要回溯并再次包含它,因为另一个导入将特定于该类。导入相同的文件也会在运行时产生大量开销。
答案 5 :(得分:1)
我觉得 require 语句属于类。使用类意味着我们接受OOP的基本原则,即对象应尽可能松散耦合。对我来说意味着最小化外部依赖性。如果我稍后将一个类移动到它自己的文件中,我不想让它中断,因为我没有找到该类消耗的所有必要的 require 语句。
在文件中包含重复的 require 语句不会导致任何问题,并且它简化了继承您的代码的下一个程序员不可避免地会发生的重构。
答案 6 :(得分:0)
大多数答案建议将 require 语句放在文件顶部。但是,当需要嵌套的类/模块时,您可能需要考虑将它们放在类中(在顶部)。看这个例子:
# foo.rb
require './foo/bar'
class Foo < Struct.new(:name, :description)
def bar
Bar.new(self)
end
end
# foo/bar.rb
class Foo
class Bar < Struct.new(:foo)
end
end
irb:
require './foo'
# ...
# TypeError (superclass mismatch for class Foo)
发生这种情况是因为 Bar 嵌套在 Foo 内,并且需要通过将 Bar 类嵌套在内来进行定义。 Foo 类。但是,由于尚未定义 Foo ,因此现在是由嵌套结构定义的。成功要求 Bar 之后,我们现在尝试定义从另一个类继承的 Foo 类。由于 Foo 已经被定义(通过嵌套结构),并且继承只能在该类的初始定义上发生,因此此操作失败。因此提高:
TypeError(Foo类的超类不匹配)
只需在 Foo 类中移动require语句即可解决此问题。