What's the difference between the require and gem methods?
For example, what's the difference betweenrequire 'minitest' and gem 'minitest'?
Say you have two versions of the gem foo installed:
$ gem list foo
*** LOCAL GEMS ***
foo (2.0.1, 2.0.0)
If you use only require, the newest version will be loaded by default:
require 'foo' # => true
Foo::VERSION # => "2.0.1"
If you use gem before calling require, you can specify a different version to use:
gem 'foo', '2.0.0' # => true
require 'foo' # => true
Foo::VERSION # => "2.0.0"
Note: using gem without subsequently calling require does not load the gem.
gem 'foo' # => true
Foo::VERSION # => NameError: uninitialized constant Foo
Kernel#require activates the latest version of a gem.
Kernel#gem (added by RubyGems) allows activation of specific gem versions.
Related
When I start server with padrino start, this error happens:
C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/padrino-core-0.15.1/lib/padrino-core/application.rb:32:in `concat': can't modify frozen Array:
[/\\/sinatra(\\/(base|main|show_exceptions))?\\.rb$/,
/lib\\/tilt.*\\.rb$/, /^\\(.*\\)$/,
/rubygems\\/(custom|core_ext\\/kernel)_require\\.rb$/,
/active_support/, /bundler(\\/(?:runtime|inline))?\\.rb/,
/<internal:/] (FrozenError)
And my gemfile is...
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Padrino supports Ruby version 2.2.2 and later
ruby '2.7.0'
# Distribute your app as a gem
# gemspec
# Server requirements
# gem 'thin' # or mongrel
# gem 'trinidad', :platform => 'jruby'
# Optional JSON codec (faster performance)
# gem 'oj'
# Project requirements
gem 'rake'
gem 'bcrypt'
gem 'activesupport'
# Component requirements
gem 'erubi', '~> 1.6'
gem 'activerecord', '>= 3.1', :require => 'active_record'
gem 'sqlite3'
# Test requirements
# Padrino Stable Gem
gem 'padrino', '0.15.1'
The error is being raised here when padrino tries to modify the CALLERS_TO_IGNORE array.
The root cause it is a change in sinatra 3, the CALLERS_TO_IGNORE array was not frozen on version 2.2.2.
Given that last version of padrino was released on April 26, 2021, I would not expect it to be solved soon.
My advice is to pin the version of sinatra in your gemfile gem 'sinatra', '2.2.2'.
Noticed today that running require fileutils in pry always returns false. But, if I do the same thing in irb, it returns true. Furthermore, when fileutils is set to false, it still works!
First I thought that fileutils is a dependency of pry, and that would explain why it is already required. But it's not. Am I missing something fundamental here?
[07:40] ~/Desktop $ gem dependency pry
Gem pry-0.10.2
bundler (~> 1.0, development)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
Gem pry-theme-1.1.3
bundler (~> 1.0, development)
coderay (~> 1.1)
json (~> 1.8)
Example:
First I use pry to make some folders. Is fileutils already loaded? Notice that even though fileutils returns false it still works:
[07:44] ~/Desktop $ ls
[07:44] ~/Desktop $ ########## (nothing)
[07:44] ~/Desktop $ pry
[1] pry(main)> require 'fileutils'
=> false
[2] pry(main)> FileUtils::mkdir_p 'foo'
=> ["foo"]
[3] pry(main)> Dir.mkdir('bar')
=> 0
[4] pry(main)> Dir["/home/caveman/Desktop/*"]
=> ["/home/caveman/Desktop/foo", "/home/caveman/Desktop/bar"]
I remove the folders I just created...
[07:48] ~/Desktop $ rm -r *
[07:48] ~/Desktop $ ls
[07:48] ~/Desktop $ ########## (nothing again)
Now I try again with irb:
[07:49] ~/Desktop $ irb
irb(main):001:0> require 'fileutils'
=> true
irb(main):002:0> FileUtils::mkdir_p 'foo2'
=> ["foo2"]
irb(main):003:0> Dir.mkdir 'bar2'
=> 0
irb(main):004:0> Dir["/home/caveman/Desktop/*"]
=> ["/home/caveman/Desktop/bar2", "/home/caveman/Desktop/foo2"]
Here's what blows my mind. Even after I set 'fileutils' to false in irb, it still works:
irb(main):005:0> require 'fileutils'
=> false
irb(main):006:0> FileUtils::mkdir_p 'foo3'
=> ["foo3"]
irb(main):007:0> Dir["/home/caveman/Desktop/*"]
=> ["/home/caveman/Desktop/foo3", "/home/caveman/Desktop/bar2", "/home/caveman/Desktop/foo2"]
First off, FileUtils isn't a gem, so it will never show up as a gem dependency.
Secondly, the return value of require doesn't tell you whether requiring succeeded or not (if it fails, it will raise an exception). false just means it's already loaded. Your statement
Even after I set 'fileutils' to false in irb
doesn't make sense. You're not setting anything at all, you're just calling require again and the second time it returns false.
What you've observed just means that pry (or one of its dependencies) either loads FileUtils directly or loads a bit of the standard library that loads FileUtils. It looks like pry requires 'tempfile', which itself requires 'tmpdir' which in turn requires 'fileutils'.
Please help,
I am doing a project with rails and neo4j with the neo4j.rb gem by ronge. I can get generator and CRUD working with Neo4j. But, everytime I run 'rspec' tests, there is method missing error within the configure block of RSpec within spec_helper.
Can anyone helps me figure this out?
Thanks so much!!
Rails and JRuby version.
saasbook#saasbook:~/temp$ rails -v
Rails 3.2.17
saasbook#saasbook:~/temp$ ruby -v
jruby 1.7.10 (1.9.3p392) 2014-01-09 c4ecd6b on Java HotSpot(TM) Client VM 1.7.0_51-b13 [linux-i386]
Create Rails App
rails new myapp -m http://andreasronge.github.com/neo4j/rails.rb -O -T
Gemfile
source 'https://rubygems.org'
gem 'rails', '3.2.17'
gem 'jruby-openssl'
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'therubyrhino'
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
group :development, :test do
gem "rspec-rails"
end
gem "neo4j"
Then,
saasbook#saasbook:~/test/myapp$ rails g rspec:install
create .rspec
create spec
create spec/spec_helper.rb
saasbook#saasbook:~/test/myapp$ rails g model testnode
invoke neo4j
create app/models/testnode.rb
invoke rspec
create spec/models/testnode_spec.rb
When I run rspec, here is the error:
saasbook#saasbook:~/test/myapp$ rspec
NoMethodError: undefined method `fixture_path=' for #<RSpec::Core::Configuration:0xbcf6bf>
(root) at /home/saasbook/test/myapp/spec/spec_helper.rb:21
configure at /home/saasbook/.rvm/gems/jruby-1.7.10/gems/rspec-core-2.14.7/lib/rspec/core.rb:120
(root) at /home/saasbook/test/myapp/spec/spec_helper.rb:11
require at org/jruby/RubyKernel.java:1083
(root) at /home/saasbook/test/myapp/spec/models/testnode_spec.rb:1
load at org/jruby/RubyKernel.java:1099
(root) at /home/saasbook/test/myapp/spec/models/testnode_spec.rb:1
each at org/jruby/RubyArray.java:1613
(root) at /home/saasbook/.rvm/gems/jruby-1.7.10/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:1
load_spec_files at /home/saasbook/.rvm/gems/jruby-1.7.10/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896
load_spec_files at /home/saasbook/.rvm/gems/jruby-1.7.10/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896
run at /home/saasbook/.rvm/gems/jruby-1.7.10/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:22
Also, here is the generated spec_helper.rb file:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
Resolved, see comments on the questions.
:fixture_path and :use_transactional_fixtures are two settings added by rspec-rails ONLY under the presence of ActiveRecord. So of course they are method missing. Just comment them out, you don't need them if you use Neo4j.rb
While trying to solve Gem found in irb, not in Ruby , I tried seeing what effect require 'rubygems' had on my own installation:
$ irb
irb(main):001:0> RUBY_VERSION
=> "1.8.7"
irb(main):002:0> $:
["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/x86_64-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/x86_64-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/x86_64-linux", "."]
=> nil
irb(main):003:0> require "rubygems" # Hasn't been required already
=> true
irb(main):004:0> require "rubygems" # Will return false, because it's already been required
=> false
irb(main):005:0> $: # Same as before
=> ["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/x86_64-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/x86_64-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/x86_64-linux", "."]
If requring rubygems doesn't modify $:, then how does it help find files? Does it monkeypatch require? If so, what variable does it use to find rubygem-installed libraries?
Here's the current version of the relevant source: https://github.com/rubygems/rubygems/blob/02ead548e38ff90923444fa7c0ff9f6a5dbd87b0/lib/rubygems/custom_require.rb. (Edit: here's an earlier version (1.5.2) that more clearly expresses what happens.)
The docs say:
When RubyGems is required, Kernel#require is replaced with our own which
is capable of loading gems on demand.
When you call require 'x', this is what happens:
If the file can be loaded from the existing Ruby loadpath, it
is.
Otherwise, installed gems are searched for a file that matches.
If it's found in gem 'y', that gem is activated (added to the
loadpath).
The normal require functionality of returning false if
that file has already been loaded is preserved.
It does this by opening up module Kernel and aliasing the original require with alias gem_original_require require, then redefining require to first call the original version, and look at the gems if that doesn't work.
So the load path is only changed when you require a gem:
ruby-1.8.7-p330 :002 > $:.length
=> 9
ruby-1.8.7-p330 :003 > require 'rubygems'
=> true
ruby-1.8.7-p330 :004 > $:.length
=> 9
ruby-1.8.7-p330 :005 > require 'haml'
=> true
ruby-1.8.7-p330 :006 > $:.length
=> 10
Specifically, the ruby-oci8 gem. I have both 1.0.7 and 2.0.4 installed. I want 1.0.7.
I can just require oci8, but I don't get the version I want.
irb(main):001:0> require 'oci8'
=> true
irb(main):002:0> OCI8::VERSION
=> "2.0.4"
I can require using the full path to the file, which works, but is not going to be portable:
irb(main):001:0> require 'C:\Ruby\lib\ruby\gems\1.8\gems\ruby-oci8-1.0.7-x86-mswin32-60\lib\oci8'
=> true
irb(main):002:0> OCI8::VERSION
=> "1.0.7"
I can use the gem command to ask for the version I want, but it doesn't appear to actually load the library:
irb(main):001:0> gem 'ruby-oci8', :lib=>'oci8', :version=>'=1.0.7'
=> true
irb(main):002:0> OCI8::VERSION
NameError: uninitialized constant OCI8
from (irb):2
I would definitely favor this last approach if would load the library, rather than just confirming that it's present on my system. What am I missing?
My problem was twofold:
1) confusing gem command syntax with that used in config.gem lines in a rails environment.rb configuration file.
2) failing to issue a require command after the gem command.
Proper usage in a script is:
gem 'ruby-oci8', '=1.0.7'
require 'oci8' # example is confusing; file required (oci8.rb) is not
# same name as gem, as is frequently the case
Proper usage in a rails 2.3.x environment.rb file is:
config.gem "ruby-oci8", :version=>'1.0.7'
Thanks to the folks at http://www.ruby-forum.com/topic/109100
Try the following syntax (instead of require):
require_gem 'RMagick' , '=1.10'
require_gem 'RMagick' , '>=1.10'
require_gem 'rake', '>=0.7.0', '<0.9.0'