require in 1.9.2 and 1.9.1

I

Ill Everbe

#i have a file 'user.rb' in the current directory. if i ...

require "user"

#i get this messege (1.9.2 in xp and in windows 7)

##<internal:lib/rubygems/custom_require>:29:in `require': no such file
to
##load -- user_input (LoadError)
## from <internal:lib/rubygems/custom_require>:29:in `require'

##this worked fine in 1.9.1 in xp. and when i

puts $:

#in 1.9.1 the last load path is '.', but '.' is not in load path for
#1.9.2
#works fine if i

require_relative 'user'

#or if i

load 'user.rb'

#a bug or a reason for this behavior? i used the installer. on xp and
on #windows 7
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

#i have a file 'user.rb' in the current directory. if i ...

require "user"

#i get this messege (1.9.2 in xp and in windows 7)

##<internal:lib/rubygems/custom_require>:29:in `require': no such file
to
##load -- user_input (LoadError)
## from <internal:lib/rubygems/custom_require>:29:in `require'

##this worked fine in 1.9.1 in xp. and when i

puts $:

#in 1.9.1 the last load path is '.', but '.' is not in load path for
#1.9.2
#works fine if i

require_relative 'user'

#or if i

load 'user.rb'

#a bug or a reason for this behavior? i used the installer. on xp and
on #windows 7
It's intentional, because "." is relative. So your script would work if you
invoke it from the same dir on 1.9.1, but would break if you invoke it from
the parent dir, because now it is looking in the parent dir for "user"
rather than the dir of the file. So most code that does require statements
like that has a bug there.



IDK what everyone else does, but for me, if its a bigger project, I add the
project root dir to the load path so that require("user") would then work if
user.rb is in the root dir of the project.

For smaller projects, like 1 or 2 files, I just do require("#{File.dirname
__FILE__}/user").

In library code (ie a gem you are writing), I don't think you are supposed
to alter the load path as part of the lib at all, rather do that in your
test code or in your binary, or just rely on rubygems to do it for you. Then
within the library, you can require things relative to the lib directory of
your project, even though the lib itself doesn't alter the path.



I'd be interested to know whether everyone else does it like this also, or
if you guys have discovered some useful pattern I don't know about.
 
S

serialhex

[Note: parts of this message were removed to make it a legal post.]

one method to require them all:
require_relative

ok, maybe not 'all' but it will solve your problem, as long as you're using
1.9. and if you want to be *sure* it will work you can do something like:

if RUBY_VERSION < '1.9'
Kernel.class_eval do
def require_relative str
require './' + str
end
end
end

in your top level lib that gets called first & then you can have all the
require_relative's you want :D

require_relative 'foo'
require_relative 'bar/bak'
require_relative 'animals/magical/fire_breathing_llamas'
# and so on...

have fun!!
hex

p.s. the method i made above is probably seriously cheating & may have some
flaws that one more knowledgeable than i could point out, but ATM it should
work well enough.




It's intentional, because "." is relative. So your script would work if you
invoke it from the same dir on 1.9.1, but would break if you invoke it from
the parent dir, because now it is looking in the parent dir for "user"
rather than the dir of the file. So most code that does require statements
like that has a bug there.



IDK what everyone else does, but for me, if its a bigger project, I add the
project root dir to the load path so that require("user") would then work
if
user.rb is in the root dir of the project.

For smaller projects, like 1 or 2 files, I just do require("#{File.dirname
__FILE__}/user").

In library code (ie a gem you are writing), I don't think you are supposed
to alter the load path as part of the lib at all, rather do that in your
test code or in your binary, or just rely on rubygems to do it for you.
Then
within the library, you can require things relative to the lib directory of
your project, even though the lib itself doesn't alter the path.



I'd be interested to know whether everyone else does it like this also, or
if you guys have discovered some useful pattern I don't know about.



--


No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.
-- Linus Torvalds' follow-up to a question about Linux
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

one method to require them all:
require_relative

ok, maybe not 'all' but it will solve your problem, as long as you're using
1.9. and if you want to be *sure* it will work you can do something like:

if RUBY_VERSION < '1.9'
Kernel.class_eval do
def require_relative str
require './' + str
end
end
end
According to the spec (
https://github.com/rubyspec/rubyspec/blob/master/core/kernel/require_relative_spec.rb#L20),
require_relative
requires relative to the file rather than current dir. I think this means it
would have to be handled by the interpreter because I don't think there is a
way to get the file of the caller.
 
S

Steve Klabnik

[Note: parts of this message were removed to make it a legal post.]

I wrote a gem that backports require_relative (which is the correct way to
do it!) to Ruby 1.8: https://github.com/steveklabnik/require_relative

Having "." in the $: is a security concern. And modifying $: is bad
practice, in general. That's Rubygems' job.
 
S

serialhex

[Note: parts of this message were removed to make it a legal post.]

I wrote a gem that backports require_relative (which is the correct way to
do it!) to Ruby 1.8: https://github.com/steveklabnik/require_relative

Having "." in the $: is a security concern. And modifying $: is bad
practice, in general. That's Rubygems' job.

spiffy!!! thanks steve!
and yeah, don't use my metaprogramming cheat, steve's is MUCH better! (and
much less copy-paste-error prone :D )
hex


--
No. That's it. The cool name, that is. We worked very hard on
creating a name that would appeal to the majority of people, and it
certainly paid off: thousands of people are using linux just to be able
to say "OS/2? Hah. I've got Linux. What a cool name". 386BSD made the
mistake of putting a lot of numbers and weird abbreviations into the
name, and is scaring away a lot of people just because it sounds too
technical.
-- Linus Torvalds' follow-up to a question about Linux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top