DevHeads.net

Requires

Hi folks. Can someone provide some insight into how requires work with require_relative?

HQ
├── Gemfile
├── Gemfile.lock
├── app.rb
├── config.ru
├── css
│ ├── HQ.css
│ └── reset.css
├── img
│ ├── traffic.jpg
│ └── weather.gif
├── alt
│ ├── db.rb
│ └── methods.rb
├── blah.txt

In this model I would like app.rb to call methods.rb which calls db.rb when needed.

So in app.rb: require_relative(‘/alt/methods.rb’)
in methods.rb: require_relative(‘db.rb’)

Does this work? I was having some issues before and I forgot the specifics of them, so I thought I would ask for a best practice on the list.

Any insight appreciated.

Cheers, Bee

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Comments

Re: Requires

By Matthew Kerwin at 02/24/2016 - 17:51

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 <http://ruby-doc.org/core-2.3.0/Kernel.html#method-i-load>)

Cheers

Re: Requires

By Bee.Lists at 02/24/2016 - 17:57

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?

Cheers, Bee

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Re: Requires

By Matthew Kerwin at 02/24/2016 - 22:15

Sorry, a second reply after a re-read of the question:

​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

Re: Requires

By Bee.Lists at 02/25/2016 - 09:13

OK, that’s what I was asking.

Cheers, Bee

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Re: Requires

By Matthew Kerwin at 02/25/2016 - 00:06

Re: Requires

By thomas Perkins at 02/24/2016 - 22:20

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

Re: Requires

By Matthew Kerwin at 02/25/2016 - 00:04

On 25 February 2016 at 12:20, thomas Perkins <thomas. ... at icloud dot com>
wrote:

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.

Re: Requires

By Bee.Lists at 02/25/2016 - 09:15

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.

Cheers, Bee

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Re: Requires

By Matthew Kerwin at 02/25/2016 - 17:02

On 25/02/2016 11:16 PM, "Bee.Lists" <bee. ... at gmail dot com> wrote:
That was a snark at Thomas Perkins, who said we were 'missing the point'
about absolute paths.

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?

Re: Requires

By Bee.Lists at 02/25/2016 - 17:33

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.

Cheers, Bee

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Re: Requires

By Matthew Kerwin at 02/25/2016 - 18:37

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]

[1]: <a href="https://gist.github.com/phluid61/70c75302512630642d36" title="https://gist.github.com/phluid61/70c75302512630642d36">https://gist.github.com/phluid61/70c75302512630642d36</a>

Re: Requires

By Matthew Kerwin at 02/24/2016 - 22:09

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 ?

Re: Requires

By Bee.Lists at 02/25/2016 - 09:12

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.

Cheers, Bee

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Re: Requires

By Quintus at 02/24/2016 - 18:44

"Bee.Lists" <bee. ... at gmail dot com> writes:
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.

Greetings
Marvin

Re: Requires

By Rob Biedenharn at 02/24/2016 - 17:14

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

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>