Ruby: Module, Require and Include

Ruby: module, require and include

In short: you need to extend instead of include the module.

class MyApp
extend MyModule
self.hallo
end

include provides instance methods for the class that mixes it in.

extend provides class methods for the class that mixes it in.

Give this a read.

What is the difference between include and require in Ruby?

What's the difference between
"include" and "require" in Ruby?

Answer:

The include and require methods do
very different things.

The require method does what include
does in most other programming
languages: run another file. It also
tracks what you've required in the
past and won't require the same file
twice. To run another file without
this added functionality, you can use
the load method.

The include method takes all the
methods from another module and
includes them into the current module.
This is a language-level thing as
opposed to a file-level thing as with
require. The include method is the
primary way to "extend" classes with
other modules (usually referred to as
mix-ins). For example, if your class
defines the method "each", you can
include the mixin module Enumerable
and it can act as a collection. This
can be confusing as the include verb
is used very differently in other
languages.

Source

So if you just want to use a module, rather than extend it or do a mix-in, then you'll want to use require.

Oddly enough, Ruby's require is analogous to C's include, while Ruby's include is almost nothing like C's include.

How do i require and include a module in the initialize method

The reason that you can't call include in initialize like that is that include is a method that's only defined on classes and modules, but inside of an instance method like initialize the implicit receiver is an object of your class, not the class itself.

Since you only need the methods to be available on the newly created object, you can just use extend instead of include. extend is like a per-object version of include in that it adds the methods of the given module as singleton methods to an object rather than adding them as instance methods to a module or class.

Why use both require and include in Rails class?

require loads a ruby file, making the BCrypt module available to your ruby code. It does not, necessarily have to be in the same file as the class you're including the module in.

require can also be used to make a ruby class defined in that file available (for instance, other classes you've defined in your project). As it's in a gem, bcrypt is on the ruby path, if it's a file in your project you may need to reference the full path, or use require_relative.

include takes the code in the bCrypt module and includes it to your User class, providing User with the methods and attributes declared in the BCrypt module.

When do you have to require a module in Ruby?

You never require modules, you require files.

In the above example, if the two fragments that you posted were in different files, e.g. my_first_module.rb and module_tester.rb, then you would have to do

require "my_first_module"

before you could reference MyFirstModule.

(Obviously, if they were in the same file, no require statement would be necessary, and would not make sense anyway, as there would be no file to require.)

What require does is to look for the given Ruby file in the library path, and then load the Ruby file, just as if you had executed it. The file will be loaded at most once during the runtime of your program (which is the difference to the load command, which is otherwise very similar to require).

In the above example, before you can use MyFirstModule, you'll have to require the file that defines it.

Be aware that there is an auto loading mechanism which can require files automatically for you. Also, Rails does require most classes automatically. So don't be confused that in some cases a require statement does not seem to be necessary.

Ruby - How to include classes in a Module

Im not sure what the issue is. I understand that it says uninitialized but Im not sure why. It seems it is looking for a constant instead of reading the class?

It is not clear to me what you mean by "reading the class". Yes, Ruby is looking for a constant. Variable names that begin with a capital letter are constants, ergo, HtmlBody is a constant, HeadingTags is a constant, and HtmlBody::HeadingTags is the constant HeadingTags located in a class or module that is referenced by the constant HtmlBody.

How are you supposed to include classes located in separated files inside a module?

You namespace a class inside a module by defining the class inside the module. If you are sure that the module already exists, you can define the class like this:

class HtmlBody::HeadingTags
# …
end

However, if HtmlBody is not defined (or is not a class or module), this will fail.

module HtmlBody
class HeadingTags
# …
end
end

This will guarantee that module HtmlBody will be created if it doesn't exist (and simply re-opened if it already exists).

There is also a slight difference in constant lookup rules between the two, which is however not relevant to your question (but be aware of it).

The is something that Im missing in Ruby and the require/require_relative probably.

Indeed, your question stems from a fundamental misunderstanding of what Kerne#load / Kernel#require / Kernel#require_relative does.

Here is the very complicated, detailed, in-depth explanation of all the incredibly convoluted stuff that those three methods do. Brace yourself! Are you ready? Here we go:

They run the file.

Wait … that's it? Yes, that's it! That's all there is to it. They run the file.

So, what happens when you run a file that looks like this:

class HeadingTags
# …
end

It defines a class named HeadingTags in the top-level namespace, right?

Okay, so what happens when we now do this:

require_relative './html_body/HeadingTags'

Well, we said that require_relative simply runs the file. And we said that running that file defines a class named HeadingTags in the top-level namespace. Therefore, this will obviously define a class named HeadingTags in the top-level namespace.

Now, looking at your code: what happens, when we do this:

module HtmlBody
require_relative './html_body/HeadingTags'
end

Again, we said that require_relative simply runs the file. Nothing more. Nothing less. Just run the file. And what did we say running that file does? It defines a class named HeadingTags in the top-level namespace.

So, what will calling require_relative from within the module definition of HtmlBody do? It will define a class named HeadingTags in the top-level namespace. Because require_relative simply runs the file, and thus the result will be exactly the same as running the file, and the result of running file is that it defines the class in the top-level namespace.

So, how do you actually achieve what you are trying to do? Well, if you want to define a class inside a module, you have to … define the class inside the module!

lib/html_body.rb

require_relative 'html_body/heading_tags'
require_relative 'html_body/anchor_tags'
require_relative 'html_body/img_tags'

module HtmlBody; end

lib/html_body/heading_tags.rb

module HtmlBody
class HeadingTags
# …
end
end

lib/html_body/anchor_tags.rb

module HtmlBody
class AnchorTags
# …
end
end

lib/html_body/img_tags.rb

module HtmlBody
class ImgTags
# …
end
end

main.rb

require_relative 'lib/html_body'

HtmlBody::HeadingTags.new

Ruby require module/class on another folder

I believe the following will work:

require_relative '../database/base'

Inside run.rb file, include A and then run file

With a ruby-doc.org library how do you work out whether to require or include?

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.


Related Topics



Leave a reply



Submit