Ruby include module helper inside class - :cannot load such file - ruby

I've pure Ruby app with HashHelper located in lib/hash_helpers.rb which I want to use inside Matcher class in lib/matcher.rb.
To fire Matcher class I've got separate file in root directory of the app called runner.rb. How to include HashHelpers to be used inside the class Matcher ?
What I did is:
# runner.rb
require_relative 'lib/matcher'
matched_words = Matcher.new('dictionary.txt').call
p matched_words
# lib/matcher.rb
require_relative 'hash_helpers'
class Matcher
(...)
end
# lib/hash_helpers.rb
module HashHelpers
extend self
(...)
end
When I tried to run ruby runner.rb I'm getting an error:
lib/monads_matcher.rb:6:in `require_relative': cannot load such file -- /Users/usr/dictionary_app/lib/hash_helpers (LoadError)

Related

Handling a method from outside of a mixin module in ruby and rspec

I have a class that looks like this:
module ReusableBitlyLinks
def shorten_url url, *args
ShortenedUrl.shorten_url_with_bitly( url, email.user )
end
end
I have a test that looks like this:
require File.expand_path("../../../../app/decorators/mixins/reusable_bitly_links", __FILE__)
include ReusableBitlyLinks
describe ReusableBitlyLinks do
describe "shorten_url" do
it "works" do
ReusableBitlyLinks.shorten_url('asdf').should == 'asdf'
end
end
end
When I run the test I get an error that says:
uninitialized constant ReusableBitlyLinks::ShortenedUrl
How do I mock stub ReusableBitlyLinks::ShortenedUrl?
Is ShortenedUrl defined inside ReusableBitlyLinks module? If not - try to access it with ::ShortenedUrl.shorten_url_with_bitly.
Not sure what stubbing has to do with it...
In your mixin module, you need to tell it that ShortenedUrl is from outside the module by prepending :::
module ReusableBitlyLinks
def shorten_url(url, *args)
::ShortenedUrl.shorten_url_with_bitly(url, email.user)
end
end
You may also need to do a require inside the mixin file to load whatever file it is that defines ShortenedUrl.
Further, in your test file, the line:
require File.expand_path("../../../../app/decorators/mixins/reusable_bitly_links", __FILE__)
could be simplified to:
require_relative '../../../../app/decorators/mixins/reusable_bitly_links'

How do I reference a method in a different class from a method in another class?

I have a module and class in a file lib/crawler/page-crawler.rb that looks like this:
require 'oga'
require 'net/http'
require 'pry'
module YPCrawler
class PageCrawler
attr_accessor :url
def initialize(url)
#url = url
end
def get_page_listings
body = Net::HTTP.get(URI.parse(#url))
document = Oga.parse_html(body)
document.css('div.result')
end
newpage = PageCrawler.new "http://www.someurl"
#listings = newpage.get_page_listings
#listings.each do |listing|
bizname = YPCrawler::ListingCrawler.new listing['id']
end
end
end
Then I have another module & class in another file lib/crawler/listing-crawler.rb that looks like this:
require 'oga'
require 'pry'
module YPCrawler
class ListingCrawler
def initialize(id)
#id = id
end
def extract_busines_name
binding.pry
end
end
end
However, when I try to run this script ruby lib/yp-crawler.rb which executes the page-crawler.rb file above and works without the YPCrawler call, I get this error:
/lib/crawler/page-crawler.rb:23:in `block in <class:PageCrawler>': uninitialized constant YPCrawler::ListingCrawler (NameError)
The issue is on this line:
bizname = YPCrawler::ListingCrawler.new listing['id']
So how do I call that other from within my iterator in my page-crawler.rb?
Edit 1
When I just do `ListingCrawler.new listing['id'], I get the following error:
uninitialized constant YPCrawler::PageCrawler::ListingCrawler (NameError)
Edit 2
Here is the directory structure of my project:
Edit 3
My yp-crawler.rb looks like this:
require_relative "yp-crawler/version"
require_relative "crawler/page-crawler"
require_relative "crawler/listing-crawler"
module YPCrawler
end
In your yp-crawler.rb file, based on the structure that you posted, you should have something like:
require 'yp-crawler/version'
require 'crawler/listing-crawler'
require 'crawler/page-crawler'
Try this, in your yp-crawler.rb add the line:
Dir["#{File.dirname(__FILE__)}/crawler/**/*.rb"].each { |file| load(file) }
That should automatically include all files in your /crawler directory at runtime. Might want to do the same for the other directories.
Let me know if that helps :)

Call EXCEL method from Module

Creating module:
module CF
def work_sheet(excel_doc_name, workbook_name)
dir_to_excel = Dir.pwd + '/lib/config/data/'
read_workbook = RubyXL::Parser.parse("#{dir_to_excel}#{excel_doc_name}")
worksheet = read_workbook["#{workbook_name}"]
end
end
Call this method from module:
Given(/^Excel read$/) do
include CF
work_sheet("Login.xlsx", "Login_info")
end
Error message:
NoMethodError: undefined method `work_sheet' for #<Object:0x442f158>
Please check
To include the methods of a module in a step definition, you need to add the module to the World.
In your env.rb (or a file required by it) add the following line (after you have required the module file):
World(CF)
You should also remove the include CF line from the step definition.

How can I use my Sinatra helpers in included modules?

I have my routes and helpers defined in external files and included by Sinatra, however I'm new to Ruby and I can't now figure out how I can use my helper methods in my routes. When I run the code in RubyMine and access a profile URL I get the error "NoMethodError - undefined method `protected!'"
## Main class
require 'sinatra/base'
class MyApp < Sinatra::Base
register Sinatra::MyHelpers
register ProfileRoutes
...
end
## Helpers include
require 'sinatra/base'
module Sinatra
module LocutusHelpers
def self.registered( app )
app.before do
...
end
def protected!
...
end
end
end
end
## Routes include
require 'sinatra/base'
module ProfileRoutes
def self.registered( app )
app.get '/profile/:userid' do
protected!
...
end
end
end
I've tried def self.protected! for the helper but then it cant access the request object.
I've also tried Sinatra::MyHelpers.protected!, Sinatra.protected! and app.protected!, errors are thrown for all of these too
Do you know how I can access the helpers from my routes? Or have I set something up incorrectly?
It looks like you are mixing up adding helpers from extensions and configuring your app from extensions.
You need to move protected! into a module, then when registering your extension add that module as a helpers module.
module LocutusHelpers
# new module, move protected! into here
module HelperMethods
def protected!
...
end
end
def self.registered( app )
# add new hlpers module
app.helpers HelperMethods
# other extension setup as before...
app.before do
...
end
end
end

Monkey patch class methods

I'm trying to do some monkey patching in ActiveShipping UPS class .
I need to add a class level method (starting with .self), so here it's what I'm trying to do:
module ActiveMerchant
module Shipping
class UPS < Carrier
def self.process_request(receiver, sender, packages, options = {})
# some code
end
def regular_method
"foobar"
end
end
end
end
Unfortunately when I'm trying to use it:
ActiveMerchant::Shipping::UPS.process_request(receiver etc)
I get an error:
NoMethodError: undefined method `process_request' for ActiveMerchant::Shipping::UPS:Class
from (irb):6
from C:/Ruby19/bin/irb.bat:19:in `<main>'
There is no class method named process_request in original class.
In original UPS class provided in gem there is one static method defined self.retry_safe = true
and I can use it without errors.
I can also use regular_method after creating instance of UPS class.
More details provided:
I'm working with Rails 2.3 ( :-( ) and Ruby 1.9.2. I have no influce on environment.
Monkey patched code is under plugins/my_plugin/lib/active_shipping/ext/carriers/ups.rb
In /active_shipping I have file named extensions.rb in which i have:
require 'active_shipping'
require_relative 'ext/carriers'
require_relative 'ext/carriers/ups'
It deals with loading everything properly (I suppose basing on regular_method beheaviour from first chunk of code in my question).
I try to invoke process_request in one of my Controllers. This part is little tricky, beacuse i'm using sth like this:
MyModel.courier_service.process_request(parameters)
where courier_service, in this case holds the ActiveMerchant::Shipping::UPS class.
I'm still a newbie in Ruby and don't know what sort of details i should provide.
Maybe you want to do it in another way
File patch_classes.rb:
module ActiveMerchantExpand
module Shipping
module ClassMethods
def self.process_request(receiver, sender, packages, options = {})
# some code
end
end
module InstanceMethods
def regular_method
"foobar"
end
end
def self.included(receiver)
receiver.extend ClassMethods
receiver.send :include, InstanceMethods
end
end
end
Then you have to load your class "ActiveMerchant::Shipping::UPS"
and after that you can attach your methods to your class via
Rails.configuration.to_prepare do
require_dependency [[file for ActiveMerchant::Shipping::UPS]]
require 'patch_classes' )
ActiveMerchant::Shipping::UPS.send(:include, ::ActiveMerchantExpand::Shipping)
end
This is from rails plugin writing, i hope this helps.
regards tingel2k
Do you explicitly require file with your monkey patch? If you just put it under your app or lib path without requiring, it wouldn't load because constant ActiveMerchant::Shipping::UPS is defined in gem and it doesn't trigger dependency resolution mechanism.

Resources