<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Virtuous Code &#187; files</title>
	<atom:link href="http://devblog.avdi.org/tag/files/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.avdi.org</link>
	<description>&#34;The three virtues of a programmer: laziness, impatience, and hubris&#34; -- Larry Wall</description>
	<lastBuildDate>Sun, 19 May 2013 17:37:58 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Removing files with varied capitalization</title>
		<link>http://devblog.avdi.org/2010/03/03/removing-files-with-varied-capitalization/</link>
		<comments>http://devblog.avdi.org/2010/03/03/removing-files-with-varied-capitalization/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 09:00:02 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=514</guid>
		<description><![CDATA[Nothing ground-breaking today, just a one-liner that I expected to be longer than a one-liner. # Remove Rakefile, rakefile, RakeFile, etc... File.delete(*Dir.glob('rakefile', File::FNM_CASEFOLD)) There are two notable things going on here: Dir.glob can take optional bitflags; in this case, FNM_CASEFOLD &#8230; <a href="http://devblog.avdi.org/2010/03/03/removing-files-with-varied-capitalization/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Nothing ground-breaking today, just a one-liner that I expected to be longer than a one-liner.</p>
<pre name="code" class="ruby">
# Remove Rakefile, rakefile, RakeFile, etc...
File.delete(*Dir.glob('rakefile', File::FNM_CASEFOLD))
</pre>
<p>There are two notable things going on here:</p>
<ol>
<li><code>Dir.glob</code> can take optional bitflags; in this case, <code>FNM_CASEFOLD</code> means to ignore case.</li>
<li><code>File.delete</code> can take N arguments.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2010/03/03/removing-files-with-varied-capitalization/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Double-Load Guards in Ruby</title>
		<link>http://devblog.avdi.org/2009/10/22/double-load-guards-in-ruby/</link>
		<comments>http://devblog.avdi.org/2009/10/22/double-load-guards-in-ruby/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 23:34:30 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[load]]></category>
		<category><![CDATA[pathnames]]></category>
		<category><![CDATA[require]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=224</guid>
		<description><![CDATA[If you&#8217;ve ever worked with C or C++ you no doubt remember that one of continual headaches of working with those languages is avoiding double-inclusions of header files. Most C headers start and end with preprocessor directives in order to &#8230; <a href="http://devblog.avdi.org/2009/10/22/double-load-guards-in-ruby/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;ve ever worked with C or C++ you no doubt remember that one of continual headaches of working with those languages is avoiding double-inclusions of header files. Most C headers start and end with preprocessor directives in order to avoid this scenario:</p>
<pre name="code" class="c">
#ifndef HELLO_H
#define HELLO_H

/* ... C code ... */

#endif
</pre>
<p>At first the situation in Ruby seems much improved. We have <code>require</code>, after all, which ensures that a given file will only be loaded once. Or does it?</p>
<p>As it turns out all is not rosy in Ruby-land. Require works great for gems and system libraries. But when we start loading files relative to the current file, the old double-load problem rears it&#8217;s ugly head once more.</p>
<p>Let&#8217;s take a look at why this happens. First, we&#8217;ll define a file to load:</p>
<pre name="code" class="ruby">
# foo.rb
class Foo
  puts "I'm being loaded!"
end
</pre>
<p>Now we&#8217;ll define a client file which <code>require</code>s foo.rb:</p>
<pre name="code" class="ruby">
# client.rb
require File.join(File.dirname(__FILE__), './foo')
require File.join(File.dirname(__FILE__), '../lib/foo')
</pre>
<p>When we run the script above, we get the following output:<br />
<tt>
<pre>
I'm being loaded!
I'm being loaded!
</pre>
<p></tt></p>
<p>Of course, we&#8217;d never write a file like that, with the same library being required twice using two different paths. But in larger projects it is all too common for a file to be <code>require</code>d using a different path in different files. Because Ruby does not use canonicalized pathnames to check if it has already loaded a file, it assumes that the different paths must refer to different files and loads the file over and over again.</p>
<p>Is this a problem? Besides for slower application startup, the most common ill effect of repeated file loads is constant redefinition warnings. If you have a project that outputs a lot of warnings that look like this on startup&#8230;</p>
<p><tt>
<pre>
../lib/foo.rb:1: warning: already initialized constant FOO
</pre>
<p></tt></p>
<p>&#8230;you probably have some files being loaded twice or more times.</p>
<p>More serious and subtle side-effects of double-loading can occur though, especially if the files being reloaded do any class-level metaprogramming. Errors caused by double-loading can be strange and very difficult to track down.</p>
<p>So what do do? Well, first we need to find where the offending loads are originating from. In a large project this can be a daunting task.  Here&#8217;s some code I wrote to help track down double loads at <a href="http://devver.net">Devver</a>:</p>
<pre name="code" class="ruby">
ROOT_PATH = File.expand_path('..', File.dirname(__FILE__))

def require_with_reload_check(raw_path)

  unless $LOADED_FEATURES.include?(raw_path)
    $require_sites ||= {}
    site, line, info = caller.first.split(':')
    expanded_site = File.expand_path(site)
    load_dir = $LOAD_PATH.detect{|dir|
      File.exist?(File.expand_path(raw_path + ".rb", dir))
    }
    expanded_path = File.expand_path(raw_path, load_dir)

    if (expanded_path.index(ROOT_PATH) == 0) &#038;&#038;
        $require_sites.key?(expanded_path) &#038;&#038;
        $require_sites[expanded_path][:as] != raw_path &#038;&#038;
        expanded_path !~ /test_helper$/
      warn "!" * 80
      warn "#{expanded_path} is being reloaded!"
      warn "It was originally loaded as: #{$require_sites[expanded_path][:as]}"
      warn "From #{$require_sites[expanded_path][:in]}"
      warn "But now it is being loaded as: #{raw_path}"
      warn "In #{expanded_site}"
      warn "!" * 80
    end

    $require_sites[expanded_path] = {
      :as => raw_path,
      :in => expanded_site
    }
  end
end

unless defined?($reload_guard_enabled)
  alias require_without_reload_check require
  alias require require_with_reload_check
  $reload_guard_enabled = true
end
</pre>
<p>This code should be loaded as early as possible in your project. Once loaded, it spits out some a very noisy warning every time a file is re-loaded using a different path:<br />
<tt>
<pre>
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/home/avdi/articles/double-load-guards/lib/foo is being reloaded!
It was originally loaded as: ././foo
From /home/avdi/articles/double-load-guards/lib/client.rb
But now it is being loaded as: ./../lib/foo
In /home/avdi/articles/double-load-guards/lib/client.rb
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
</pre>
<p></tt></p>
<p>But how do we avoid reloads, once we have located the offenders? The simplest remedy is to always expand relative paths before requiring them. I prefer to use the two-argument form of <code>File.expand()</code> to construct fully-qualified paths:</p>
<pre name="code" class="ruby">
# client.rb
require File.expand_path('../lib/foo', File.dirname(__FILE__))
</pre>
<p>Eliminate your double-loads, and your Ruby code will load faster, produce fewer warnings, and be that much less prone to bugs.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2009/10/22/double-load-guards-in-ruby/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
