Well, you want to use a relative path with require_relative, so:
### app.rb
require_relative 'alt/methods'
### methods.rb
require_relative 'db'
Note that you don't typically see the .rb extension in require calls (Ruby can load .so files or the equivalent on some systems) and parentheses are rarely used for these either.
-Rob
···
On 2016-Feb-24, at 15:59 , Bee.Lists <bee.lists@gmail.com> wrote:
Hi folks. Can someone provide some insight into how requires work with require_relative?
On 25 February 2016 at 06:59, Bee.Lists <bee.lists@gmail.com> wrote:
Hi folks. Can someone provide some insight into how requires work with
require_relative?
---
Ruby tries to load the library named *string* *relative to the requiring
file’s path*. If the file’s path cannot be determined a LoadError is
raised. If a file is loaded true is returned and false otherwise.
---
(my emphasis)
So you'd have this:
~~~ app.rb
require_relative 'alt/methods'
~~~
~~~ alt/methods.rb
require_relative 'db'
~~~
As Rob said in his reply, you don't need (and shouldn't include) the ".rb"
on the end of the required target. Think of it as *requiring a library*,
not *loading a file*. (Side note: if you do want to load a file, there's
Kernel#load <Module: Kernel (Ruby 2.3.0))
The issue with the documentation is that it doesn’t explain if a file that’s been called two files deep, will pertain outside of the first inclusion.
app.rb -> inc/methods -> db
Does db.rb persist in app.rb after that initial include?
···
On Feb 24, 2016, at 4:51 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote:
There's always the documentation:
---
Ruby tries to load the library named string relative to the requiring file’s path. If the file’s path cannot be determined a LoadError is raised. If a file is loaded true is returned and false otherwise.
The issue with the documentation is that it doesn’t explain if a file
that’s been called two files deep, will pertain outside of the first
inclusion.
require_relative treats its path always relative to the file it is
written in, i.e. the currently active file, regardless of the
depth level of requirements.
If /root/a.rb require_relatives foo/b.rb, and that file require_relatives
bar/c.rb, then you end up with /root/foo/bar/c.rb being loaded. Just try
it out.
It says "
relative to the requiring file’s path
", not "relative to the path of the first file that ever called
require_relative."
Think about it logically: why would I want to write a library/gem that uses
'require_relative' to load its parts, if all of that would break the first
time someone loads my library/gem using require_relative ?
···
On 25 February 2016 at 07:57, Bee.Lists <bee.lists@gmail.com> wrote:
Thanks for the replies, guys.
The issue with the documentation is that it doesn’t explain if a file
that’s been called two files deep, will pertain outside of the first
inclusion.
app.rb -> inc/methods -> db
Does db.rb persist in app.rb after that initial include?
> On Feb 24, 2016, at 4:51 PM, Matthew Kerwin <matthew@kerwin.net.au> > wrote:
>
>
> There's always the documentation:
>
> ---
> Ruby tries to load the library named string relative to the requiring
file’s path. If the file’s path cannot be determined a LoadError is raised.
If a file is loaded true is returned and false otherwise.
Sorry, a second reply after a re-read of the question:
app.rb -> inc/methods -> db
Does db.rb persist in app.rb after that initial include?
I don't understand that question. The Ruby **process** is what "includes"
all the code in those files. Once you require some code, that code is now
part of the Ruby virtual machine state. The only way to get rid of it is
for some other code to explicitly destroy (overwrite or remove all
references to) it.
Note that Ruby doesn't have file scope either; global variables and
constant are always global; class, instance, and local variables are bound
to their class/instance/function.
Cheers
···
On 25 February 2016 at 07:57, Bee.Lists <bee.lists@gmail.com> wrote:
--
Matthew Kerwin http://matthew.kerwin.net.au/
These are all great answers but everyone seems to be missing the point that you can give the full path to the file and it will load.
···
Sent from my iPhone
On Feb 24, 2016, at 8:15 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote:
Sorry, a second reply after a re-read of the question:
On 25 February 2016 at 07:57, Bee.Lists <bee.lists@gmail.com> wrote:
app.rb -> inc/methods -> db
Does db.rb persist in app.rb after that initial include?
I don't understand that question. The Ruby *process* is what "includes" all the code in those files. Once you require some code, that code is now part of the Ruby virtual machine state. The only way to get rid of it is for some other code to explicitly destroy (overwrite or remove all references to) it.
Note that Ruby doesn't have file scope either; global variables and constant are always global; class, instance, and local variables are bound to their class/instance/function.
Think about what I said earlier. Outside of any logic, I was having issues with it earlier and wanted to know the scope of the code. If A calls B and B calls C (as in my case), I wanted to see how far C would remain active. There are languages where that scope is limited.
···
On Feb 24, 2016, at 9:09 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote:
It says "relative to the requiring file’s path", not "relative to the path of the first file that ever called require_relative."
Think about it logically: why would I want to write a library/gem that uses 'require_relative' to load its parts, if all of that would break the first time someone loads my library/gem using require_relative ?
On Feb 24, 2016, at 9:15 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote:
I don't understand that question. The Ruby *process* is what "includes" all the code in those files. Once you require some code, that code is now part of the Ruby virtual machine state. The only way to get rid of it is for some other code to explicitly destroy (overwrite or remove all references to) it.
Note that Ruby doesn't have file scope either; global variables and constant are always global; class, instance, and local variables are bound to their class/instance/function.
Indeed, as long as you're not writing a library that can be installed in
different places on different users' machines, and will never be moved.
Hey, does anyone else remember the days before #require_relative, when you
had to use #require and either futz the load path, or do awesome things
like:
require File.dirname(__FILE__).'/../lib/foo'
(or File.absolute_path(...) rescue ... )
Oh, another point everyone seems to be missing (?) is that #require and #require_relative try to only load a file once, while #load reads, parses,
and executes it every time.
···
On 25 February 2016 at 12:20, thomas Perkins <thomas.perkins23@icloud.com> wrote:
These are all great answers but everyone seems to be missing the point
that you can give the full path to the file and it will load.
This is a slight lie (sorry.) If you declare any local variables in the
'global' scope of a file, those variables will not be available to the
calling scope whether you use #load, #require, or #require_relative, so
there is a sort of file scope in that context.
···
On 25 February 2016 at 12:15, Matthew Kerwin <matthew@kerwin.net.au> wrote:
Note that Ruby doesn't have file scope either; global variables and
constant are always global; class, instance, and local variables are bound
to their class/instance/function.
At no point was I ever asking about loading a file for any data reasons, etc. It was a question about the scope of inclusion of the functional code beyond a structure.
I also had the db.rb inclusion inside a method. Having executed that method once, I was interested to see if methods inside db.rb would still be accessible.
···
On Feb 24, 2016, at 11:04 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote:
Oh, another point everyone seems to be missing (?) is that #require and #require_relative try to only load a file once, while #load reads, parses, and executes it every time.
What I did say was that I had forgotten the issues involved. I have done some messing around with some examples and then realized the require was within a method.
Essentially if a method is called specifically to load up db requirements, I was fuzzy if that connection was loaded for the rest of the script. I now know. I did construct something and it wasn’t playing out as expected. I might have been tired, like human beings get.
···
On Feb 25, 2016, at 4:02 PM, Matthew Kerwin <matthew@kerwin.net.au> wrote:
You probably should have said that up front, then people would know how to direct the answers.
For those sorts of uncommon edge cases, why not just construct a test script and see first hand how it works?
Well, back to the original query (asking for best practices):
1. always use 'require' for system-wide libraries (gems, etc.)
2. always use 'require_relative' for local (sub-)libraries
3. never use absolute paths
4. don't include the ".rb" on the end of the filename unless you really
mean it
5. only use 'load' if you want all side-effects (definitions, etc.) to
be (re)applied every time
6. don't do any of the above from within a method unless you know what
you're doing
7. when in doubt, test it [1]
On 26 February 2016 at 07:33, Bee.Lists <bee.lists@gmail.com> wrote:
What I did say was that I had forgotten the issues involved. I have done
some messing around with some examples and then realized the require was
within a method.