I'm new to Ruby/JRuby and has been disturbed by the error "LoadError: no such file to load" for many weeks, when I try to directly run the Ruby source code of certain projects.
I downloaded the source code of many Ruby projects from GitHub. Yes only the source code, I didn't install them because my task is more on analyzing the code itself.
Let's take an example, say the project "rqrcode" has the following (simplified) structure:
rqrcode
lib (folder)
rqrcode (folder)
core_ext (folder, with some files inside)
core_ext.rb
qrcode (folder, with some files inside)
qrcode.rb
rqrcode.rb
test (folder)
data.rb
test_rqrcode.rb
So if I run "jruby test_rqrcode.rb" inside the test folder, it throws LoadError at this line inside the file:
require_relative "../lib/rqrcode"
And it also throws LoadError at here, the rqrcode.rb file in lib folder:
require "rqrcode/core_ext"
The error message is
LoadError: no such file to load -- rqrcode/core_ext
require at org/jruby/RubyKernel.java:1054
require at /Users/x5lai/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:36
(root) at /Users/x5lai/Downloads/rqrcode-master/lib/rqrcode.rb:12
require at org/jruby/RubyKernel.java:1054
(root) at /Users/x5lai/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:1
require at /Users/x5lai/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:36
(root) at test_rqrcode.rb:12
I really don't understand why it says it cannot find "rqrcode/core_ext" because that folder does exist there!
Such error doesn't always occur. Sometimes, when I download the source code of other Ruby projects which have similar structure as above, it runs successfully with all the "require", "require_relative" statements.
My friend says it is a Ruby default load path problem. I therefore went to look at what's inside my Ruby load path. It's full of many Ruby files. But, those Ruby projects that run successfully do not have their Ruby files in these load path as well (and they do not use ".unshift" to modify their load path inside their code). So I don't think this is the cause of those failing projects.
Hope there's someone who could clarify my doubts. Maybe it's because of my JRuby configuration? I'm using a Mac. My JRuby version is 1.7.4.
Firstly, ruby load path doesn't include current directory.
You can verify this by running jruby -e "$:" in cmd.
Secondly, when you do require_relative "../lib/rqrcode" in test_rqrcode.rb, you are saying "please find the file at a path relative to myself". Okay, it can find rqrcode.rb right away. However, rqrcode.rb doesn't know where to find its own required files, so it goes to global load path, which is the $:. Since $: doesn't include the lib folder, it cannot find any file residing inside its lib folder, thus return a exception.
Knowing this, you should add local lib directory to the load path in your main script, so every subsequent file will use the same load path environment.
$:.unshift "path_to_the_folder_need_to_include"
On the command line, you can add a folder to the $LOAD_PATH by using the -I switch. For example:
ruby -I lib test/test_qrcode.rb
It is common for ruby projects to add their lib folder to the $LOAD_PATH on their test setup, typically on a file called test_helper.rb or spec_helper.rb (depending on the framework).
Related
I just spent three days of my life banging my head against the wall trying to figure out why a simple 'rake' would not pass my spec file.
If this happens to you: Do not have a space in any folder path!. Seriously. In fact do not have a space in anything you name from here on out.
Here is my console output:
(in /Users/*****/Desktop/Learning Ruby/learn_ruby)
$ rake
/Users/*******/Desktop/Learning Ruby/learn_ruby/00_hello/hello_spec.rb:116:
in `require': cannot load such file -- hello (LoadError)
The failure is caused by the line: require "hello"
This line tells Ruby that it needs to search the load path for a file named hello.rb. However, when it looks at the load path, it can't find that file. You should either remove that line and define your code directly in the spec file, or create a hello.rb file.
Newer versions of RSpec (2.11+ I believe) automatically add subdirectory lib to the load path. Based on your Rakefile it seems you are also loading the current lab directory and the subdirectory solution.
I'm guessing you're expected to put your solution in solution/hello.rb.
What worked for me was changing the require statement to a require_relative
I am using windows and an IDE
I'm new to ruby, but I'm working on my first ruby program. It currently has two files, one is a library of functions (xgync.rb stored in lib) the other is the executable xgync stored in 'bin'. (Project visible here https://bitbucket.org/jeffreycwitt/xgync/src) I've also created a symlink to my /usr/local/bin/xgync so that I can write the command xgync {arguments} from anywhere in the terminal.
The problem seems to be that bin/xgync depends on the library lib/xgync.rb. I've written this dependency in bin/xgync as follows:
$:.unshift(File.dirname(__FILE__) + '/../lib')
require "xgync"
However, i keep getting the following error:
/Users/JCWitt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- xgync (LoadError)
from /Users/JCWitt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /usr/local/bin/xgync:4:in `<main>'
can you see anything wrong with what I've written? Could the symlink be somehow messing things up?
Thanks for your help :)
When using ruby 1.9.x you don't usually alter the path with the $:.unshift when requiring other files in your project.
Instead the best practice is to use require_relative instead.
require_relative '../lib/xgync.rb'
require_relative requires files relative to the file you are currently editing.
But the error you experience appears, because you require a file, which does not exist:
bin/xgync
lib/xgync.rb
These are the files in your project according to your question, and the code-excerpt is from bin/xgync you extended the path to look for files in lib/ but you try to require 'xgync' which is a file, that is not present in lib/, so if you wanted to use this method (instead of require_relative you would have to use require 'xgync.rb'.
I have to run my Ruby script from path that is higher than a script. My Ruby file is in folder lib. I start it in console:
jruby --1.9 -Clib main.rb
but it doesn't work correctly. It changes Dir.pwd, but require doesn't see it and another library DataMapper doesn't see it too.
I know I can add path to be seen by require by -Ilib, but it doesn't fix DataMapper issue and it is ugly I think.
require loads a file from the $LOAD_PATH. If the directory the file you want to load is in is not on the $LOAD_PATH, then require won't find it. If you want to load a file not from the $LOAD_PATH but relative to the position of the currently executing file, you need to use require_relative.
Assuming this is your folder structure
app/other/some_class.rb
app/lib/main.rb
If you navigate to the lib folder
cd app/lib
Then run your main.rb script
jruby main.rb
You can refer to the some_class.rb file in your main.rb script with this line
require "../other/some_class.rb"
I'm writing an IDE in Ruby, and I'm stumped on how to get all my files to get "required" when I run the program on the command line, AND when its installed as a Rubygem.
My Rubygem has an executable file named "vr" in it. I need to make this "vr" executable file "require" all the other files from my project.
When I'm developing, its easy to require all my project's files. I simply "require" a relative path to them like this:
require_all Dir.glob(File.expand_path(File.dirname(__FILE__)) + "/../bin/**/*.rb")
The require_all gem will work perfectly. However, I get a big problem when I install this program as a rubygem. When my "vr" executable is installed by rubygems, it copies the "vr" executable to a special directory:
/home/eric/.rvm/gems/ruby-1.9.3-p125/bin
This directory is totally separated from my project's root folder. And so all my project's files are no longer found by the "require" statement.
Rubygems makes this directory for my gem's root:
/home/eric/.rvm/gems/ruby-1.9.3-p125/visualruby-0.0.55
I need to be able to "require" all the files from that directory into my project.
My solution so far, is to make a second file called "visualruby.rb" that resides in my project's lib folder. It has the require_all statement in it to require all the project files. Then I just have to link the executable to it by adding this code to my "vr" executable file:
base_file = File.dirname(__FILE__) + '/lib/visualruby.rb'
if File.file?(base_file)
require base_file #load from project
else
require 'visualruby.rb' #load from gem
end
It is necessary to check if there's a file named "visualruby.rb" relative to the current file because when I'm developing, it will always find the installed gem's version of "visualruby.rb" So when I make a change to a file, it has no effect. I have to force it to load the version from my development project for changes to work.
Also, my IDE creates projects from scratch, so it would be nice to know the general solution to this. I'd like to have a consistent project file system for all projects, but I'm not sure that's possible. I had the general solution of making a file called "requires.rb" for all projects, but I don't think it will work because every project will have the same filename added to the $LOAD_PATH.
Please help me understand how I can make a consistent file structure where I can develop, and make rubygems.
I found the answer to my own question:
The problem was that I was installing my rubygems using the rubygems API:
Gem::Installer.new(file_name)
This created syslinks that messed up my paths. There is an option to make wrappers instead of syslinks and that seems to be the standard way to install:
Gem::Installer.new(file_name, :wrappers => true)
Now the a wrapper is copied to my gem's bin directory and it uses the correct path. Now I can have a universal file that can be made into a gem. And everything runs the same in development and in the gem.
A happy ending...
I'm using Eclipse with RDT to do some Ruby programming. I'm trying to include a file in another, but require fails. Both files are in the same directory.
The folder hierarchy is set up like this:
Project > src > folder > a.rb b.rb
If I try to require b.rb in a.rb I would use this:
require 'b.rb'
But I get the following error message:
src/folder/a.rb:1:in `require': no such file to load -- b.rb (LoadError)
from src/folder/a.rb:1
If, however, I specify the full path it works:
require '/home/peter/workspace/project/src/folder/b.rb'
But, obviously, using the full path is a bit stupid.
How can I fix this?
Like evoked here, if the ruby editor uses a ProcessBuilder to call ruby, the working directory is whatever it was when the JVM was started.
A good test would be start eclipse from the "Project > src > folder" directory to see if the relative path is seen then.