strange behaviour - irb and rails console - ruby-on-rails

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

Related

Permanently add a directory to Ruby $LOAD_PATH

I'd like the option to use awesome_print in every IRB console or Rails console.
The IRB console is pretty much working satisfactorily right now. If I run irb, I can type require 'awesome_print' and it works.
The Rails console isn't as easy. require 'awesome_print' doesn't work. I apparently have to do this:
> $LOAD_PATH << '~/.rvm/gems/ruby-2.1.8/gems/awesome_print-1.7.0/lib'
After that, require 'awesome_print' works fine.
But I definitely don't want to have to type $LOAD_PATH << '~/.rvm/gems/ruby-2.1.8/gems/awesome_print-1.7.0/lib' and then require 'awesome_print' every single time I open a Rails console just to be able to use awesome_print. That seems ridiculous.
So, how can I permanently add a path to Ruby's $LOAD_PATH?
Note: I don't want to add awesome_print to the Gemfile of any particular project. I want awesome_print to be available to all my Ruby/Rails projects.
You could simply use a a ~/.irbrc file and do:
require 'awesome_print'
Now, open up another IRB prompt:
irb(main):003:0> ap hash
{
"a" => "b"
}
Edit: this isn't working in rails, seems to be a known issue.
puts the following to the .irbrc:
to_load = %w[
awesome_print
coderay
hirb
pry
pry-doc
pry-remote
pry-theme
slop
yard
].join('|')
regexp = Regexp.new( "(#{to_load})" )
Gem.path.each do |path|
Dir.new("#{path}/gems").each do |gem_path|
next if %w[ . .. ].any?{ |d| gem_path == d }
new_el = "#{path}/gems/#{gem_path}/lib"
$LOAD_PATH << new_el if new_el =~ regexp
end
end

Why are my Open-uri/Nokogiri requests taking longer (>30s) on my Heroku rails console than on my local rails console (<1s)?

I have rails 4.2.1 installed.
On my local rails console:
2.2.1 :001 > require 'nokogiri'
=> true
2.2.1 :002 > require 'open-uri'
=> true
2.2.1 :003 > doc = Nokogiri::HTML(open('http://sfbay.craigslist.org/search/fuo?srchType=T&query=knoll'))
And the response time is ~ 1s.
On the heroku rails console, I just run:
doc = Nokogiri::HTML(open('http://sfbay.craigslist.org/search/fuo?srchType=T&query=knoll'))
And the response time is over 30s.
I get what I'm expecting in both places, but the response time on Heroku causes my app to time out in production.

Ruby Gemfile gem has different behavior than 'require' gem

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.

Where is Rails.application defined?

Out of curiosity, where is Rails.application defined? If I do this in irb in a Rails-powered app, I got an error:
$ irb
1.9.3-p327 :001 > require 'rails/application'
=> true
1.9.3-p327 :002 > class App < Rails::Application; end
NoMethodError: undefined method `application' for Rails:Module
I have tried requiring more, like active_support and rails/railtie/configuration but no luck.
The purpose of this is to load a minimal Rails env where I can test an ActiveRecord::Base helper :)
Usually when working with Rails you use rails console instead of IRB. When you run rails console it will boot up your Rails application.
FWIW, Rails.application is defined in railties:
lib/rails.rb

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 >

Resources