Ruby Gemfile gem has different behavior than 'require' gem - ruby-on-rails

I am using the Matrix library in Ruby, and when I use it in irb, it works fine:
2.1.5 :001 > require 'matrix'
=> true
2.1.5 :002 > a=Matrix.build(3,3) { |row,col| row==col ? 0 : 1}
=> Matrix[[0, 1, 1], [1, 0, 1], [1, 1, 0]]
But when I use it from Gemfile, the behavior is different:
Loading development environment (Rails 4.1.8)
2.1.5 :001 > a=Matrix.build(3,3) { |row,col| row==col ? 0 : 1 }
NoMethodError: undefined method `build' for Matrix:Module
I inspected this a bit, and I noticed the require behavior loads a class, while Gemfile loads a module:
Require:
2.1.5 :003 > Matrix.class
=> Class
2.1.5 :004 > Matrix.constants
=> [:EigenvalueDecomposition, :LUPDecomposition, :SELECTORS, :ConversionHelper, :CoercionHelper, :Scalar, :ErrDimensionMismatch, :ErrNotRegular, :ErrOperationNotDefined, :ErrOperationNotImplemented]
Gemfile:
2.1.5 :002 > Matrix.class
=> Module
2.1.5 :003 > Matrix.constants
=> [:VERSION]
How should I include this in my Rails project? I can use require somewhere, but I'd really rather load it as a dependency from Gemfile.

Ruby Gemfile gem has different behavior than 'require' gem
Yes, that's because they are two different things. Adding a gem to your Gemfile does not replace the need to require classes, it only informs the bundler that this gem is needed to run your program. See here for more information about Gemfile and Bundler.

I think you're installing the matrix 'gem' http://rubygems.org/gems/matrix in your gemfile. The matrix class is part of stdlib so you should not need to install a gem for it: http://www.ruby-doc.org/stdlib-2.0/libdoc/matrix/rdoc/Matrix.html. You do need to require it to use it however.
TL/DR: Remove gem 'matrix' from your Gemfile and just use require 'matrix' to use the stdlib matrix implementation rather than the seemingly empty 'matrix' gem Module.

Related

Error using Log4r

I have a problem using Log4r.
uninitialized constant Log4r::Logger::RootLogger
I tried this, but still got an error:
>> require "log4r"
=> true
>> Log4r::DEBUG
NameError: uninitialized constant Log4r::DEBUG
>> Log4r::Logger.root
=> uninitialized constant Log4r::Logger::RootLogger
from /var/lib/gems/1.9.1/gems/log4r-1.1.11/lib/log4r/staticlogger.rb:5:in `root'
from (irb):5
from /usr/bin/irb:12:in `<main>'
Your problem with Log4r::Logger.root is version depending (the actual version 1.1.11 has this problem).
You may use the previous log4r-version 1.1.10:
gem 'log4r', '<=1.1.10' #or '= 1.1.10'
require 'log4r'
Log4r::Logger.root
log4r defines the constants like Log4r::DEBUG with the creation of the first logger.
You need a Log4r::Logger.new('dummy') before you have access to the level constants.
require 'log4r'
p defined? Log4r::INFO #false
Log4r::Logger.new('dummy')
p defined? Log4r::INFO #constant -> is defined
Some background:
There is a constant Log4r::Log4rConfig::LogLevels defining the different levels. The level-constants are defined, when the first logger is created. You may define them also with Log4r.define_levels(*Log4r::Log4rConfig::LogLevels)
This technique allows it to create loggers with different logging levels.
AlthoughLog4r::Logger.root no longer enables the constants, the code included later on in the answer you referred to does introduce the constants:
Log4r.define_levels(*Log4r::Log4rConfig::LogLevels)
per the following:
MacbookAir1:so1 palfvin$ irb
2.0.0p247 :001 > require 'log4r'
=> true
2.0.0p247 :002 > Log4r.define_levels(*Log4r::Log4rConfig::LogLevels)
=> 5
2.0.0p247 :003 > Log4r::DEBUG
=> 1
2.0.0p247 :004 >

NameError: undefined local variable or method `app' for main:Object

I would like to know if when using pry is possible to have access to the variable app?
As an example, when I try to access the root_path I get the following error:
[14] pry(main)> app.root_path
NameError: undefined local variable or method `app' for main:Object
Someone said that "It does now work with pry and 3.2.9". I am using rails 3.2.12, but it doesn't seem to work.
I have gem 'pry' in my GemFile group development and in config/environments/development.rb the following
# Use Pry instead of IRB
silence_warnings do
begin
require 'pry'
IRB = Pry
rescue LoadError
end
end
Yes, it works
➜  MyApp git:(master) rc
Loading development environment (Rails 3.2.13)
[1] pry(main)> app.root_path
=> "/"
I use pry-rails in favor of your overriding of IRB in an initializer.
group :development do
gem 'pry-rails'
end
https://github.com/rweng/pry-rails
Though this is solved, if you don't want to or can't use the 'pry-rails' gem for some reason you can also add the following into your .pryrc file:
if defined?(Rails) && Rails.env
extend Rails::ConsoleMethods
end
You can read more in the pry wiki

strange behaviour - irb and rails console

The irb is giving true at first and then false always for the command require rails.
The rails console is giving false always.
How's this happening?
Please see below cmd-
~/Workspaces/eclipse/image_cropper_ws/image_cropper$ irb
1.9.2-p180 :001 > require 'rails'
=> true
1.9.2-p180 :002 > require 'rails'
=> false
1.9.2-p180 :003 > exit
~/Workspaces/eclipse/image_cropper_ws/image_cropper$ rails console
Loading development environment (Rails 3.2.8)
1.9.2-p180 :001 > require 'rails'
=> false
1.9.2-p180 :002 > require 'rails'
=> false
require returns false when what you're trying to require is already loaded - the first time you require 'rails', it's not loaded, and require returns true.
The second time you require 'rails', it is already loaded and require returns false.
Rails is always loaded in the rails console.
Check the docs for require, it states
Loads the given name, returning true if successful and false if the feature is already loaded.
So the first time you call require in irb it loads and returns true. The second time it is already loaded so it returns false.
When you call rails c it loads irb with your rails environment so it must have already required rails

Rails3 Engine: Gems (paperclip and inherited_resources) not loaded

In my rails3 engine gemfile, I added:
gem 'paperclip'
gem 'inherited_resources'
I also added this to my gemspec:
s.add_dependency "paperclip"
s.add_dependency "inherited_resources"
I then ran bundle install for both my engine and the client app and started up the console for the client app in order to first test paperclip, to which I get:
Using /Users/ynkr/.rvm/gems/ruby-1.9.2-p180 with gemset rails31beta
ynkr % rails c
/Users/ynkr/.rvm/gems/ruby-1.9.2-p180#rails31beta/gems/actionpack-3.1.0.rc4/lib/action_dispatch/http/mime_type.rb:101: warning: already initialized constant YML
Loading development environment (Rails 3.1.0.rc4)
ruby-1.9.2-p180 :001 > b=Blog::Blog.first
Blog::Blog Load (0.2ms) SELECT `blogs`.* FROM `blogs` LIMIT 1
=> #<Blog::Blog id: 1, user_id: 1, context_id: 2, title: "Cmd Line Blog Title", title_for_url: "cmd-line-blog-title", teaser: "This is the teaser for the command line blog", content: "Some content for the cmd line blog", created_at: "2011-06-28 06:06:55", updated_at: "2011-06-28 06:06:55">
ruby-1.9.2-p180 :002 > b.photos
NoMethodError: undefined method `has_attached_file' for #<Class:0x00000102a57fc8>
from /Users/ynkr/.rvm/gems/ruby-1.9.2-p180#rails31beta/gems/activerecord-3.1.0.rc4/lib/active_record/base.rb:1078:in `method_missing'
from /websites/gems/blog/app/models/blog/photo.rb:6:in `<class:Photo>'
from /websites/gems/blog/app/models/blog/photo.rb:1:in `<top (required)>'
from /Users/ynkr/.rvm/gems/ruby-1.9.2-p180#rails31beta/gems/activesupport-3.1.0.rc4/lib/active_support/dependencies.rb:452:in `load'
OK, so it appears the has_attached_file method from the paperclip gem cannot be found. Why? I'm not sure.
Moving on to inherited_resources, I altered a scaffold generated controller to look like the following:
class Blog::ContextsController < InheritedResources::Base
before_filter :redirect_unless_admin
end
and load up the index page for that to which I am greeted (in the logs) with:
Started GET "/blog/contexts" for 127.0.0.1 at 2011-06-28 12:06:25 -0700
ActionController::RoutingError (uninitialized constant InheritedResources):
Rendered /Users/ynkr/.rvm/gems/ruby-1.9.2-p180#rails31beta/gems/actionpack-3.1.0.rc4/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.5ms)
My question is why are these not working? My hunch is that there is something about engines, namespacing and loading up gems that I am totally unaware of.
You need to require each gem within your engine in an initializer file, eg. lib/<your_engine_name>/engine.rb
Bit more of an explanation over here...
Rails Engine - Gems dependencies, how to load them into the application?

'no such file to load -- net/ssh' from rails Controller on Ubuntu

I have a very simple controller:
require 'net/ssh'
class MyController < ApplicationController
def foo
render :text => 'bar'
end
end
But when I request http://server:3000/my/foo I get:
MissingSourceFile in MyController#foo
no such file to load -- net/ssh
The gem is installed
> gem list net-ssh
*** LOCAL GEMS ***
net-ssh (2.0.11)
Also, I tried require 'net/ssh' in IRB, and it works.
MyController works fine on Windows, but fail on Ubuntu.
What can be wrong?
In a project I am working on we have used the config/environment.rb file to hold the gem require stuff. So
Rails::Initializer.run do |config|
# ...
config.gem 'net-ssh'
config.gem 'daemons'
config.gem 'slave'
config.gem 'vpim'
config.gem 'json'
# ...
end
I think you will require 'net-ssh' rather than 'net/ssh'. However we did run into a problem where have a hyphen in the name of the gem led to failures. Then we had to do
config.gem 'Ruby-IRC', :lib => 'IRC'
so that version maybe required for you. So that would be
config.gem 'net-ssh', :lib => 'net/ssh'
in case of rails 3.0
this solution if OK.
add this in the yourapp/Gemfile,
gem 'net-ssh
This may help:
Rails Gem Dependencies and Plugin Errors
This is also worth watching:
Railscasts: Gem Dependencies
In my case, since it's a stand alone ruby app, I only needed to require rubygems.
You can also use Dr Nic's ''gemsonrails'' and load vendored gems as plugins, check:
http://gemsonrails.rubyforge.org
I think, the original problem was that I used normal user instead of root:
$ gem install net-ssh
WARNING: Installing to ~/.gem since /usr/lib/ruby/gems/1.8 and
/usr/bin aren't both writable.
WARNING: You don't have /home/alex/.gem/ruby/1.8/bin in your PATH,
gem executables will not run.
So, I guess, rails could not find this gem.

Resources