test.rb :
require 'b'
b = B.new
lib/base.rb:
module A
class Base
end
end
lib/b.rb:
module A
class B < Base
end
end
Why do I get
/lib/b.rb:2: uninitialized constant A::Base (NameError)
from test.rb:1:in `require'
from test.rb:1
?
This is a stripped down version of what I want to do (ie organize my
code into a module, but still keep classes in separate files, have a
base class and inherit).
It's probably something trivial, but at the moment I'm stuck - any help
would be (as always) greatly appreciated
Kev
> given:
>
> test.rb :
>
> require 'b'
>
> b = B.new
b = A::B.new
> lib/base.rb:
>
> module A
> class Base
> end
> end
>
> lib/b.rb:
require 'base'
> module A
> class B < Base
> end
> end
>
> Why do I get
>
> ./lib/b.rb:2: uninitialized constant A::Base (NameError)
> from test.rb:1:in `require'
> from test.rb:1
>
> ?
>
> This is a stripped down version of what I want to do (ie organize
> my code into a module, but still keep classes in separate files,
> have a base class and inherit).
>
> It's probably something trivial, but at the moment I'm stuck - any
> help would be (as always) greatly appreciated
Also you can get away with less indentation:
$ cat base.rb
module A; end
class A::Base
end
$ cat b.rb
require 'base'
class A::B < A::Base
end
--
Eric Hodel - drb...@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
In lib/b.rb, you need to write:
require "base"
module A
class B < Base
end
end
otherwise your code in b.rb isn't aware of base.rb, and thus doesn't
know about A::Base.
--
Christophe Grandsire.
http://rainbow.conlang.free.fr
You need a straight mind to invent a twisted conlang.
> require "base"
> module A
> class B < Base
> end
> end
>
> otherwise your code in b.rb isn't aware of base.rb, and thus doesn't
> know about A::Base.
require 'base'
causes
/lib/b.rb:1:in `require': No such file to load -- base (LoadError)
from ./lib/b.rb:1
from test.rb:1:in `require'
from test.rb:1
which is weird as I have done this before with other files, it's just
this one that it won't find
> In lib/b.rb, you need to write:
>
>
>> require "base"
>> module A
>> class B < Base
>> end
>> end
>>
>> otherwise your code in b.rb isn't aware of base.rb, and thus
>> doesn't know about A::Base.
>>
>
> require 'base'
require 'lib/base' then
> causes
>
> ./lib/b.rb:1:in `require': No such file to load -- base (LoadError)
> from ./lib/b.rb:1
> from test.rb:1:in `require'
> from test.rb:1
>
> which is weird as I have done this before with other files, it's
> just this one that it won't find
>
--
> In lib/b.rb, you need to write:
>
>> require "base"
>> module A
>> class B < Base
>> end
>> end
>>
>> otherwise your code in b.rb isn't aware of base.rb, and thus doesn't
>> know about A::Base.
>
>
> require 'base'
>
> causes
>
> ./lib/b.rb:1:in `require': No such file to load -- base (LoadError)
> from ./lib/b.rb:1
> from test.rb:1:in `require'
> from test.rb:1
>
> which is weird as I have done this before with other files, it's just
> this one that it won't find
>
in fact from test.rb, I can require 'lib/base', but from b.rb I can't
require 'base' (with b.rb and base.rb in the same directory) - this is
very strange behaviour
Kev
Hi Kev,
require 'b' loads /and runs/ b.rb immediately.
You have at the top:
module A
class B < Base
end
end
Base is defined later, so you need to organise the require order (?).
Then b = A::B.new (as Eric said)
HTH,
daz
> On Oct 27, 2005, at 9:51 PM, Kev Jackson wrote:
>
>> In lib/b.rb, you need to write:
>>
>>
>>> require "base"
>>> module A
>>> class B < Base
>>> end
>>> end
>>>
>>> otherwise your code in b.rb isn't aware of base.rb, and thus
>>> doesn't know about A::Base.
>>>
>>
>> require 'base'
>
>
> require 'lib/base' then
Thanks, this fixes it - but the actual path 'lib/base' is incorrect in
the context of the file b.rb (b.rb is in the same directory as base.rb,
therefore the line should be require 'base' no?)
Kev
The load path works from Dir.pwd, not the paths of the files you
require.
ruby -Ilib will allow things to Just Work.
> >
> > require 'base'
> >
> > causes
> >
> > ./lib/b.rb:1:in `require': No such file to load -- base (LoadError)
> > from ./lib/b.rb:1
> > from test.rb:1:in `require'
> > from test.rb:1
> >
> > which is weird as I have done this before with other files, it's just
> > this one that it won't find
> >
> in fact from test.rb, I can require 'lib/base', but from b.rb I can't
> require 'base' (with b.rb and base.rb in the same directory) - this is
> very strange behaviour
>
Oops! Of course. "require"'s lookup system bit me again. IIRC it uses
$LOAD_PATH, which contains the usual standard lib directory roots, as well as
the directory of the file first run by Ruby (AFAIK). It *doesn't* contain the
path of library files you may also require. So you have to do require
'lib/base' everywhere.
Is there a good reason for this behaviour? There was a RCR to make the require
load path relative to the currently executing file (rather than only the
originally executing file), but it is branded 'obsolete' and I haven't seen it
rewritten, not even in the rejected RCRs. It's currently here:
http://www.rcrchive.net/rcr/show/170
Wouldn't it be a good idea to revive it?
--
Christophe Grandsire.
http://rainbow.conlang.free.fr
It takes a straight mind to create a twisted conlang.
> Oops! Of course. "require"'s lookup system bit me again
I just added RCR-324.
def require_relative(path)
require File.join(File.dirname(caller[0]), path.to_str)
end