Ruby NameError: uninitialized constant - ruby

Just started with Ruby - and already stuck :)
I have a module like this:
module Simple
Env = AppEnv::Environment.new { |env, src|
env.test = src.test
}
class Application < Rails::Application
config.autoload_paths += [
"#{config.root}/app/lib/"
]
end
end
Then a class named simplex.rb in the folder /app/lib
class Simplex
def initialize(some)
puts(some)
end
end
Finally a rake task that looks like:
task(:simple => 'simple:default')
namespace(:simple) {
desc('Run simple, first task')
task(:default => :load) do
Simplex.new('okok')
end
}
However I keep getting the error: NameError: uninitialized constant Simplex
I would have thought the autoload_paths would allow Simplex to be found.
Any ideas what I'm doing wrong - seems really trival but I cant see what.

At the top of your Rake file try adding require "#{Rails.root}/lib/simplex" to bring in your Simplex class. Autoload works like this:
mylibrary.rb
puts "I was loaded!"
class MyLibrary
end
IRB
irb(main):001:0> require 'mylibrary'
I was loaded!
=> true
irb(main):001:0> autoload :MyLibrary, 'mylibrary'
=> nil
irb(main):002:0> MyLibrary.new
I was loaded!
=> #<MyLibrary:0x0b1jef>
I would highly recommend reading this article on what the difference between require and autoload is. More importantly, autoload is in the process of being deprecated because of pitfalls regarding it's lazy loading.

Related

How to use let variables in rails console?

using
rspec 2.6.4
rails 3.1.6
How to use let variables in rails test console?
1.9.3-p0 :032 > let(:user) { create(:user) }
NoMethodError: undefined method `let' for main:Object
Please advise, which library should be required here?
For example: below is executed in console to use stub methods in console.
require 'rspec/mocks/standalone'
Is it possible, to define and call let variables in rails console?
If you are fine with let just creating globals, you can polyfill it like this:
def let(name)
Object.send :instance_variable_set, "##{name}", yield
Object.send :define_method, name do
Object.send :instance_variable_get, "##{name}"
end
end
Usage is the same as rspec:
irb(main):007:0> let(:foo) { 1 }
=> :foo
irb(main):008:0> foo
=> 1
though you really shouldn't be pasting your test code into console to debug it. It's much better to use a breakpoint tool like pry or byebug.
let in rspec is not much more than a lazily executed and memoized method definition. If you must have in the irb you could define it like this:
$ cat let.rb
def let(sym)
$let ||= {}
define_method sym do
$let[sym] ||= yield
end
end
require './let in irb or place it in .irbrc and you have your rspec-like let. Note, that rspec reevaluates let in each new example (it or specify block). Since you don't have them in irb you may need to clear your let cache manually ($let = {}) to force re-evaluation.

Builder's XmlMarkup object loses constants?

I try to upgrade a legacy application from Ruby 1.8.7 to 2.2.3. Afterwards the rendering of builder templates raises errors about unknown classes.
uninitialized constant Builder::XmlMarkup::BigDecimal (NameError)
It seem that within the Builder::XmlMarkup constants like classes disappear.
### example.xml.builder (template) ###
BigDecimal.new('23') # no error
class << xml
def some
data(BigDecimal.new('23')) # raises an error in 2.2.3
end
end
xml.test { xml.some }
### main script ###
require 'rubygems'
require 'builder'
require 'bigdecimal'
def eval_script(file)
xml = Builder::XmlMarkup.new
binding.eval(File.read(file), file)
xml.target!
end
template = File.join(File.dirname(__FILE__), 'example.xml.builder')
puts eval_script(template)
# Ruby 1.8.7 / builder 3.2.0 => <test><data>0.23E2</data></test>
# Ruby 2.2.3 / builder 3.2.2 => ./eval_script.rb:5:in `some': uninitialized constant Builder::XmlMarkup::BigDecimal (NameError)
I found no reason for the behavior. How can I fix the problem?
BTW: I have the same problem with the method lookup, e.g format('%d', 42) which returns the full XML document but doesn't call Kernel.format in Ruby 2.2.3.
I found a workaround overriding const_missing which has to be applied to every template file. It works so far for the legacy application.
### example.xml.builder (template) ###
class << xml
def self.const_missing(name)
super rescue ::Object.const_get(name)
end
def some
data(BigDecimal.new('23'))
end
end
xml.test { xml.some }
But every time the constant BigDecimal is used, it triggers const_missing and then raises a NameError and calls the Object method.

Can't access custom helper functions made within the file - Sinatra

I have this helper within my 'app.rb' file, which is used to get the current user object.
helpers do
def get_current_user(column, value)
user = User.where(column => value).first
return user
end
end
get '/' do
user = get_current_user(:id, params[:id])
end
This is what i did in irb:
irb(main):001:0> require './app'
=> true
irb(main):007:0> user = get_current_user(:id, 2)
NoMethodError: undefined method `get_current_user' for main:Object
from (irb):7
from /usr/bin/irb:12:in `<main>'
I don't understand why i can't access the helper methods from irb. Should i explicitly include the helpers or something? If so, why? Because i put them under the same file, under the same class.
get_current_users is metaprogrammed through the helpers method to be an instance method of App. So, if app.rb looks something like this:
require 'sinatra/base'
class App < Sinatra::Base
helpers do
def get_current_user
puts "here!"
end
end
end
...then from irb you can invoke get_current_user on an instance of App like this:
>> require './app'
>> App.new!.get_current_user
here!
=> nil
>>
(If you're wondering why that's new! and not new like most sane ruby code, read this answer.)

Why do I get the error uninitialized constant Stuff::HTTParty?

I have the HTTParty gem on my system and I can use it from within rails.
Now I want to use it standalone.
I am trying:
class Stuff
include HTTParty
def self.y
HTTParty.get('http://www.google.com')
end
end
Stuff.y
but I get
$ ruby test_httparty.rb
test_httparty.rb:2:in `<class:Stuff>': uninitialized constant Stuff::HTTParty (NameError)
from test_httparty.rb:1:in `<main>'
07:46:52 durrantm Castle2012 /home/durrantm/Dropnot/_/rails_apps/linker 73845718_get_method
$
You have to require 'httparty':
require 'httparty'
class Stuff
include HTTParty
# ...
end
Its all because of the include which exists with in the class
If you include a class with a module, that means you're "bringing in" the module's methods as instance methods.
If you need more clarity on include and require
I request you to refer to this wonderful SO Posting
What is the difference between include and require in Ruby?
Here is an example which I have taken from the same posting
module A
def say
puts "this is module A"
end
end
class B
include A
end
class C
extend A
end
B.say => undefined method 'say' for B:Class
B.new.say => this is module A
C.say => this is module A
C.new.say => undefined method 'say' for C:Class

What's the proper way to mock Rails 3 routes and controllers in a plugin test?

I have an old pre-Rails 3 plugin whose tests will no longer run under Rails 3. The test looks something like this:
class TestController < ActionController::Base
def test_action; render :nothing => true; end
end
TestController.view_paths = [File.dirname(__FILE__)]
ActionController::Routing::Routes.draw {|m| m.connect ':controller/:action/:id' }
class TestControllerTest < ActionController::TestCase
context "test_action" do
should "do something" do
lambda { post :test_action }.should change { Model.count }
end
end
end
Running this test gets me:
uninitialized constant ActionDispatch::Routing::Routes (NameError)
When I use with_routing, which I thought was the new way of doing test routing, like so:
should "do something" do
with_routing do |set|
set.draw { |m| m.connect ':controller/:action/:id' }
lambda { post :test_action }.should change { Model.count }
end
end
I get:
NameError: undefined local variable or method `_routes' for TestController:Class
What am I missing? My test helper requires:
require 'rubygems'
require 'active_record'
require 'active_record/version'
require 'active_record/fixtures'
require 'action_controller'
require 'action_dispatch'
require 'action_view'
require 'test/unit'
require 'shoulda'
require 'mocha'
Ideas? Thanks!
You just need to draw the routes on Rails.application
Rails.application.routes.draw do
# Fun times
end
Edit: Uh, sorry, this won't work on rails 3, but maybe you upgraded already?
https://relishapp.com/rspec/rspec-rails/v/3-6/docs/controller-specs/engine-routes-for-controllers
You didn't specify any test framework, so I'll just mention that RSpec gives you routes method in type: :controller and type: :routing specs so you could do something like
before do
routes.draw do
get ':controller/:action/:id' => 'controller#action'
end
end

Resources