ruby mixins errors - ruby

I'm confused with the following piece of code.
HTTParty library has class method named def self.get(..).
I include it in the Client module and then include that Client module in my Line class and access the get method in my def self.hi() method.
But when I run, it throws out the error:
ruby geek-module.rb
geek-module.rb:12:in `hi': undefined method `get' for Line:Class (NoMethodError)
from geek-module.rb:16:in `<main>'
Why I'm not being able to access that get method of HTTParty?
Following is the code:
require 'rubygems'
require 'httparty'
module Client
include HTTParty
end
class Line
include Client
def self.hi
get("http://gogle.com")
end
end
puts Line.hi

You cannot access self.get method because you use include HTTParty, include makes methods acessible by instances of class not class himself, your hi method is class method but get method is the instance method. If you use something like:
class Line
include Client
def hi
get("http://gogle.com")
end
end
line = Line.new
line.get
I think it should work
... or just use extend Client rather than include

So, when you include HTTParty in the Client module you can access the get method through Client.get. And when you include Client in the Line class you can access the get method through Client.get too. Actually, if you want to use the get method in your Line class, you don't need to include it. So:
require 'rubygems'
require 'httparty'
module Client
include HTTParty
end
class Line
def self.hi
Client.get("http://google.com")
end
end
puts Line.hi
or if you want the get method in your Line class you can use something like that:
class Client
include HTTParty
end
class Line < Client
def self.hi
get("http://google.com")
end
end
puts Line.hi

Related

Instance method not able to act on instance variable

Even though I required Nokogiri and initialized the variable, my method does not have access to the Nokogiri methods. I want to do this:
class Requester
require 'nokogiri'
def initialize(body)
#body = body
end
def destination
#body.at_css('destination')
end
end
and then I pass body, which is a Nokogiri document.
mess = Requester.new(body)
When I do this I get a "No Method Error":
mess.destination
I don't understand. I thought my class would have all the Nokogiri methods if I require it.
The full error is on at_css and looks like:
NoMethodError (undefined method `at_css' for #<Requester:0x007f685d971478>
You are confusing require and include.
require loads a file or a gem.
include includes the methods of another object.
a.rb:
module A
def hello
"hello world"
end
end
b.rb:
require 'a'
class B
include A
end
puts B.new.hello # hello world
However, you really need to rethink what you are trying to do. You can't include a class - you extend classes. And the object you are looking for is the class Nokogiri::HTML::Document.
If you are trying to build a document crawler you can use the delegator pattern:
require 'nokogiri'
class Requester < Delegator
def initialize(body)
super
#body = body
#doc = Nokogiri::HTML(body)
end
def __getobj__
#doc
end
end
Or you would create a subclass of Nokogiri::HTML::Document.
http://www.nokogiri.org/tutorials/searching_a_xml_html_document.html
http://ruby-doc.org/stdlib-2.2.1/libdoc/delegate/rdoc/Delegator.html

NoMethodError when trying to access method defined in included module

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.

Rails: class methods helpers from Lib

Sorry the title may not be very clear. Basically I have a wrapper for the Split gem called ABFeature in lib/ab_feature/ab_feature.rb
In my view I want to be able to call my helpers like this:
ABFeature.current_settings
But this is not working, here is the error I have:
undefined local variable or method `session' for ABFeature:Module
session is a method from ActionController and is seems I can't access it...
Here is my code:
require 'split'
module ABFeature
class << self
include Split::Helper
def current_settings
...
end
end
end
class ActionController::Base
ActionController::Base.send :extend, ABFeature
end
Any idea?,
Greg
I'm not sure what the result should be but if you want the current_settings method available in the controller I think you can do
module ABFeature
include Split::Helper
def current_settings
end
end
and then
class ApplicationController < ActionController::Base
include ABFeature
end
I think you usually call helpers as instance methods. Then they should share the context with the controller.

Ruby instance_eval confusion with load`

I am trying to test a single method in ruby. It is in a separate file so basically:
a.rb:
def my_method
...
end
in my a_spec.rb
require 'minitest/autorun'
Object.instance_eval do
load("path_to/a.rb")
def hello_world
...
end
end
When I try to run my test, it says that my_method is a private method while I can actually call Object.hello_world outright. What gives?
Also, is there an easier way to test plain ruby methods(no classes or modules) with minitest?
Doing the load above doesn't add the methods of a.rb as singleton methods to Object. Rather, it adds the methods to the global namespace. (The fact that you are doing the load inside the block where self refers to the Object class is irrelevant.)
With you above code, you should be able to call *my_method* directly in your tests:
class MyTest < MiniTest::Unit::TestCase
def test_my_method
assert my_method
end
def test_hello_world
assert Object.hello_world
end
end

Can't include ruby modules correctly

I'm kinda new to Ruby, so I'm not even sure if what I'm doing is best practice. Right now I am trying to define a function import that resides in a module on something.rb:
require 'rexml/document'
module MyModule
def import(file)
Document.new(File.new(file))
end
end
I have another file somethingelse.rb that calls on file something.rb that will use function import
require 'something.rb'
class MyClass
include MyModule
def initialize(file)
#myFile = import(file)
end
end
The problem only arises when I try to import the module from another file. When I use the module in the same file, everything works according to what you'd expect. The errors I get are:
usr/lib/ruby/1.8/rexml/dtd/elementdecl.rb:8: warning: already initialized constant PATTERN_RE
XMLTest.rb:9: uninitialized constant MyModule (NameError)
What am I doing wrong?
You need to require the other file you're trying to load in your first file, Ruby won't do that for you automatically. So if your module is in a file named "something.rb":
require "something"
class MyClass
include MyModule
def initialize(file)
#myFile = import(file)
end
end
try changing your rexml require to require_once.
So:
require_once 'rexml/document'
you can you use require_relative to import the file that has your module
use include to add the module in the class to access the module
class MyClass
include somethingModuleName
end

Resources