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
andinclude
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
Ruby: Is There an Opposite of Include? for Ruby Arrays
How Would You Test Observers with Rspec in a Ruby on Rails Application
Rails Authentication Across Apps/Servers
Rails: How to Make Date Strftime Aware of the Default Locale
Ruby JSON Parse Changes Hash Keys
Is It Idiomatic Ruby to Add an Assert( ) Method to Ruby's Kernel Class
Find Most Common String in an Array
Can You Use Semicolons in Ruby
How Get All Routes in My Rails Application
Solutions to the Annoying "Warning: Already Initialized Constant" Message
Generate Unique Random String with Letters and Numbers in Lower Case
Failed to Build Gem Native Extension When Install Redcloth-4.2.9 Install Linux
Why Is It Best to Store a Telephone Number as a String VS. Integer
How to Describe an Enumeration Column in a Rails 3 Migration