I'm trying to set up a testing environment for a ruby project using Rake and Rspec.
When I try to run "rake" in the console I get this error:
C:/Ruby21-x64/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- spec_helper (LoadError)
from C:/Ruby21-x64/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from spec/numbersTest_spec.rb:1:in `<main>'
rake aborted!
My filetree looks like this:
project
-spec
--numbersTest_spec.rb
--spec_helper.rb
-rakefile
rakefile
begin
require 'rspec/core/rake_task'
task default: %w[test]
task :test do
ruby "spec/numbersTest_spec.rb"
end
end
numbersTest_spec.rb
require "spec_helper"
describe "Imperative" do
perfectImperative(5).should == false
end
require_relative 'spec_helper'
instead of require ... in numbersTest_spec.rb will solve this problem.
The reason is that numbersTest_spec.rb has no clue where to look the required file for. require expects an argument to be available on global require path. To solve this in general, one might update $: (global require path), by e.g.:
$:.unshift "#{`pwd`}".chomp
But in your particular case relative requiring is the silver bullet. In fact, bundler was invented to forget about loading path managing horror.
Related
This is my executable file, named execute:
#!/usr/bin/env ruby
require_relative '../config/environment.rb'
x = Scraper.new
Item.clear_all
x.create_entire_menu
x.start
environment.rb looks like this:
require 'pry'
require 'nokogiri'
require 'open-uri'
require_relative '../lib/cfaprotein.rb'
require_relative '../lib/item.rb'
require_relative '../lib/scraper.rb'
require_relative '../lib/clifunctions.rb'
environment.rb is in config
execute is in bin
cfaprotein.rb is in lib with item.rb, scraper.rb and clifunctions.rb
cfaprotein.rb has the following at the top:
require "cfaprotein/version"
the other three items in lib have the following at the top:
require_relative './environment.rb'
require 'nokogiri'
require 'open-uri'
require 'pry'
config, lib and bin are all in cfaprotein inside of Development.
When I enter:
ruby bin/execute
I get:
/usr/local/rvm/rubies/ruby-
2.3.1/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:54:in
`require': cannot load such file -- cfaprotein/version (LoadError)
from /usr/local/rvm/rubies/ruby-
2.3.1/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:54:in
`require'
from /home/swarbrick85/Development/cfaprotein/lib/cfaprotein.rb:1:in
`<top (required)>'
from /home/swarbrick85/Development/cfaprotein/config/environment.rb:5:in
`require_relative'
from /home/swarbrick85/Development/cfaprotein/config/environment.rb:5:in
`<top (required)>'
from bin/execute:3:in `require_relative'
from bin/execute:3:in `<main>'
What in my code is incorrect and preventing this executable file in bin from executing?
require_relative(string) does the following (emphasis mine):
Ruby tries to load the library named string relative to the
requiring file's path.
Since you're trying to require files from environment.rb using require_relative './foo' it's looking for those files in the same directory as environment.rb (config I believe).
The original question provided a different error message. The new error message points to the same type of problem, which is that when using both require and require_relative you need to understand how the methods work and where your files are located and how to navigate a tree structure.
The link for require_relative is posted but you should also look at require (which is a little more verbose)
Your error message is pretty clear if you weed out the cruft:
cannot load such file -- cfaprotein/version
from /home/swarbrick85/Development/cfaprotein/lib/cfaprotein.rb:1
This would, I believe, expect a version.rb file to live in lib/cfaprotein/version.rb, assuming the lib folder is configured somewhere (maybe a gemspec file, maybe somewhere else) to be in your $LOAD_PATH
If version.rb isn't in the lib/cfaprotein folder, move it there and try it.
If it is in that folder, and still doesn't work, change the require to require_relative './cfaprotein/version.rb' after moving the file.
I am following the gem guide in the bundler documentation.
when i reached the command line part where i have to require 'foodie/cli' on the executable, i keep getting error.
/Users/suyesh/.rbenv/versions/2.3.3/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- foodie/cli (LoadError)
from /Users/suyesh/.rbenv/versions/2.3.3/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from exe/foodie:2:in `<main>'
here is my code in the executable
#!/usr/bin/env ruby
require 'foodie/cli'
Foodie::CLI.start
here is my cli which is in lib/foodie/cli.rb
require 'thor'
require 'foodie'
module Foodie
class CLI < Thor
desc "portray ITEM", "Determines if a piece of food is gross or sdeliciour."
def portray(name)
puts Foodie::Food.portray(name)
end
end
end
What am i doing wrong?
Depending on how you call your executable and how your paths are set up it should work (tm).
Use bundle exec path/to/my/executable in your development environment (assuming you are writing a gem - which is nearly always a good idea). If you followed the other steps in the Bundler tutorial I believe you should have a gemspec file which tells bundler where to look for ([lib/]foodie/cli.rb).
Use ruby -Iinc/lude/dir/for/example/lib path/to/my/executable to tell your ruby to (temporarily) also look in the directory inc/lude/dir/for/example/lib for source files (in your case foodie/cli.rb). Since you are learning bundler, dont use this approach, but it might be interesting to others, and to cast some light in the area where lib-, load- and include-paths live.
I have a directory structure that looks like this:
- lib
- yp-crawler (directory)
- file-a.rb
- file-b.rb
- file-c.rb
- yp-crawler.rb
My lib/yp-crawler.rb file looks like this:
require "yp-crawler/file-c"
require "yp-crawler/file-b"
require "yp-crawler/file-a"
module YPCrawler
end
When I try to run my file at the command line by doing this:
ruby lib/yp-crawler.rb
I get this error:
`require': cannot load such file -- yp-crawler/file-c (LoadError)
from .rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from lib/yp-crawler.rb:1:in `<main>'
What could be causing this?
According to API Dock, require_relative is what you need.
Ruby tries to load the library named string relative to the requiring
file’s path. If the file’s path cannot be determined a LoadError is
raised. If a file is loaded true is returned and false otherwise.
So all you have to do is
require_relative "file-a"
require_relative "file-b"
require_relative "file-c"
Another thing you can do is to add the directory to $LOAD_PATH (this is how most of the gems require files).
$LOAD_PATH (aka $:) is where ruby looks for a file when you call require.
So you can try this code
# lib/yp-crawler.rb
$LOAD_PATH.unshift File.expand_path('..', __FILE__)
# it can be $LOAD_PATH.push also
require "yp-crawler/file-c"
require "yp-crawler/file-b"
require "yp-crawler/file-a"
module YPCrawler
end
P.S.
For example you can see how paperclip does the same thing.
I'm writing a simple ruby application(basically using PORO's). I've added a Gemfile to it and I'm trying to require the pry gem(which is useful for adding breakpoints while debugging, as the application grows) via the Gemfile but I'm unable to require that gem using Bundler.setup, things work fine with Bundler.require.
I'm trying to avoid the use of Bundler.require for reasons stated in this blog for instance.
In the Employee.rb file, I have the below code -
# require 'bundler'
# require 'bundler/setup'
# Bundler.setup(:default, :test, :development)
Bundler.require(:default, :development, :test)
def total_score(scores)
binding.pry #added on purpose , just to see if the app stops at this breakpoint
scores.inject(:+)
end
When I use Bundler.setup(uncommenting the lines commented above), instead of Bundler.require, I get the below error for the command rspec spec . given from my apps root directory-
Failure/Error: expect(total_score(scores)).to eq(16)
NoMethodError:
undefined method `pry' for #<Binding:0x007fbda22b79d0>
# ./Employee.rb:9:in `total_score'
# ./spec/employee_spec.rb:5:in `block (3 levels) in <top (required)>'
Also, just one more note, as per the bundler docs, I tried even doing a require rubygems, but even that doesn't help. Ideally, I would want to avoid using require rubygems for reasons mentioned in this link.
How do I get my app to require the pry gem using Bundler.setup, without doing a require rubygems alongside and also without using Bunder.require ?
Bundler.setup will simply add the gems to the load path, whereas Bundler.require will do both the adding to the load path and the require.
I recommend using Bundler.setup so that your code boots faster. Then when you need to require pry, do this:
require 'pry'
I have a ruby extension written in C++, P4, and it seems to generally work:
I can run irb -Ilib and then require 'P4', and use it
I can execute tests via rake by accessing the shell script in the bin folder of the rake gem, e.g., ${GEM_HOME}/gems/rake-10.3.2/bin/rake test
however, when I access rake via the RubyGems wrapper in my path, e.g., rake test, I get this TypeError
/Users/tjuricek/dev/p4ruby/lib/P4.rb:38:in `require': P4 is not a class (TypeError)
from /Users/tjuricek/dev/p4ruby/lib/P4.rb:38:in `<top (required)>'
from /Users/tjuricek/dev/p4ruby/test/testlib.rb:31:in `require'
from /Users/tjuricek/dev/p4ruby/test/testlib.rb:31:in `<top (required)>'
from /Users/tjuricek/.rvm/gems/ruby-2.1.2/gems/rake-10.3.2/lib/rake/rake_test_loader.rb:15:in `require'
from /Users/tjuricek/.rvm/gems/ruby-2.1.2/gems/rake-10.3.2/lib/rake/rake_test_loader.rb:15:in `block in <main>'
from /Users/tjuricek/.rvm/gems/ruby-2.1.2/gems/rake-10.3.2/lib/rake/rake_test_loader.rb:4:in `select'
from /Users/tjuricek/.rvm/gems/ruby-2.1.2/gems/rake-10.3.2/lib/rake/rake_test_loader.rb:4:in `<main>'
rake aborted!
Then it pops out the ruby command that "failed". If I copy and paste that command and run it, it works.
What I've noticed is that RubyGems creates a fairly simple wrapper script:
#!/usr/bin/env ruby_executable_hooks
#
# This file was generated by RubyGems.
#
# The application 'rake' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0"
if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end
gem 'rake', version
load Gem.bin_path('rake', 'rake', version)
I'm guessing that the last line, load Gem.bin_path... has triggered some kind of misconfiguration of my part in creating my extension, but I have no idea what that would be.
Does anyone have ideas on what might cause require to fail only when run under the RubyGems wrapper?
OK, the way to debug this is to go into a line where you load the file:
require 'P4.so'
And see if it's defined:
puts "P4 #{P4.class}"
require 'P4.so'
In this case, when running under rake directly, it loaded the .gemspec which pulled in a version definition that created (incorrectly, in my case) a P4 module:
module P4
version = VERSION = '3000.0.0.pre0'
end
So, for me the fix included:
Changing module P4 to class P4
Requiring the version definition before my require 'P4.so' statement, typically: require_relative 'P4/version'
Not defining the class in my C++ extension code, but loading it and extending the one defined in my version file:
// Ensure the class has been defined by the version specification
cP4 = rb_path2class("P4");