I'm trying to access a method from a module in one of my spec helpers
I include the module in the test helper
module Support
class RestHelper
include Rest::Rest
def create_rest_client_for_ifa
# Call method from module
create_rest_client(uname, pword)
end
end
end
But I keep getting a NoMethodError when I run my spec:
Failure/Error: #rest_client = Support::RestHelper.create_rest_client_for_ifa
NoMethodError:
undefined method `create_rest_client' for Support::RestHelper:Class
Here is my module code:
module Rest
module Rest
.
.
def create_rest_client(uname, pword)
# code
end
.
.
end
end
It seems to work fine when I test it in the rails console
$ RAILS_ENV=test rails c
irb> include Rest::Rest
=> Object
irb> create_rest_client(uname, pword)
What am I missing? Why can't I access the method from the test helper?
Any help will be much appreciated.
As I remember, include adds module methods as instance methods, extend adds them as class methods.
Related
I'm trying this:
require 'minitest'
Minitest::Assertions::assert_equal(1, 1)
Doesn't work:
NoMethodError: undefined method `assert_equal' for Minitest::Assertions:Module
What is the right way? The method does exist.
module Assertions
extend Minitest::Assertions
class << self
attr_accessor :assertions
end
self.assertions = 0
end
Assertions.assert(true)
Assertions.assert(false)
The Minitest::Assertions module expects to be able to increment an instance accessor named assertions.
http://docs.seattlerb.org/minitest/Minitest/Assertions.html
module Add
def addition
sum=1+2
puts sum
end
a=Add.addition
Can anyone tell me what I'm missing and why I am getting this error->
undefined method `addition' for Add:Module (NoMethodError)
You are confusing class methods and instance methods. Your definition:
module Add
def addition
...
end
end
defines methods on instances of Add whereas you called a method on the module Add. If you want to define a class/module method, you need to define like:
module Add
def self.addition
...
end
end
If you want to be able to call it directly, define it as a directly accessible method:
def self.addition
# ...
end
Or you can always rework this using:
module Add
# ...(methods)...
extend self
end
Where that will automatically promote all mixin-type methods as being directly accessible.
You can also tag them more selectively like this:
module Add
def addition
# ...
end
module_method :addition
end
That method is then available either as Add.addition or if some other module or class calls include Add.
Here's a rough structure of a Sinatra API project I'm working on:
api.rb(main program calling methods on different API endpoints. This is also the project root level of hierarchy)
methods/v1/auth.rb
lib/api_helpers.rb
The file auth.rb has code in the following structure:
module V1
require './lib/api_helpers'
end
module V1::Auth
def register
do_something #a method defined in api_helpers.rb
end
end
Relevant part of api_helpers.rb :
helpers do
def do_something
#lots of blah
end
end
The /register endpoint in api.rb makes a call to V1::Auth.register, the file gets invoked without raising a LoadError for the api_helpers.rb file required, but throws an undefined method error when do_something is called.
How do I work in a namespaced structure like this and be able to access methods from files elsewhere in the hierarchy?
Using Ruby 2.3.1
In this case is Method register a instance method, so if you wanna to call it like V1::Auth.register you must set it like class method.
EDIT
You must to add do_something to V1::Auth module to call it directly.
api_helpers.rb
def do_something
puts "I do something"
end
api.rb
module V1
end
module V1::Auth
require './lib/api_helpers'
def self.register
puts "Register"
do_something
end
end
V1::Auth.register
# => Register
# => I do something
So why is this happening? It has to be a namespace error, I just don't understand where it is. I add a method to Fixnum like so in a file file.rb
module M
class Fixnum
def foo
return true
end
end
end
then I'll make a test like so:
require 'minitest/autorun'
require './file.rb' #the path is correct
class SomeTest < MiniTest::Test
def test_foo
assert 3.foo
end
end
which will in turn throw a
NoMethodError: undefined method `foo' for 3:Fixnum
when I run the test, and I am left scratching my head - even if I include M to include the module (applying the namespace?) for the test it still throws the error. I can use custom classes just fine, it's only when I try to add a method to an existing "open class".
Yes, you have defined your own M::Fixnum class which actually has nothing to do with ::Fixnum in the global namespace. The following will solve an issue:
module M
class ::Fixnum
def foo
return true
end
end
end
5.foo
#⇒ true
Please note, in the code above module M has no sense, since the code nevertheless monkey-patches the global Fixnum. The code is here just to show how you would monkey-patch the global class from inside another module code.
Plus, Ruby2 introduced refinements, which are likely what you are intended to use.
I have a Ruby module for constants. It has a list of variables and one method which applies formatting.
I can't seem to access the method in this module. Any idea why?
If you include the module the method becomes an instance method but if you extend the module then it becomes a class method.
module Const
def format
puts 'Done!'
end
end
class Car
include Const
end
Car.new.format # Done!
Car.format # NoMethodError: undefined method format for Car:Class
class Bus
extend Const
end
Bus.format # Done!
Bus.new.format # NoMethodError: undefined method format
module Foo
def self.hello # This is a class method
puts "self.hello"
end
def hello # When you include this module, it becomes an instance method
puts "hello"
end
end
Foo.hello #=> self.hello
class Bar
include Foo
end
Bar.new.hello #=> hello
Generally, with modules, these things should be happening :
Autoload path in application.rb, add:
config.autoload_paths += %W(#{config.root}/lib)
Place module in /lib
Include module with include NAMEOFMODULE
If the module name has an underscore like "game_engine", you need to use include GameEngine