Getting Ruby’s “require” to work in the Poignant Guide to Ruby

I’m working my way thur “Why’s (Poignant) Guide to Ruby”, chapter 4 “Floating Little Leaves of Code” and ran it a problem doing the “Making the Swap” sub-section example (part of 3. Chaining Delusions Together” – (on a Win XP box, with version 1.8.2 ) – with respect to where the Hash of code words is used in anther program using the require function/method (message).

Update : a copy of Why’s (Poignant) Guide to Ruby, see a the bottom of the post for why..

Although the wordlist.rb loaded (confirmed with more testing), when I went to use the variable defined in it (“code_words”) , I was getting “undefined local variable or method `code_words’ for main:Object (NameError)”. WTF?!!

To simplify, the wordlist.rb was :

1
2
3
4
5
6
code_words = {
'starmonkeys' => 'Phil and Pete, those prickly chancellors of the New Reich',
'catapult' => 'chucky go-go', 'firebomb' => 'Heat-Assisted Living',
'Nigeria' => "Ny and Jerry's Dry Cleaning (with Donuts)",
'Put the kabosh on' => 'Put the cable box on'
}

and, to make it an even simpler example, the calling file (SimReq.rb) could have been:

1
2
3
4
# SimReq.rb to test require loading
require 'wordlist'
code_words.each {|key, value| print "Key:", key, " for Value:", value,
"\n" }

After a bit of head scratching and hair pulling, I got around the problem by making code_words global with “$” on “code_words” in both files. (i.e. ”

1
$code_words

“). Which works but was un satisfing. Global variables are evil, and messy for any non trivial example.

So was it a scoping problem? Was there a better, or best practice, to do something like this trivial example or is this Chunky Bacon payback for actually doing the example or some other PEBKAC issue?

The anwser was YES.

Posting on the comp.lang.ruby groups (once again exploding my ignorance so you don’t have to) resolved my problem and increased my understanding (oh happy day), to wit :

a) I should have been using the fixed version of the Poignant Guide @ http://qa.poignantguide.net/, not the usual url location. (and why isn’t the version @ http://poignantguide.net/ruby/ upto date or redirecting? Health concerns about the colour blue, apparently. So it was only recently caught and is in the process). The fixed version used suggetion b), as well as the

1
load

method, rather than

1
require

. Is there a differance?

b) Using a Constant is a better practices and in this case the simplest thing that works. So

1
code_words

becomes

1
Code_words

in both files. (convention is the constants should be all upcase, so it should be

1
CODE_WORDS

rather.

c) Making a Class is a best practice, especially if you are doing something more than trivial. to quote:

Local variables used in a file you ‘require’ do not appear in the requirer’s scope. Usually the best thing is to wrap what you need in a class or module:

1
2
3
4
5
6
 class CodeWords
def initialize
{ 'a' => 'b',
'c' => 'd' }
end
end

then in the requiring file:

1
2
 require 'codewords'
code_words = CodeWords.new

Also, in the Ruby’s Docs for the load method it notes :

In no circumstance will any local variables in the loaded file be propagated to the loading environment.

.

I just wish it said that under require, or “see load method, wrap=true”. …sigh…Many thanks to David and Dominik, and of course to _why .. and now back to the brain busting.

Update: As of August 2009 the hacker / coder / and artist whytheluckystiff (a.k.a. _why) web sites and code disappeared.  

meanwhile we have the web archive and Scibd’s, Ruby inside has collected a set of mirror and links to copies of code and projects at A Cup Full Of Why: 32 Why The Lucky Stiff Links.

John Resig has written a eulogy to _why that best expresses the concerns of myself and many other’s : wherever you are : be well, and thank you for the code and chunky bacon!

12 thoughts on “Getting Ruby’s “require” to work in the Poignant Guide to Ruby

  1. Thanks for this info, I was in the process of scratching my head and wondering what was going on. Even though I’m going the through the PDF version of Why’s tutorial, it seems it also has the same problem.

    Good to know and thanks for documenting it here.

    -Amr

  2. Thanks for taking the time to post this. I fell into the same trap. I had a feeling that the error had something to do with scope, but luckly I found your post before I tried anything.

    Thanks again.

    Cheers.

  3. Dude, you’re a lifesaver. I had the same problem and I was viewing the wrong url. Once I pointed my browser to the newer url, and rewrote the code to correspond to the stuff in the new URL. All is well. Thanks for the tip.

    -Josh

  4. Thanks. Your post is a great help to me.
    But the new url(qa.poignantguide.net/) has the same content as the link at Ruby.org.
    Maybe the auther has updated the material to have the wrong example again.
    Please correct me if I’m wrong in anyway.

    Thanks again.

  5. @Hwan: no, you’re right. I’ve checked the ‘fixed’ URL and it’s still wrong! However I followed Ian’s suggestion and all is hunky dory!

  6. Pingback: Fixing the Poignant Guide « Dev Notes

  7. Great post! and it keeps on giving good fruits.

    I also was on the “scratching and pulling” phase.

    Thanks a lot for saiving the very few hairs I still have! :-)

  8. Thanks Ian for this message.

    Does anybody know where you can find the “fixed” copy of the book. It seems that why has disappeared and the waybackmachine copy has the old code for some reason.

Leave a Reply