Can't get RSpec to work -- 'require': cannot load such file - ruby

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

Related

Why doesn't Ruby 'require' allow relative paths?

This SO post sort of answers the question by claiming that require will only search relative to the path that the script was run in. But this really does not appear to be true. I will elaborate.
I created a quick C extension and compiled it to mytest.so. Then, in the same directory I fired up irb.
irb(main):009:0> require 'mytest.so'
LoadError: cannot load such file -- mytest.so
This is expected because the claim in the other answer is that require is searching relative to where irb was run from. In my case that would be /usr/bin/irb. So I tried the required_relative solution from the other question:
irb(main):006:0> require_relative './mytest.so'
LoadError: cannot infer basepath
No luck. And FYI - mytest.so is tab-completing here so irb is clearly aware it is in the current working directory. Furthermore, I can easily prove this:
irb(main):004:0> system("pwd")
/home/mike/Documents/ruby_test
# => true
irb(main):005:0> File.expand_path("./")
# => "/home/mike/Documents/ruby_test"
Okay final test, I will assume that irb is being executed in /usr/bin despite the evidence pointing against that.
irb(main):011:0> require '../../home/mike/Documents/ruby_test/mytest.so'
LoadError: cannot load such file -- ../../home/mike/Documents/ruby_test/mytest.so
I would greatly appreciate if anyone can shed some light on what is going on with require?
BTW, I am aware I can solve this issue by giving the exact file path. This question is about trying understand what is happening beneath the surface.
require '/home/mike/Documents/ruby_test/mytest.so' # this works
tl;dr: IRB is special and has some odd rules. Ruby in general works just fine with relative paths.
require will search the load path (which you can see by inspecting $: or $LOAD_PATH). This will not include the directory that you launched IRB from:
> $:
=> ["/usr/local/rvm/rubies/jruby-head/lib/ruby/2.2/site_ruby", "/usr/local/rvm/rubies/jruby-head/lib/ruby/stdlib"]
So there's no joy there, unless you explicitly add your directory to the load path. This is what Rubygems and Bundler spends most of their time doing - they manage the load paths for gems so you don't have to worry about it. However, this doesn't help you with single files.
Additionally, require_relative will search from the directory that __FILE__ is in, but in IRB, this is a non-directory (irb) value! This is why you get the "can't infer basepath" issue when trying require_relative from IRB; since the currently executing file, __FILE__, isn't a proper path, require_relative can't figure out where to start from.
When you are not running from IRB, this isn't really an issue; require_relative 'mytest.so' should work just fine when you execute it in a script, since the currently-executing script will populate __FILE__. That is, if you have loader.rb and mytest.so and execute loader via ruby loader.rb, require_relative should work just fine.
If you want to run this in IRB, consider something like:
require "#{__dir__}/mytest.so"
which will expand out to the current working directory, which should by default be the directory you've launched it from. I would recommend that you not do this in a script, though, since it depends on __dir__ not having been changed, and that may be difficult to guarantee.
From the documentation:
Loads the given name, returning true if successful and false if the
feature is already loaded.
If the filename does not resolve to an absolute path, it will be
searched for in the directories listed in $LOAD_PATH ($:).
If the filename has the extension “.rb”, it is loaded as a source
file; if the extension is “.so”, “.o”, or “.dll”, or the default
shared library extension on the current platform, Ruby loads the
shared library as a Ruby extension. Otherwise, Ruby tries adding
“.rb”, “.so”, and so on to the name until found. If the file named
cannot be found, a LoadError will be raised.
For Ruby extensions the filename given may use any shared library
extension. For example, on Linux the socket extension is “socket.so”
and require 'socket.dll' will load the socket extension.
The absolute path of the loaded file is added to $LOADED_FEATURES
($"). A file will not be loaded again if its path already appears in
$". For example, require 'a'; require './a' will not load a.rb again.
The answer to your question is that it simply isn't designed to.
You could use require_relative if you want to require files relative to your files' path.
You could add your projects library folder to the $LOAD_PATH to get the functionality you are asking for, that is, require 'my_library'
In IRB for loading local files, you may want to use load instead, as it gives you the ability to load file/library multiple times, where require will load the file/library only once. The __FILE__ variable works in IRB just like it should. It is the identification of the file (in this case the open process) in which the variable is invoked.

Why am I getting this 'no such file to load' error with rake command?

I am working on lab 21 at this site. The directory path I have added the rakefile to is:
Now, it says I should be able to run the 'hello' program by invoking the 'rake' command from my console. However, when I enter the command I get the following back:
The line in question from the rakefile is as:
require './lib/hello'
I have followed this tutorial to the letter, so I don't believe it is a mistake with the filepath. But to be sure, I even reversed the directory names of hello and lib, like this, to be sure:
The tutorial is on git, not rakefiles, so it's not exactly a pressing issue, but it sure is annoying to not be able to figure it out.
Both images have conflicting directory structure, not sure which one's right. But, since your Rakefile and hello.rb are in the same directory, you need to change :
require ./lib/hello.rb
to
require ./hello.rb
It looks like you're already in the ./lib directory. Remove ./lib from the require:
require './hello'

LoadError occurs when directly running Ruby source code in existing projects

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).

How to I load a gem from source?

I have git cloned a repo from Github, now I want to experiment with it, as in I want to poke around the code and mess with it. I've created a file test.rb that should load this gem, but I want to load my locally checked out version, what's the right way to do this?
Right now I'm just using a bunch of "require_relative 'the_gem_name/lib/file'", which feels wrong.
When you require 'foo' Ruby checks all the directories in the load path for a file foo.rb and loads the first one it finds. If no file named foo.rb is found, and you’re not using Rubygems, a LoadError is raised.
If you are using Rubygems (which is likely given that it is included in Ruby 1.9+), then instead of immediately raising a LoadError all the installed Gems are searched to see if one contains a file foo.rb. If such a Gem is found, then it is added to the load path and the file is loaded.
You can manipulate the load path yourself if you want to ensure a particular version of a library is used. Normally this isn’t something that’s recommended, but this is the kind of situation that you’d want to do it.
There are two ways of adding directories to the load path. First you can do it in the actual code, using the $LOAD_PATH (or $:) global variable:
$LOAD_PATH.unshift '/path/to/the/gems/lib/'
require 'the_gem'
Note that you normally want to add the lib dir of the gem, not the top level dir of the gem (actually this can vary depending on the actual Gem, and it’s possible to need to add more than one dir, but lib is the norm).
The other way is to use the -I command line switch to the ruby executable:
$ ruby -I/path/to/the/gems/lib/ test.rb
This way might be a bit cleaner, as normally you don’t want to be messing with the load path from inside your code, but if you’re just testing the library it probably doesn’t matter much.
Following apneadiving's suggestion in the comments, I created a Gemfile and added this line
source "http://rubygems.org"
gem 'gem_name', path: '~/path/to/gem/source/folder'
Then bundle install, and bundle exec ruby test.rb and it worked.

ruby require not working

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'.

Resources