使用ruby-doc.org库,您如何确定是否需要或包含?

时间:2017-05-21 05:41:29

标签: ruby-on-rails ruby

使用带有红宝石的红宝石CSV library,您可以通过声明require 'csv'来使用该库,但在使用Math module时,您会声明include Math。两个图书馆都没有证明使用哪种声明。你是如何解决这个问题的,例如:使用include for module和require for a Class?如果是这种情况,为什么在模块的情况下你不需要文件?你如何计算文件名是'csv'而不是'CSV'?

这不是关于requireinclude的一般性问题,而是寻求有关如何解释ruby-doc.org文档以使用特定类或模块的信息。

1 个答案:

答案 0 :(得分:1)

正如JörgMittag已在我们的评论中指出:requireinclude正在做完全不同的事情并没有任何共同之处。它们彼此无关,也不可互换。

require加载文件(有关详细信息,请阅读docs)。 Ruby不会神奇地找到文件中定义的文件或模块/类。在外部文件中定义的每段代码都需要在执行代码之前加载文件并可以使用。

Ruby的核心模块(如Math - 请注意URL中的core)是自动需要的,因此您无需自己加载它们。但是如果你想使用标准库中的模块或类(如CSV)或外部gem,你需要自己需要它。这可能并不明显,因为像bundler这样的工具需要你的文件或者gem需要内部所需的所有其他文件。

所有 Ruby文件需要先加载才能使用。 require是加载Ruby文件的最常用方法。

想象一下,有一个名为foo.rb的文件如下所示:

puts 'loading file...'

def foo_loaded?
  true
end

module Foo
  def self.bar
    puts 'bar'
  end
end

在控制台中玩耍:

# `foo` wasn't required yet
> foo_loaded?
#=> NoMethodError: undefined method `foo_loaded?' for main:Object
> Foo
#=> NameError: uninitialized constant Foo

# It doesn't find the file if it ist not in the current $LOAD_PATH
require 'foo' 
#=> LoadError: cannot load such file -- foo

# It loads and executes (see the output from `puts`) the file when found
> require './foo'
#=> loading file...
#=> true

# Now we can start using the methods and modules defined in the file
> foo_loaded?
#=> true
> Foo
#=> Foo
> Foo.bar
#=> bar

没有必要include任何事情。文件中定义的所有内容都可以立即用于Ruby。不需要为该文件命名,使其与内部的模块,类或方法匹配。但是,通过内容命名文件是一种常见的模式和良好做法。

include在文件级别上不起作用,但在语言级别上起作用。它基本上从模块中获取所有方法,并将它们包含在另一个模块或类中。顺便说一句:如果你要包含的模块是在外部文件中定义的,那么你需要先要求该文件,否则Ruby甚至不会知道该模块是否存在而且不能包含它。

想象一下这样的模块和类结构:

module Bar
  def bar
    puts 'bar'
  end
end

class Foo
end

Foo.new.bar
#=> NoMethodError: undefined method `bar' for #<Foo:...

# Bar is not related to Foo
Foo.ancestors
#=> [Foo, Object, Kernel, BasicObject]

当我们include Bar进入Foo时:

module Bar
  def bar
    puts 'bar'
  end
end

class Foo
  include Bar
end

Foo.new.bar
#=> bar

# Bar is now a superclass of Foo
Foo.ancestors
#=> [Foo, Bar, Object, Kernel, BasicObject]

注意事项:在此示例中无需使用require,因为模块和类都在同一文件中定义。 include使模块不是定义文件或模块名称的字符串。

因为include做了一件非常特别的事情,所以要问:在使用之前我是否需要要求或包含X?或者:我怎么知道什么包含?之后不需要包含任何内容:gem可能只提供直接使用的类/模块,或者它可能包含其功能本身。这取决于模块的设计和目的。如果不阅读文档或源代码,您无法分辨。

tl:dr

  • requireinclude完全不同。
  • Ruby文件在使用前必须为loadedrequire是加载Ruby文件的一种方法。
  • include包括从模块到当前模块/类的方法。
  • 您必须阅读有关如何使用库的文档,不仅有一种方法可以实现。