# Require from a method

**URL:** <https://www.ruby-forum.com/t/require-from-a-method/194056>\
**Category:** Ruby\
**Created:** [August 29, 2010, 12:27pm UTC](https://www.ruby-forum.com/t/require-from-a-method/194056 "2010-08-29T12:27:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ammar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9fc348/32.png) [@ammar](https://www.ruby-forum.com/u/ammar)\
**Post date:** [August 29, 2010, 12:27pm UTC](https://www.ruby-forum.com/t/require-from-a-method/194056/1 "2010-08-29T12:27:16Z")

</div>

Hello,

Are there any gotchas in requiring files from within a method? It  
seems to work, but I have a sinking feeling that I’m missing something  
here.

def require\_relative(start, path)  
require File.expand\_path( File.join( File.dirname(start), path ) )  
end

require\_relative **FILE** , %w{… tests tester.rb}

1.upto(3) {|i|  
Tester.run i, “some”, [3,6,9], :foo =\> :bar  
}

Thanks,  
Ammar

---

<div class="post-metadata">

**Author:** ![ammar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9fc348/32.png) [@ammar](https://www.ruby-forum.com/u/ammar)\
**Post date:** [August 29, 2010, 12:43pm UTC](https://www.ruby-forum.com/t/require-from-a-method/194056/2 "2010-08-29T12:43:39Z")

</div>

On 29.08.2010 12:25, Ammar A. wrote:

> Are there any gotchas in requiring files from within a method? It  
> seems to work, but I have a sinking feeling that I’m missing something  
> here.

Not technically. It might even be more efficient if you require a  
particular functionality only rarely and include the “require” in the  
method that needs that functionality. OTOH I find “require” in the  
middle of the code difficult to spot which makes it harder to keep track  
of dependencies. Also, errors might surface later (e.g. you copy your  
app to a different machine, start it and believe it works while in  
reality you forgot to install a gem or lib which is only used for  
particular use cases).

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![ammar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9fc348/32.png) [@ammar](https://www.ruby-forum.com/u/ammar)\
**Post date:** [August 29, 2010, 1:11pm UTC](https://www.ruby-forum.com/t/require-from-a-method/194056/3 "2010-08-29T13:11:45Z")

</div>

Hi,

On 29.08.2010 12:40, Robert K. wrote:

> On 29.08.2010 12:25, Ammar A. wrote:
> 
> > Are there any gotchas in requiring files from within a method? It  
> > seems to work, but I have a sinking feeling that I’m missing something  
> > here.
> 
> Not technically. It might even be more efficient if you require a  
> particular functionality only rarely and include the “require” in the  
> method that needs that functionality.

Sorry for hijacking, but I’m wondering how require exactly works in the  
context of a class or method; does scoping play any role if I’ve defined  
classes/modules in the required file?

thanks,

- Markus

---

<div class="post-metadata">

**Author:** ![ammar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9fc348/32.png) [@ammar](https://www.ruby-forum.com/u/ammar)\
**Post date:** [August 29, 2010, 2:55pm UTC](https://www.ruby-forum.com/t/require-from-a-method/194056/4 "2010-08-29T14:55:22Z")

</div>

On 29.08.2010 13:11, Markus F. wrote:

> > particular functionality only rarely and include the “require” in the  
> > method that needs that functionality.
> 
> Sorry for hijacking, but I’m wondering how require exactly works in the  
> context of a class or method; does scoping play any role if I’ve defined  
> classes/modules in the required file?

No. It would be bad because then if the require statements would be  
executed in a different order totally unpredictable behavior would  
occur.

Robert@babelfish ~  
$ echo ‘p self’ \>x.rb

Robert@babelfish ~  
$ ruby19 -r x -e 1  
main

Robert@babelfish ~  
$ ruby19 -r x -e ‘class X; def m;require “x”; end; end; X.new.m’  
main

Robert@babelfish ~  
$

Cheers

robert

---

<div class="post-metadata">

**Author:** ![ammar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9fc348/32.png) [@ammar](https://www.ruby-forum.com/u/ammar)\
**Post date:** [August 29, 2010, 4:51pm UTC](https://www.ruby-forum.com/t/require-from-a-method/194056/5 "2010-08-29T16:51:51Z")

</div>

On Aug 29, 3:25 am, Ammar A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> require\_relative **FILE** , %w{… tests tester.rb}
> 
> 1.upto(3) {|i|  
> Tester.run i, “some”, [3,6,9], :foo =\> :bar
> 
> }
> 
> Thanks,  
> Ammar

Hi Ammar,  
I recently wrote a script to graph out (using a .dot file and Graphviz  
for visualization) what files load when a given gem is loaded. When I  
started looking at gems this way I realized that it was not uncommon  
for one file to require a second more than once. When I inspect in the  
code, there is usually two require statement within separate method  
calls. The logic is just as Robert explained, better efficiency by  
only loading something when you need it. I can give you a quick  
example from the yadis gem. requiring ‘yadis’ causes a chain reaction  
of file loading resulting in 73 files loading! One of those is a  
‘cgi.rb’ file, which itself loads tempfile twice. Looking in cgi.rb  
shows the following def for the read\_multipart method definition. Note  
the two require ‘tempfile’ statements in one method definition.  
Regards,  
Tim

```
def read_multipart(boundary, content_length)
  params = Hash.new([])
  boundary = "--" + boundary
  quoted_boundary = Regexp.quote(boundary, "n")
  buf = ""
  bufsize = 10 * 1024
  boundary_end=""

  # start multipart/form-data
  stdinput.binmode if defined? stdinput.binmode
  boundary_size = boundary.size + EOL.size
  content_length -= boundary_size
  status = stdinput.read(boundary_size)
  if nil == status
    raise EOFError, "no content body"
  elsif boundary + EOL != status
    raise EOFError, "bad content body"
  end

  loop do
    head = nil
    if 10240 < content_length
      require "tempfile"
      body = Tempfile.new("CGI")
    else
      begin
        require "stringio"
        body = StringIO.new
      rescue LoadError
        require "tempfile"
        body = Tempfile.new("CGI")
      end
    end
    body.binmode if defined? body.binmode

    until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)

      if (not head) and /#{EOL}#{EOL}/n.match(buf)
        buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
          head = $1.dup
          ""
        end
        next
      end

      if head and ( (EOL + boundary + EOL).size < buf.size )
        body.print buf[0 ... (buf.size - (EOL + boundary +

```

EOL).size)]  
buf[0 … (buf.size - (EOL + boundary + EOL).size)] = “”  
end

```
      c = if bufsize < content_length
            stdinput.read(bufsize)
          else
            stdinput.read(content_length)
          end
      if c.nil? || c.empty?
        raise EOFError, "bad content body"
      end
      buf.concat(c)
      content_length -= c.size
    end

    buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}

```

([\r\n]{1,2}|–)/n) do  
body.print $1  
if “–” == $2  
content\_length = -1  
end  
boundary\_end = $2.dup  
“”  
end

```
    body.rewind

    /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;

```

\s]\*))/ni.match(head)  
filename = ($1 or $2 or “”)  
if /Mac/ni.match(env\_table[‘HTTP\_USER\_AGENT’]) and  
/Mozilla/ni.match(env\_table[‘HTTP\_USER\_AGENT’]) and  
(not /MSIE/ni.match(env\_table[‘HTTP\_USER\_AGENT’]))  
filename = CGI::unescape(filename)  
end

```
    /Content-Type: ([^\s]*)/ni.match(head)
    content_type = ($1 or "")

    (class << body; self; end).class_eval do
      alias local_path path
      define_method(:original_filename) {filename.dup.taint}
      define_method(:content_type) {content_type.dup.taint}
    end

    /Content-Disposition:.* name="?([^\";\s]*)"?/ni.match(head)
    name = $1.dup

    if params.has_key?(name)
      params[name].push(body)
    else
      params[name] = [body]
    end
    break if buf.size == 0
    break if content_length == -1
  end
  raise EOFError, "bad boundary end of body part" unless

```

boundary\_end=~/–/

```
  params
end # read_multipart

```

---

<div class="post-metadata">

**Author:** ![ammar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9fc348/32.png) [@ammar](https://www.ruby-forum.com/u/ammar)\
**Post date:** [August 29, 2010, 3:35pm UTC](https://www.ruby-forum.com/t/require-from-a-method/194056/6 "2010-08-29T15:35:45Z")

</div>

Markus F. wrote:

> classes/modules in the required file?  
> No. Required files always get evaluated in the global context. Which  
> is actually another gotcha: if you call require inside a module or  
> class, then it _looks like_ you jail the library into a namespace,  
> when in fact you don’t. Code that looks like it’s doing one thing, but  
> does another thing, is always dangerous.

Note that Kernel#load takes an optional boolean argument telling it to  
load the file into an anonymous module instead of the global  
namespace. (Unfortunately, there doesn’t seem to be any way to  
actually _get_ at that module[1], so this API looks rather useless.  
Also, the code in that file can always use ::Object to gain access to  
the global namespace.)

jwm

[1] except for ugly hacks with ObjectSpace

---

<div class="post-metadata">

**Author:** ![ammar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9fc348/32.png) [@ammar](https://www.ruby-forum.com/u/ammar)\
**Post date:** [August 31, 2010, 8:15am UTC](https://www.ruby-forum.com/t/require-from-a-method/194056/7 "2010-08-31T08:15:45Z")

</div>

On 08/29/2010 03:34 PM, Jörg W Mittag wrote:

> > context of a class or method; does scoping play any role if I’ve defined  
> > classes/modules in the required file?
> 
> No. Required files always get evaluated in the global context. Which  
> is actually another gotcha: if you call require inside a module or  
> class, then it _looks like_ you jail the library into a namespace,  
> when in fact you don’t. Code that looks like it’s doing one thing, but  
> does another thing, is always dangerous.

Which is one good reason for not doing it at all. 🙂

> Note that Kernel#load takes an optional boolean argument telling it to  
> load the file into an anonymous module instead of the global  
> namespace. (Unfortunately, there doesn’t seem to be any way to  
> actually _get_ at that module[1], so this API looks rather useless.  
> Also, the code in that file can always use ::Object to gain access to  
> the global namespace.)
> 
> jwm
> 
> [1] except for ugly hacks with ObjectSpace

The usage of load with module I can think of is to load a file which  
registers instances or classes somewhere in some kind of global registry  
(hence you need global scope access). That way you do not have to care  
how everybody names their classes and they don’t interfere with each  
other - which is good for this plugin like scenario.

But I agree, more direct access to the scope used would increase utility  
of that feature a lot.

Kind regards

robert
