Unable to override read method URI::HTTP - ruby

I am trying to stub the following:
uri = URI(base_url)
source = uri.read
I have re-written the read method as follows:
equire 'open-uri'
module OpenURI
module OpenRead
def read
return IO.read('source.html')
end
end
end
But it doesn't seem to work. New to ruby and could use some pointers. I always seem to end up with
NoMethodError: undefined method `read' for #<URI::HTTP:0x10ac59918>

uri = URI(base_url)
source = uri.read
You use the read method, so take a look where it is:
uri.method(:read).method_location
If you want to know where to override, go for
uri.method(:read).owner
or simply
def uri.read
<your body>
end

Related

NoMethodError but did 'require_relative'

I did the 'requir_relative' but still got the NoMethodError.
There are 2 ruby files, under 'run.rb' I have this
class Run
def separate(data)
hash_block = []
(0...data.count).each do |i|
f = data[i].split('|')
hash_block[i] = Hashing.new(f[0].to_i, f[1], f[2], f[3], f[4])
end
hash_block
end
end
and then in the main file, I did these:
require_relative 'run'
...some codes...
to_separate = IO.readlines(ARGV[0])
separated = separate(to_separate)
...some codes...
but I still get this:
in `block in <main>': undefined method `separate' for main:Object (NoMethodError)
If I cut the method and paste it in the main file it will work as expected but that is something I wanted to avoid.
In order to call the method within the class Run you have to instantiate it. Since is an instance method. The way your calling the class is giving you the error undefined because it can not find it with in the scope of your current file
run_instance = Run.new
to_separate = IO.readlines(ARGV[0])
sperated = run_instance.separate(to_separate)
You required the file, but in that file you have a class definition. separate is inside that class (and that's an instance method), so you need an object to call the method on.
separated = Run.new.separate(to_separate)

Undefined method `collection' for #<Mongo::Client> Did you mean? collections (NoMethodError). Ruby

I am working with automated test. This is the first time I'm working with mongoDB.
So, I am trying to create a generic method to find a document in a desired collection that will be passed as parameter. I've found some examples and all of them use the .collection method. It doesn't seem to work in my project.
Here's my DB client code:
require 'mongo'
require 'singleton'
class DBClient
include Singleton
def initialize
#db_connection = Mongo::Client.new($env['database']['feature']['url'])
end
def find(collection, value)
coll = #db_connection.collection(collection)
coll.find(owner: 'value')
end
end
And here's how I instance my method
DBClient.instance.find('collectionTest', 'Jhon')
When I run my test I get the following message:
undefined method `collection' for #<Mongo::Client: cluster=localhost:>
Did you mean? collections (NoMethodError)
The gem I'm using is mongo (2.6.1).
What I am doing wrong?
Based on documentation, there is indeed no method collection in Mongo::Client. What you are looking for is the [] method. The code will then look like this:
require 'mongo'
require 'singleton'
class DBClient
include Singleton
def initialize
#db_connection = Mongo::Client.new($env['database']['feature']['url'])
end
def find(collection, value)
coll = #db_connection[collection]
coll.find(owner: value)
end
end
EDIT: I've also changed the line with the find itself. In your original code, it would find documents where owner is 'value' string. I presume you want the documents where owner matches the value send to the function.

Can't get Curl URL to work inside a Ruby Module Method

I am having a problem where I can't get any of the following methods, (1, 2 and 3) to work.
require "curb"
#username = 'user'
#api_key = 'key'
#base_uri = 'https://url.com'
#offer_id = 999
#login_method = "login=#{#username}&api_key=#{#api_key}"
#method_3_url ="#{#base_uri}/3/?#{#login_method}"
module My_script
def self.call_method(url)
Curl::Easy.http_get(url){|curl| curl.follow_location = true; curl.max_redirects=10;}
end
def self.method1
call_method("#{#base_uri}/1/#{#login_method}")
end
def self.method2
call_method("#{#base_uri}/2/?#{#login_method}")
end
def self.method3
call_method("#{#base_uri}/3/?#{#login_method}")
end
end
I get the following error:
Curl::Err::MalformedURLError: URL using bad/illegal format or missing
URL from
/Users/home/.rvm/gems/ruby-2.0.0-p598/gems/curb-0.8.8/lib/curl/easy.rb:72:in
`perform'
When I run call_method(#method_3_url) it does seem to work correctly.
I can also take the original POST URL and paste it into Chrome and it'll work..
I have spent hours looking for a solution online for this and I can't seem to make it work.. I also get a similar error when using HTTParty. Please help :-)
Your instance variables aren't in the module, and are therefore out of scope.
Instead of:
#foo = 'bar'
module Foo
...
end
You're looking for:
module Foo
#foo = 'bar'
...
end

How can I extend a module, override a method, and still call the overridden method?

I'd like to use URI in this way:
require 'open-uri'
uri = URI.parse('http://subdomain.domain.com/section/page.html')
puts uri.first_level_domain # => 'domain.com'
How can I do that?
I'm trying:
module URI
def parse
ret = super
domain = ret.host.split('.').last(2).join('.')
ret.send(:define_method, :first_level_domain, lambda { domain })
ret
end
end
but I get undefined method 'first_level_domain' for #<URI::HTTP:0x9bc7ab0> (NoMethodError)
Why something so complicated ? You could something like this
module URI
def first_level_domain
host.split('.').last(2).join('.')
end
end
uri = URI.parse('http://subdomain.domain.com/section/page.html')
uri.first_level_domain
# => "domain.com"

How do I monkey-patch ruby's URI.parse method

Some popular blog sites typically use square brackets in their URLs but ruby's built-in URI.parse() method chokes on them, raising a nasty exception, as per:
http://redmine.ruby-lang.org/issues/show/1466
I'm trying to write a simple monkey-patch that gracefully handles URLs with the square bracket. The following is what I have so far:
require 'uri'
module URI
def self.parse_with_safety(uri)
safe_uri = uri.replace('[', '%5B')
safe_uri = safe_uri.replace(']', '%5D')
URI.parse_without_safety(safe_uri)
end
alias_method_chain :parse, :safety
end
But when run, this generates an error:
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/module/aliasing.rb:33:in alias_method: NameError: undefined method 'parse' for module 'URI'
How can I successfully monkey-patch URI.parse?
alias_method_chain is executed on the module level so it only affects instance methods.
What you have to do is execute it on the module's class level:
require 'uri'
module URI
class << self
def parse_with_safety(uri)
parse_without_safety uri.gsub('[', '%5B').gsub(']', '%5D')
end
alias parse_without_safety parse
alias parse parse_with_safety
end
end
#nil his comment is very helpful, we ended up with the following:
def parse_with_safety(uri)
begin
parse_without_safety uri.gsub(/([{}|\^\[\]\#`])/) {|s| URI.escape(s)}
rescue
parse_without_safety '/'
end
end

Resources