Did require become replaced by require_relative for files? - ruby

I'm using Ruby 2.1.5 and whenever I download code that uses require to include a file, I get errors. Changing require to require_relative fixes the problem. For example, if I use the example code from rspec, I get the following error output.
mario#crunchbang:~/projects/rspec_test$ rspec bowling_spec.rb
/home/mario/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- bowling (LoadError)
from /home/mario/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /home/mario/projects/rspec_test/bowling_spec.rb:2:in `<top (required)>'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1105:in `load'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1105:in `block in load_spec_files'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1105:in `each'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1105:in `load_spec_files'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:96:in `setup'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:84:in `run'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:69:in `run'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:37:in `invoke'
from /home/mario/.rvm/gems/ruby-2.1.5/gems/rspec-core-3.1.7/exe/rspec:4:in `<top (required)>'
from /home/mario/.rvm/gems/ruby-2.1.5/bin/rspec:23:in `load'
from /home/mario/.rvm/gems/ruby-2.1.5/bin/rspec:23:in `<main>'
from /home/mario/.rvm/gems/ruby-2.1.5/bin/ruby_executable_hooks:15:in `eval'
from /home/mario/.rvm/gems/ruby-2.1.5/bin/ruby_executable_hooks:15:in `<main>'
Is there something wrong with my Ruby set up or can require no longer be used the way it was in earlier versions of Ruby?

require works exactly the same as it did before: it searches the $LOAD_PATH. What has changed is the default $LOAD_PATH: the current directory . was removed from it, for various maintenance and security reasons.
In almost all cases, you don't want to load a file relative to the current working directory anyway (after all, the CWD is controlled by the user, so you don't even know what it is, how could you then reliably load a file from there?), you want to load it relative to the current file … which is exactly what require_relative does.
By the way: this change was relased 7 years ago, made before that, and announced even before that, I don't know where you are getting that code from, but I would be highly suspicious of code that hasn't been maintained for such an extended period of time (almost 10 years).

Require only searches for files in Ruby's load path. Prior to 1.9, the current folder (.) was included in the load path. See Kernel#require
if you've been writing code with paths relative to the current directory it's normal that require doesn't work. You can either add . to the load path:
rspec -I . my_script.rb
Or as you have found, require_relative resolves the argument relative to the path to the file it is contained in. People also used to use __FILE__ to achieve this before require_relative was available.
You can also add the -I option to your .rspec file or setup your load paths in your spec_helper.rb

When you use require you need to pass the absolute path for the file.
require_relative is working as it depends on the relative path.
Edit the code part where you require the file to absolute file path and it should work well.

Related

Travis CI Build Failure: The command "bundle exec rake" exited with 1

Very new to Travis CI. Build failed with The command "bundle exec rake" exited with 1.
The build was passing before my latest changes which involved using Fileutils to write to gem directory so I'm assuming this is the culprit.
I found this : https://stackoverflow.com/a/40643667/9526393 but still no luck
Any ideas?
Build: https://travis-ci.org/AlphaDaniel/ruby_doc/builds/356485701?utm_source=github_status&utm_medium=notification
Repo: https://github.com/AlphaDaniel/ruby_doc
rake aborted!
Errno::ENOENT: No such file or directory # rb_sysopen - /home/travis/build/AlphaDaniel/ruby_doc/vendor/bundle/ruby/2.2.0/gems/ruby_doc-2.2.0/favs.txt
/home/travis/build/AlphaDaniel/ruby_doc/config/environment.rb:23:in `<top (required)>'
/home/travis/build/AlphaDaniel/ruby_doc/Rakefile:5:in `require_relative'
/home/travis/build/AlphaDaniel/ruby_doc/Rakefile:5:in `<top (required)>'
/home/travis/.rvm/rubies/ruby-2.2.3/bin/bundle:30:in `block in <main>'
/home/travis/.rvm/rubies/ruby-2.2.3/bin/bundle:22:in `<main>'
Errno::ENOENT: No such file or directory # utime_internal - /home/travis/build/AlphaDaniel/ruby_doc/vendor/bundle/ruby/2.2.0/gems/ruby_doc-2.2.0/favs.txt
/home/travis/build/AlphaDaniel/ruby_doc/config/environment.rb:23:in `<top (required)>'
/home/travis/build/AlphaDaniel/ruby_doc/Rakefile:5:in `require_relative'
/home/travis/build/AlphaDaniel/ruby_doc/Rakefile:5:in `<top (required)>'
/home/travis/.rvm/rubies/ruby-2.2.3/bin/bundle:30:in `block in <main>'
/home/travis/.rvm/rubies/ruby-2.2.3/bin/bundle:22:in `<main>'
(See full trace by running task with --trace)
The problem here becomes more clear if you read the error message and the stack trace. Errno::ENOENT: No such file or directory basically means that Ruby can not find a specific file or directory, in your case it's /home/travis/build/AlphaDaniel/ruby_doc/vendor/bundle/ruby/2.2.0/gems/ruby_doc-2.2.0/favs.txt. The last line of code that ran is a call to FileUtils.touch (in config/environment.rb:23).
You may have asked yourself "But shouldn't that create this file if it does not yet exist?". The answer to that is: yes, however only when the parent directories exist as well. When you gem install your gem, those directories will be created for you. This is not the case when you clone your repository and run rake (which is also what Travis automatically does for you when it sees a Ruby project).
To solve that, I recommend you to change the fav_dir method's body to something like this:
File.expand_path("../favs.txt", __dir__)
Looks a bit magic at first glance, but it isn't really: __dir__ is a Ruby method which returns the absolute path of the directory of the file from which this method is called. In this case this would be e.g. /usr/home/foo/dev/ruby_doc/config. Finally, File.expand_path allows us to resolve relative paths, in this case the final result will be /usr/home/foo/dev/ruby_doc/favs.txt.
This way you don't need to specify any absolute paths or make assumptions about a directory layout, and also ensure that the path exists (as the source file's directory and its parent always exist).

Ruby SketchUp LoadError if requiring correct files

I have the problem that I want to require a ruby file.
File overview:
ExcelConversion.rb
main.rb
/classes/excelReader.rb
/classes/elementIdentifier.rb
the main.rb has the header:
require classes/excelReader
require classes/elementIdentifier
the excelReader.rb has the header:
require 'rubyXL
the elementIdentifier.rb has the header:
require 'inifile
The problem is that if I execute the main.rb file, everything works fine. But, as soon as I write require main within the ExcelConversion file I get the error:
Error Loading File ExcelConversion.rb
Error: #<LoadError: cannot load such file -- rubyXL>
C:/Program Files (x86)/SketchUp/SketchUp 2018/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:54:in 'require'
C:/Program Files (x86)/SketchUp/SketchUp 2018/Tools/RubyStdLib/rubygems/core_ext/kernel_require.rb:54:in 'require'
C:/shortenedPath/ExcelConversion/classes/ExcelReader.rb:1:in '<top (required)>'
C:/shortenedPath/ExcelConversion/main.rb:1:in 'require_relative'
C:/shortenedPath/ExcelConversion/main.rb:1:in '<top (required)>'
C:/shortenedPath/ExcelConversion.rb:4:in 'require_relative'
C:/shortenedPath/ExcelConversion.rb:4:in '<top (required)>'
I don't understand how that is even possible to throw an error, since the main.rb runs without problems.
Edit: Solution
I managed to find the solution. SketchUp needs to install the gems separately. This can be achieved through the Ruby Console and the command:
Gem.install "nameOfTheGem"
Then SketchUp stores a copy of the gem within it's own path and one can require it as usual.

Running a single RSpec spec fails with "`require': cannot load such file"

I am trying to get test-first-ruby-master as instructed but I am getting multiple errors. This is the structure of the files/directory in test-first-ruby-master:
Gemfile Gemfile.lock README.md lib spec
lib contains ruby files and spec contains spec files.
I am trying to execute 00_hello_spec.rb file on my terminal but it doesn't work.
What I have tried
require "lib/00_hello.rb"
require_relative "lib/00_hello.rb"
Errors I get
supritkumars-MacBook-Pro:test-first-ruby-master supritkumarshah$ rspec spec/00_hello_spec.rb
/Users/supritkumarshah/Desktop/test-first-ruby-master/spec/00_hello_spec.rb:103:in `require': cannot load such file -- lib/00_hello.rb (LoadError)
from /Users/supritkumarshah/Desktop/test-first-ruby-master/spec/00_hello_spec.rb:103:in `<top (required)>'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/configuration.rb:1226:in `load'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/configuration.rb:1226:in `block in load_spec_files'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/configuration.rb:1224:in `each'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/configuration.rb:1224:in `load_spec_files'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/runner.rb:97:in `setup'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/runner.rb:85:in `run'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/runner.rb:70:in `run'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/lib/rspec/core/runner.rb:38:in `invoke'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/gems/rspec-core-3.2.3/exe/rspec:4:in `<top (required)>'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/bin/rspec:23:in `load'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/bin/rspec:23:in `<main>'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval'
from /Users/supritkumarshah/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>'
Thank you
The require is failing because you're requiring a relative path, 'lib/00_hello.rb', but the directory it's relative to (the root of your project) is not in the list of directories that Ruby is looking in for files to require (the load path, $LOAD_PATH).
There are lots of ways to fix this. Here are some:
Tell rspec to add the root of your project to the load path. Since that's your current directory, you can use .:
rspec -I. spec/00_hello_spec.rb
Change your spec to require_relative '../lib/00_hello'. This works regardless of the current directory or load path — a good idea in command-line programs, although not so important for a learning project.
As B Seven answered, change your spec to require './lib/00_hello'. This requires you to run rspec in the root of your project.
You can even remove the require altogether! When you run rspec, if the current directory has subdirectories named lib and/or spec, rspec adds them to the load path. This also requires you to run rspec in the root of your project. This solution won't work if you need the require when running your program for real (not under rspec).
Note that including the .rb in the filename you required did not cause the problem, but it's not necessary.
Although Dave's answer is correct, I prefer to use:
require './lib/00_hello'
Did you tried adding require 'bundler/setup' at the top of your test helper file?

require: cannot load such file -- one_plus (LoadError)

I am learning custom matchers for rspec from this old, 2008 tutorial - http://www.reactive.io/tips/2008/12/10/up-and-running-with-custom-rspec-matchers/
Project Structure
.
├── one_plus.rb
└── one_plus_spec.rb
I followed all the instructions, but I am not able to understand why I am getting the following error:
rspec one_plus_spec.rb
/home/john/.rvm/rubies/ruby-2.0.0-p598/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- one_plus (LoadError)
from /home/john/.rvm/rubies/ruby-2.0.0-p598/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /home/john/Code/Rspec/Misc/CustomRspecMatchers/one_plus_spec.rb:3:in `<top (required)>'
from /home/john/.rvm/gems/ruby-2.0.0-p598/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `load'
from /home/john/.rvm/gems/ruby-2.0.0-p598/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `block in load_spec_files'
from /home/john/.rvm/gems/ruby-2.0.0-p598/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `each'
from /home/john/.rvm/gems/ruby-2.0.0-p598/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `load_spec_files'
from /home/john/.rvm/gems/ruby-2.0.0-p598/gems/rspec-core-2.14.8/lib/rspec/core/command_line.rb:22:in `run'
from /home/john/.rvm/gems/ruby-2.0.0-p598/gems/rspec-core-2.14.8/lib/rspec/core/runner.rb:80:in `run'
from /home/john/.rvm/gems/ruby-2.0.0-p598/gems/rspec-core-2.14.8/lib/rspec/core/runner.rb:17:in `block in autorun'
john#ubuntu:~/Code/Rspec/Misc/CustomRspecMatchers$
There is no clear answer in other stack overflow questions for this. I don't just want a solution, but I also want to know why this error happens and the concepts that I need to learn to prevent it from happening again.
Try using require_relative instead:
require_relative 'one_plus'
./ (current directory) was removed from the load path in Ruby 1.9.
your load path doesn't include ./ by default, that's why.
Understanding Ruby's load paths includes details as well as solutions.
I personally use require_relative pretty often in specs myself, but you can also modify the load path.

Compass (ruby) encoding error

I had Compass 0.12 (a ruby gem) installed on Ubuntu Oneiric with no problems I have updated to Precise formatting / and keeping /home, so I needed to reinstall ruby (1.9.3).
I get this error now when I compile a SCSS file:
compass watch --trace
Change detected at 12:45:09 to: style.scss overwrite css/style.css
Dear developers making use of FSSM in your projects, FSSM is essentially dead at this point. Further development will be taking place in the new shared guard/listen project. Please let us know if you need help transitioning! ^_^b - Travis Tilley
>>> Compass is polling for changes. Press Ctrl-C to Stop.
ArgumentError on line ["46"] of /usr/lib/ruby/1.9.1/pathname.rb: invalid byte sequence in US-ASCII
/usr/lib/ruby/1.9.1/pathname.rb:46:in `chop_basename'
/usr/lib/ruby/1.9.1/pathname.rb:102:in `cleanpath_aggressive'
/usr/lib/ruby/1.9.1/pathname.rb:90:in `cleanpath'
/usr/lib/ruby/1.9.1/pathname.rb:452:in `relative_path_from'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/path.rb:82:in `split_path'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/path.rb:70:in `run_callback'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/path.rb:56:in `callback_action'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/path.rb:36:in `update'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/state/directory.rb:39:in `block in modified'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/state/directory.rb:37:in `each'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/state/directory.rb:37:in `modified'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/state/directory.rb:18:in `refresh'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/backends/polling.rb:17:in `block (2 levels) in run'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/backends/polling.rb:17:in `each'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/backends/polling.rb:17:in `block in run'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/backends/polling.rb:15:in `loop'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/backends/polling.rb:15:in `run'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm/monitor.rb:26:in `run'
/var/lib/gems/1.9.1/gems/fssm-0.2.9/lib/fssm.rb:70:in `monitor'
/var/lib/gems/1.9.1/gems/compass-0.12.1/lib/compass/commands/watch_project.rb:89:in `perform'
/var/lib/gems/1.9.1/gems/compass-0.12.1/lib/compass/commands/base.rb:18:in `execute'
/var/lib/gems/1.9.1/gems/compass-0.12.1/lib/compass/commands/project_base.rb:19:in `execute'
/var/lib/gems/1.9.1/gems/compass-0.12.1/lib/compass/exec/sub_command_ui.rb:43:in `perform!'
/var/lib/gems/1.9.1/gems/compass-0.12.1/lib/compass/exec/sub_command_ui.rb:15:in `run!'
/var/lib/gems/1.9.1/gems/compass-0.12.1/bin/compass:29:in `block in <top (required)>'
/var/lib/gems/1.9.1/gems/compass-0.12.1/bin/compass:43:in `call'
/var/lib/gems/1.9.1/gems/compass-0.12.1/bin/compass:43:in `<top (required)>'
/usr/local/bin/compass:19:in `load'
/usr/local/bin/compass:19:in `<main>'
(The "Dear developers" message is part of the output).
This error doesn't appear the first time I make a change to the scss file, but the second.
In addition, compass "eats" one "s" in some files and, instead of compiling them as "style.css" (what it should be from the file's name) it does as "tyle.css".
I've spend 3 hours looking at similar problems here but I couldn't solve it. I tried including # encoding: utf-8 on the top of some files with no luck.
Please explain step by step what should I do, since I am a total noob with Ruby (I just use it because of SASS).
I think there is some problem with the pathname, maybe it contains an invalid non-ASCII sequence; probably the eaten "s" is the problem, maybe it is an invalid character, or maybe a character near to it; try to ensure path is ASCII.
Or maybe a bug in precise readline package? Try to install ruby 1.9.3 via RVM, RVM should use readline bundled with it (see the comments below for details)
From what I can see, the file in question pathname.rb contains this function that seems to be where the trouble is:
def chop_basename(path)
base = File.basename(path)
if /\A#{SEPARATOR_PAT}?\z/o =~ base
return nil
else
return path[0, path.rindex(base)], base
end
end
private :chop_basename
Here's a link to a similar question with the same issue:
Ruby on Rails application won’t start using Passenger when there are non-ASCII characters in the app path
So the fix is clearly to stick with us-ascii pathnames.
Here's a snippet from the doc on that class:
Pathname represents a pathname which locates a file in a filesystem. The pathname depends on OS: Unix, Windows, etc. Pathname library works with pathnames of local OS. However non-Unix pathnames are supported experimentally.
As to why it worked before and doesn't now, that's hard to say. It's possible that some other library on your system changed, or that the upgrade to ruby 1.9.3 caused a minor change that introduced the error.

Resources