With any given gem is there a way to determine what you need to require to use the gem?
e.g. I had a look at this issue on github and it's clearly not obvious in this case what file needed to be used in the require.
https://github.com/mark-nery/craigslist_scraper/issues/3
You can use Bundler (http://bundler.io/) to manage your gems. You'll want to run bundle init in terminal to create a gemfile.
In the gemfile declare all of your dependent gems, for example:
gem "sqlite3"
gem "pry"
Then on your environment.rb file, require bundler and the gems should all be required. On the last line, require the files that actually contain your code.
require 'bundler/setup'
Bundler.require
Dir[File.join(File.dirname(__FILE__), "[ENTER DIRECTORY PATH HERE]", "ENTER FILE TYPE HERE")].each {|f| require f}
#=> Example: Dir[File.join(File.dirname(__FILE__), "../app/models", "*.rb")].each {|f| require f}
Related
When I use
require 'bundler/setup'
i get Bundler.with_clean_env is not supported.
But when I change this to
require 'bundler'
It supports Bundler.with_clean_env. The confusion that rises here is what is the difference between requiring 'bundler' and 'bundler/setup'?
When referring to gems, require 'foo' would require the foo.rb file that is located in the gem's lib directory. That file usually has the same name as the gem and is responsible for requiring all other necessary files for the gem to function.
When you do require 'foo/bar', you search for lib/foo/bar.rb. In other words, you require only a specific file from that gem and not the whole thing.
The bundler/setup is responsible for loading all gems described in your Gemfile. Bundler.with_clean_env is a completely different functionality, defined in the gem's main file.
Gemfiles can include groups like :test or :development.
require 'bundler/setup' includes all groups from your Gemfile.
require 'bundler' on the other hand lets you specify (via Bundler.setup) which groups to include.
From the documentation:
Configure the load path so all dependencies in your Gemfile can be required
require 'rubygems'
require 'bundler/setup'
require 'nokogiri'
Only add gems from specified groups to the load path. If you want the gems in the default group, make sure to include it
require 'rubygems'
require 'bundler'
Bundler.setup(:default, :ci)
require 'nokogiri'
I have a conflict between rspec and mocha (rspec is not using mocha but other minitest tests are).
If I put mocha in my gemfile (even with require: false) it gets loaded by activesupport/test_case.rb:15
silence_warnings { require 'mocha/setup' }
which then causes rspec to barf.
So, I'd like to just require it in my test_setup file from my system gems but I can't figure out how to load a gem outside of bundler.
Other ideas on how to get these gems to play nice are welcome.
You can use groups in your Gemfile: http://bundler.io/v1.3/groups.html
Require the gems in particular groups, noting that gems outside of a
named group are in the :default group
Bundler.require(:default, :development)
Require the default gems, plus the gems in a group
named the same as the current Rails environment
Bundler.require(:default, Rails.env)
Restrict the groups of gems that
you want to add to the load path. Only gems in these groups will be
require'able
require 'rubygems'
require 'bundler'
Bundler.setup(:default, :ci)
require 'nokogiri'
Could you just install gem and require it?
$ gem install my_gem
and in testfile:
require 'full/path/to/my_gem.rb'
I've got a wrapper for my Gem, socks, inside socks.rb. The entire file is made up of require statements, and a module declaration:
# lib/socks.rb
require 'socks/version'
require 'socks/base_controller'
require 'socks/templates'
require 'socks/tasks'
require 'socks/rake_tasks'
module Socks
end
However, require 'socks/tasks' and socks/rake_tasks is giving me a LoadError: no such file to load -- socks/tasks / rake_tasks error.
Is this a problem with the alignment of the require statements, or just the code?
Code is on Github: https://github.com/Beakr/socks
EDIT: require './socks/tasks' is now working, however require './socks/rake_tasks' is not.
Ruby load files using its $LOAD_PATH. This global array is changed by e.g. rubygems and bundler to allow to find libraries in various locations. In your sock.gemspec you have defined
gem.require_paths = ["lib"]
which means that rubygems will add the lib directory of your gem to ruby's $LOAD_PATH. But it odes so only if you have installed the gem and the gemspec is thus evaluated. If you don't want to install your gem, you can test your gem using
bundle exec irb
in your gem directory, or alternatively by first adapting your $LOAD_PATH in your irb session like so:
$LOAD_PATH.push "/path/to/your/gem/lib"
require 'socks'
I'd like to use bundler/setup to include all of my listed gems but I'm not
succeeding. In go.rb I have
require 'rubygems'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
which fails to require httparty as I thought it would:
$ bundle exec ruby go.rb
go.rb:5:in `<main>': uninitialized constant HTTParty (NameError)
What am I doing incorrectly?
I've created a small project for this question, here.
As far as I understand 'bundler/setup' it only manages the require path (removes the default contents and adds paths for gems that are defined in Gemfile.lock). If you don't require the libraries in question, their contents won't be available.
I believe the problem in your particular case is the following snippet:
File.expand_path('Gemfile', __FILE__)
If I run this from a file called /foo/bin/somescript, what the above code expands to is /foo/bin/somescript/Gemfile. Presumably what you actually want is /foo/bin/Gemfile, which you can get with:
File.expand_path('../Gemfile', __FILE__)
So, repeating your original code with the correction:
require 'rubygems'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
This seems to work for me, to have files in my ~/bin directory have access to libraries I've installed by running bundle install within that directory, as specified by the Gemfile therein.
Does this:
gem 'whenever', require: false
mean that the gem needs to be installed, or does it mean it is not required?
This means install the gem, but do not call require when you start Bundler. So you will need to manually call
require "whenever"
if you want to use the library.
If you were to do
gem "whenever", require: "whereever"
then bundler would download the gem named whenever, but would call
require "whereever"
This is often used if the name of library to require is different than the name of the gem.
You use :require => false when you want the gem to be installed but not "required".
So in the example you gave:
gem 'whenever', :require => false
when someone runs bundle install the whenever gem would be installed as with gem install whenever. Whenever is used to create cron jobs by running a rake task but isn't usually used from within the rails (or other framework if not rails) application.
So you can use :require => false for anything that you need to run from the command line but don't need within your code.
require: false tells Bundler.require not to require that specific gem: the gem must be required explicitly via require 'gem'.
This option does not affect:
bundle install: the gem will get installed regardless
the require search path setup by bundler.
Bundler adds things to the path when you do either of:
Bundle.setup
which is called by require bundler/setup
which is called by bundle exec
Example
Gemfile
source 'https://rubygems.org'
gem 'haml'
gem 'faker', require: false
main.rb
# Fail because we haven't done Bundler.require yet.
# bundle exec does not automatically require anything for us,
# it only puts them in the require path.
begin Haml; rescue NameError; else raise; end
begin Faker; rescue NameError; else raise; end
# The Bundler object is automatically required on `bundle exec`.
Bundler.require
Haml
# Not required because of the require: false on the Gemfile.
# THIS is what `require: false` does.
begin Faker; rescue NameError; else raise; end
# Faker is in the path because Bundle.setup is done automatically
# when we use `bundle exec`. This is not affected by `require: false`.
require 'faker'
Faker
Then the following won't raise exceptions:
bundle install --path=.bundle
bundle exec ruby main.rb
On GitHub for you to play with it.
Rails usage
As explained in the initialization tutorial, the default Rails template runs on startup:
config/boot.rb
config/application.rb
config/boot.rb contains:
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
which does the require 'bundler/setup' and sets up the require path.
config/application.rb does:
Bundler.require(:default, Rails.env)
which actually requires the gems.
Whenever you specify a Gem in your Gemfile and run bundle install, bundler will go and install specified gem and load code for that Gem in you app by putting require 'whenever' this way bundler will load code for all of your Gems in your Rails app, and you can call any method from any Gem without any pain, like you do most of the time.
but Gems like whenever, faker or capistrano are something which you do not need in your app code you need whenever code in your schedule.rb file to manage crons and capistrano code in deploy.rb file to customize deployment recipe so you need not to load code for these gems in your app code
and wherever you want to call any method from these Gems you can manually require thsese gems by yourself by putting require "whenever" . so you put :require => false in your Gemfile for these Gems, this way bundler will install that Gem but not load code for that Gem itself, you can do it whenever you want by simply putting like require 'whenever' in your case.
Analogy to Explain
## Gemfile
gem "university_degree", require: false
gem "dealing_with_boss"
"dealing_with_boss" - loaded into memory and ready to go.
degree gem - not "needed"....you need to manually require it, in order to use it.
In order to require gems in your Gemfile, you will need to call Bundler.require.
You can prevent bundler from requiring the gem with require: false, but it will still install and maintain the gem. Check this out for a more detailed explanation.