Forum: Ruby Newbie: require 'filename' - undefined local variable or me

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9715f75919af16e170dda694178942e6?d=identicon&s=25 Grehom (Guest)
on 2005-12-18 21:35
(Received via mailing list)
I have one line of code in a file called 'stuff.rb':
     myhash = { "a" => "ay", "b" => "bee", "c" => "sea" }

and I wish to include it in another program called 'mainprog.rb' thus:

     require 'stuff'

     puts " a = " + myhash["a"]

when I run it I get an error message:
    mainprog.rb:4: undefined local variable or method `myhash' for
main:Object (NameError)

I guess I must be doing something dumb - I am basing this code on
examples in 'Why's (poignant) guide to Ruby'.  I am using the very
latest Windows version under XP Pro:
C:\rubysrcs>ruby -v
ruby 1.8.2 (2004-12-25) [i386-mswin32]

which I installed using the exe file: ruby182-15.exe

everything else I've tried seems to be working fine.  Thanks.
Fe9b2d0628c0943af374b2fe5b320a82?d=identicon&s=25 Eero Saynatkari (rue)
on 2005-12-18 21:51
Grehom wrote:
> I have one line of code in a file called 'stuff.rb':
>      myhash = { "a" => "ay", "b" => "bee", "c" => "sea" }
>
> and I wish to include it in another program called 'mainprog.rb' thus:
>
>      require 'stuff'
>
>      puts " a = " + myhash["a"]
>
> when I run it I get an error message:
>     mainprog.rb:4: undefined local variable or method `myhash' for
> main:Object (NameError)
>
> I guess I must be doing something dumb - I am basing this code on
> examples in 'Why's (poignant) guide to Ruby'.  I am using the very
> latest Windows version under XP Pro:
> C:\rubysrcs>ruby -v
> ruby 1.8.2 (2004-12-25) [i386-mswin32]
>
> which I installed using the exe file: ruby182-15.exe
>
> everything else I've tried seems to be working fine.  Thanks.

myhash is a local variable in stuff.rb and will thus not
be available when you #require the file. There are a few
options you have: you could either make it a constant
(MY_HASH), a global ($my_hash) or you could wrap it inside
a method and then call the method in your main file.


E
D30547991ceda9c951ebad386860f112?d=identicon&s=25 Dayne (Guest)
on 2005-12-18 23:20
(Received via mailing list)
The exact details of why this I'm not familiar w/ but it is a scope
issue.  The require won't make the local variable into global for you.

The 'myhash' isn't global just because it is declared outside of other
things.. prefix that myhash w/ a $ and make it a global.

$myhash =  { "a" => "ay", "b" => "bee", "c" => "sea" }

-----------

puts $myhash['a']


-dayne
9dfe8c734b0f9b37a4e218425c0a2138?d=identicon&s=25 Gene Tani (Guest)
on 2005-12-18 23:20
(Received via mailing list)
Grehom wrote:
>     mainprog.rb:4: undefined local variable or method `myhash' for
> everything else I've tried seems to be working fine.  Thanks.
this is a common gotcha, ruby doesn't include "." in $LOAD_PATH, which
is different from perl @INC and python PYTHONPATH so you have to

$:.unshift Dir.pwd

or somehtin like that
6076c22b65b36f5d75c30bdcfb2fda85?d=identicon&s=25 Ezra Zygmuntowicz (Guest)
on 2005-12-18 23:20
(Received via mailing list)
On Dec 18, 2005, at 12:02 PM, Grehom wrote:

>     mainprog.rb:4: undefined local variable or method `myhash' for
> everything else I've tried seems to be working fine.  Thanks.
>
>

Try using this instead:

load 'stuff'

local variables outside of  class like that will not be imported when
you require that file. Load should do what you want.

Cheers-

-Ezra
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2005-12-18 23:20
(Received via mailing list)
Grehom wrote:
>     mainprog.rb:4: undefined local variable or method `myhash' for
> main:Object (NameError)

Local vars are scoped to the file they are defined in, when you use
require or load. You could make it global, but unless this is just a
quick hack, it's not a good solution.

Another option is to read and eval the file. If the myhash variable has
been assigned *before* you eval, then the assignment in stuff.rb will
propagate to the mainprog.rb. Like so:

  myhash = nil
  eval File.read("stuff.rb")
  p myhash

This is ok for some purposes, but you have to know in advance which
variables the file is going to define. Also, you may have scope
collisions: any other local var in mainprog.rb can be affected by
assignments in stuff.rb.

My preference is to read the file as a string and use module_eval:

# mainprog.rb
  m = Module.new
  m.module_eval(File.read("stuff.rb"), File.expand_path("stuff.rb"))
  p m::Myhash

# stuff.rb
  Myhash = { "a" => "ay", "b" => "bee", "c" => "sea" }

Local vars stay local. Constants are accessible in the scope of the
newly defined module m. The second arg to module_eval means that errors
are reported with the correct file name.

<plug> This is the approach used by my "script" lib on raa. It adds some
sugar and features. </plug>
9715f75919af16e170dda694178942e6?d=identicon&s=25 Grehom (Guest)
on 2005-12-18 23:29
(Received via mailing list)
Thanks Gene and Ezra, I tried your suggestions but with no luck.  I
modified the main program 'mainprog.rb' as follows:
   puts $:
   load("stuff.rb", wrap=false)
   puts myhash["a"]

This produced following output:
  C:\rubysrcs>ruby mainprog.rb
    c:/ruby/lib/ruby/site_ruby/1.8
    c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt
    c:/ruby/lib/ruby/site_ruby
    c:/ruby/lib/ruby/1.8
    c:/ruby/lib/ruby/1.8/i386-mswin32
    .
    mainprog.rb:5: undefined local variable or method `myhash' for
main:Object (NameError)

and it seems the pwd '.' is part of the Load Path already (without me
changing anything)

So I'm still puzzled (there are a few examples of code like this in
aforementioned tutorial book)!
6076c22b65b36f5d75c30bdcfb2fda85?d=identicon&s=25 Ezra Zygmuntowicz (Guest)
on 2005-12-18 23:35
(Received via mailing list)
On Dec 18, 2005, at 2:27 PM, Grehom wrote:

>     c:/ruby/lib/ruby/site_ruby
> aforementioned tutorial book)!
>
>

Yeah I was wrong in thinking that load would load local vars. So like
others have said you will have to wrap your var in a method or class.
Or you could eval the file by reading the file in and running eval on
it.

#a.rb
a = [1,2,3,4,5,6]
__________________

#b.rb
a_contents = File.open("a.rb"){|f| f.read}
eval a_contents
p a

# => [1, 2, 3, 4, 5]

-Ezra
9715f75919af16e170dda694178942e6?d=identicon&s=25 Grehom (Guest)
on 2005-12-18 23:38
(Received via mailing list)
Thanks Joel, that worked but it's way different from a number of
examples in the book ('Why's (poignant) guide to Ruby), how did they
ever work there?
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2005-12-18 23:47
(Received via mailing list)
Ezra Zygmuntowicz wrote:
>>   C:\rubysrcs>ruby mainprog.rb
>> changing anything)
> #a.rb
> -Ezra
[~/tmp] cat >a.rb
a = [1,2,3,4,5,6]
[~/tmp] cat >b.rb
a_contents = File.open("a.rb"){|f| f.read}
eval a_contents
p a
[~/tmp] ruby b.rb
b.rb:3: undefined local variable or method `a' for main:Object
(NameError)
[~/tmp] ruby -v
ruby 1.8.2 (2004-12-25) [i686-linux]

This only works if you assign to 'a' somewhere in b.rb before the eval.
5c7bdd14d6885c8275eaf78be41d120a?d=identicon&s=25 Eero Saynatkari (Guest)
on 2005-12-19 00:05
(Received via mailing list)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2005.12.19 07:27, "Grehom" <grehom@ntlworld.com> wrote:
>     c:/ruby/lib/ruby/site_ruby
> aforementioned tutorial book)!
I think there may be a problem with the gateway again..

The problem you have is that myhash is local to stuff.rb and
will not be made available if you #require or #load the file.
Instead, you have a few options: either make myhash a constant
(MY_HASH), a global ($my_hash) or set up a method to retrieve
it (def my_hash(); ...; end) and call the method from your
main file.


E
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFDpe0rxvA1l6h+MUMRAsKyAJ43oioZaeoEZ8OD4omB8r9rIjEh9gCfWwTB
Lss8R5dkKElh589j7IT5RcE=
=w3Tl
-----END PGP SIGNATURE-----
4674615d2cf231975c741731be9a8685?d=identicon&s=25 why the lucky stiff (Guest)
on 2005-12-19 00:41
(Received via mailing list)
Grehom wrote:

>Thanks Joel, that worked but it's way different from a number of
>examples in the book ('Why's (poignant) guide to Ruby), how did they
>ever work there?
>
I'm very sorry about this, Grehom.  There is an update to the guide at:
http://qa.poignantguide.net/.  This will all be rolled out soon with the
new design and the German and French editions of the Guide.

_why
6076c22b65b36f5d75c30bdcfb2fda85?d=identicon&s=25 Ezra Zygmuntowicz (Guest)
on 2005-12-19 02:41
(Received via mailing list)
On Dec 18, 2005, at 2:46 PM, Joel VanderWerf wrote:

>>> This produced following output:
>>> and it seems the pwd '.' is part of the Load Path already
>> Or you could eval the file by reading the file in and running eval
>>
> [~/tmp] ruby b.rb
> b.rb:3: undefined local variable or method `a' for main:Object
> (NameError)
> [~/tmp] ruby -v
> ruby 1.8.2 (2004-12-25) [i686-linux]
>
> This only works if you assign to 'a' somewhere in b.rb before the
> eval.

Shows what I get for typing b.rb into irb instead of making it a real
file.

-Ezra
9715f75919af16e170dda694178942e6?d=identicon&s=25 Grehom (Guest)
on 2005-12-19 09:13
(Received via mailing list)
Thanks _why,
   I hate it when there is something like that I can't get my head
around.  I love the book, a little wierd as programming tutorials go,
but the programming stuff is very readable and I am finding it very
useful
G.
This topic is locked and can not be replied to.