0

With the ruby CSV library with ruby on rails, you use the library by declaring require 'csv', but when using the Math module, you declare include Math. Neither library documents which declaration to use. How do you work this out, e.g. use include for module and require for a Class? If that is the case, why do you not have to require a file in the case of a module? How do you work out the file name is 'csv' and not 'CSV'?

This is not a general question about require and include but is seeking information on how to interpret the ruby-doc.org documentation to use a particular class or module.

Obromios
  • 15,408
  • 15
  • 72
  • 127
  • Possible duplicate of [What is the difference between include and require in Ruby?](http://stackoverflow.com/questions/318144/what-is-the-difference-between-include-and-require-in-ruby) – Gerry May 21 '17 at 05:51
  • 1
    Your question is very unclear: `require` and `include` operate on *completely different* kinds of objects (`require` operates on script files, `include` operates on `module`s) and they do *completely different* things (`require` runs a file, `include` makes the `module` the superclass of the current class). There is no conceivable situation in which you could even use both, so the question which one to use simply never arises. – Jörg W Mittag May 21 '17 at 07:59

1 Answers1

1

As Jörg Mittag already pointed our in this comment: require and include are doing totally different things and have nothing in common. They aren't related to each other nor they are interchangeable.

require loads a file (reads the docs for details). Ruby doesn't magically find files or modules/classes that are defined in a file. Every piece of code that is defined in an external file requires the file to be loaded before the code is executed and can be used.

Modules in Ruby's core (like Math - note the core in the URL) are required automatically, therefore you do not need to load them yourself. But if you want to use a module or class from the standard library (like CSV) or an external gem you need to require it by yourself. This might not be obvious because tools like bundler require files for you or a gem requires internally all other files it needs.

All Ruby files need to be loaded before they can be used. require is the most common way to load Ruby files.

Imagine there is a file named foo.rb that looks like this:

puts 'loading file...'

def foo_loaded?
  true
end

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

Playing around in the console:

# `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

There is no need to include anything. Everything defined in the file is available to Ruby right away. There is not need to name give that file a special name matching the module, class or methods inside. But it is a common pattern and a good practice to name the file by its content.

include doesn't work on file-level but on the language level. It basically takes all methods from a module and includes them into another module or class. Btw: If the module you want to include is defined in an external file then you need to require that file first, otherwise Ruby won't even know that the module exists and cannot include it.

Imagine a module and class structure like this:

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]

And when we include Bar into 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]

Things to note: There is no need to use require in this example because both the module and the class are defined in the same file. include takes the module not a string defining a file or a module name.

Because include does a very special thing it is not useful to ask: Do I need to require or include X before using it? Or: How do I know what to include? Ofter there is no need to include anything: A gem might only provide classes/modules to use directly or it might include its functionality itself. This depends on the design and the purpose of the module. You cannot tell without reading the documentation or the source code.


tl:dr

  • require and include do totally different things.
  • Ruby files must be loaded before usage. require is one way to load a Ruby file.
  • include includes methods from a module into the current module/class.
  • You must read the documentation about how to use a library, there isn't just one way to implement things.
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • You load a Ruby source file via `require 'filename'`. It is common (but not obligatory) that the filename is an underscored string representation of the module/class name that is defined within the file. So your assumptions are generally correct. But the developer has the freedom to not following these conventions. If you just need to `require` a library or if you need to do something else (like `include` a module or calling a setup method) depends on the library itself, on its design and on its purpose. There is no rule around that and you need to read the documentation. – spickermann May 21 '17 at 08:35
  • @Obromios: I updated my answer to address your questions. – spickermann May 22 '17 at 08:23
  • You do not need to `include Math`. Without it, you can write `Math.sin(Math::PI)`. With it, you can write `sin(PI)` within the context of the class where you included `Math`, since the members will be found in the ancestry. `include Math` generally makes no sense programmatically, it is only there because of laziness. `include Enumerable`, on the other hand, significantly extends the including class, and is not merely a shorthand. In either case, as stated, `include` has nothing to do with `require`. – Amadan May 22 '17 at 08:35
  • Furthermore, you can only ever `require` Ruby files (unless you work in alternative Ruby engines like JRuby, where you can `require` a compiled Java code). If a gem has native extensions (e.g. Nokogiri), they will be loaded via another mechanism from the gem's Ruby code. You only ever require the gem's Ruby code (e.g. `require "nokogiri"`). Thus, something like `require "math.c"` is neither needed, nor possible. – Amadan May 22 '17 at 08:38