Ruby 2.0p0 and XMLRPC::Client - ruby

I am experiencing issues with Ruby 2.0p0 and XMLRPC::Client. When I run the code below in 2 different versions of ruby, I get a correct response on 1.9.3 but an error with 2.0.0. Anyone with the same issues? Is the solution just not to use the newest version of ruby or is there a workaround?
require "xmlrpc/client"
server = XMLRPC::Client.new2('http://api.flickr.com/services/xmlrpc/')
begin
res = server.call('flickr.test.echo')
puts res
rescue XMLRPC::FaultException => e
puts e.faultCode
puts e.faultString
end
Using ruby-1.9.3-p392 [ x86_64 ]
I get the correct response from flickr, since I didn't supply an API key:
100
Invalid API Key (Key has invalid format)
Using ruby-2.0.0-p0 [ x86_64 ]
I get an error from ruby saying "Wrong size. Was 365, should be 207 (RuntimeError)"
/home/luisramalho/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/xmlrpc/client.rb:506:in `do_rpc': Wrong size. Was 365, should be 207 (RuntimeError)
from /home/luisramalho/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/xmlrpc/client.rb:281:in `call2'
from /home/luisramalho/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/xmlrpc/client.rb:262:in `call'
from xmlrpc.rb:5:in `<main>'

I had a similar problem accessing a different xml rpc api (upcdatabase.com's) (seriously, who still uses xml rpc apis?) with ruby2.
My solution was to use a different xmlrpc library than ruby's default. LibXML-XMLRPC. It uses c extentions and is supposed to be faster than the standard library one, but it was last updated in 2008, so who knows how true that statement is today.
This is what my code ended up being that worked.
require 'xml/libxml/xmlrpc'
require 'net/http'
net = Net::HTTP.new("www.upcdatabase.com", 80)
server = XML::XMLRPC::Client.new(net, "/xmlrpc")
result = server.call('lookup', 'rpc_key' => "YOLOSWAG", 'upc' => "071160055506")
Hope this helps.

I proposed a patch for this. Lets see what the team thinks about it.
https://github.com/ruby/ruby/pull/308

Related

Strange results for the Gem.latest_version_for(name) method

I am working on a gem related utility and I have observed strange results using Gem.latest_version_for method. Here are some observations under irb:
irb(main):001:0> Gem.latest_version_for('rails').to_s
=> "5.2.2"
irb(main):002:0> Gem.latest_version_for('gosu').to_s
=> "0.7.38"
Note how the first line, gets the correct version of rails, 5.2.2 as I write this and checking with rubygems.org confirms this. The query for the gosu gem returns 0.7.38 which is wildly wrong. The correct answer should be 0.14.4
I am at a loss to explain what is happening here.
I can confirm that my host is https://rubygems.org and
C:\Sites\mysh
8 mysh>ruby --version
ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]
C:\Sites\mysh
9 mysh>gem --version
2.5.2
The latest version available for i386-mingw32 platform is 0.7.38. You'll note this comports with what your ruby version is reported as.
https://rubygems.org/gems/gosu/versions
latest_version_for calls latest_spec_for, which calls Gem::SpecFetcher.spec_for_dependency with only the name of the gem as an argument. spec_for_dependency takes another argument, matching_platform, which defaults to true.
It looks like latest_version_for is scoped to your current platform thru that chain, with the matching_platform default. The gem install command might treat i386/x386 as the same/equivalent and allow them.
spec_for_dependency
if matching_platform is false, gems for all platforms are returned
You should be able to mirror the latest_spec_for method and pass in the multi_platform argument to override. Something like
dependency = Gem::Dependency.new name
fetcher = Gem::SpecFetcher.fetcher
spec_tuples, _ = fetcher.spec_for_dependency dependency, true # true added here
With the excellent help of Jay Dorsey, I think I have made some progress here. What I need to say is too large to fit in a comment and is the actual answer to the question about the odd behavior. Well at least I am pretty sure that it is.
As mentioned above: latest_version_for calls latest_spec_for, which calls Gem::SpecFetcher.spec_for_dependency.
The key is that that method then calls Gem::SpecFetcher.search_for_dependency. This is a long rambling method. I want to focus of one line that occurs after the specs have be obtained:
tuples = tuples.sort_by { |x| x[0] }
This sorts the tuples which are an array of [spec, source] arrays. It sorts them in ascending version/platform (as far as I can tell)
Now we return to the Gem class method latest_spec_for(name) and in particular the line:
spec, = spec_tuples.first
This grabs the first sub-array and keeps the spec and discards the source.
Note that it grabs the first element. The one with the lowest version number. This is normally not a problem because for the vast majority of gems, there will be only one spec present. Not so for the gosu gem. Here there are three due to the fact that gosu contains platform specific code. It seems to grab specs for the two Gem platforms ("ruby" and "x86-mingw32") and also the ruby platform (i386-mingw32).
To test my idea, I created the file glmp.rb (get last monkey patch) Here it is:
# The latest_spec_for(name) monkey patch.
module Gem
# Originally in File rubygems.rb at line 816
def self.latest_spec_for(name)
dependency = Gem::Dependency.new name
fetcher = Gem::SpecFetcher.fetcher
spec_tuples, = fetcher.spec_for_dependency dependency
spec_tuples[-1][0]
end
end
Now I know monkey patching is frowned upon, but for now this is just to test the idea. Here are my results:
36 mysh>=Gem.latest_version_for('gosu')
Gem::Version.new("0.7.38")
C:\Sites\ideas\gem_usage
37 mysh>ls
gem_latest.rb gem_usage.rb glmp.rb
C:\Sites\ideas\gem_usage
39 mysh>=require './glmp'
true
C:\Sites\ideas\gem_usage
40 mysh>=Gem.latest_version_for('gosu')
Gem::Version.new("0.14.4")
While I can use this hack to solve my problem for now, I think I will raise an issue with rubygems bringing up this matter.

How do I fix a NoMethodError?

I did a fresh install on a MacBook Pro, and installed Mavericks, MacTex, Textmate and Texlive.
I am trying to work with some LaTex documents and I get this error on build:
undefined method `+' for nil:NilClass (NoMethodError).
In previous uses I did not see this error.
Below is the script I think I need to tweak but I do not know how. I found guidance in "Ruby undefined method `+' for nil:NilClass (NoMethodError)", but it does not appear to be applicable.
I am also suspicion of the MacTex download via Chrome, I checked that it was ok in Terminal, ran a checksum, and it was, but the MacTex site advises against using Chrome.
Script with a "problem:"
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
# coding: utf-8
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/process"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/htmloutput"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/save_current_document"
# To enable the typesetting of unsaved documents, you must change the “Save” setting of
# this command to “Current File” and add the variable TM_LATEX_AUTOSAVE to TextMate's
# Shell Variables preferences. Be warned that your document must be encoded as UTF-8 if
# you excercise this option — becauseTextMate.save_current_document cannot know the file
# encoding you prefer.
TextMate.save_current_document unless ENV["TM_LATEX_AUTOSAVE"].nil?
texMate = ENV["TM_BUNDLE_SUPPORT"] + "/bin/texMate.py"
engine_version = TextMate::Process.run(texMate, "version")
TextMate::HTMLOutput.show(:title => "Typesetting “#{ENV["TM_DISPLAYNAME"] || File.basename(ENV["TM_FILEPATH"])}”…", :sub_title => engine_version) do |io|
TextMate::Process.run(texMate, 'latex', '1', :interactive_input => false) do |line|
io << line
end
end
::Process.exit($?.exitstatus || 0) # exitstatus is nil if our process is prematurely terminated (SIGINT)
Any help would be great, thanks.
The error you received happens when you try to use the method + on nil:
nil + 'something'
In your code the '+' sign appears in 4 places:
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/process"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/htmloutput"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/save_current_document"
...
texMate = ENV["TM_BUNDLE_SUPPORT"] + "/bin/texMate.py"
Which means that one of either ENV["TM_SUPPORT_PATH"] or ENV["TM_BUNDLE_SUPPORT"] returns nil.
The ENV construct reflects the content of your machine's environment variables, therfore you should make sure the environment variables TM_SUPPORT_PATH and TM_BUNDLE_SUPPORT are set.
Problem solved. I deleted Textmate and then relied on Hazel to delete all affiliated files. I used TexLive to update all packages, ... just an overhaul. Following Mactex guidance using Safari for all future downloads, including the new download of Textmate, Installed Textmate, then followed this guidance, How and "Why to use TextMate for LaTeX," by Kelle, http://www.astrobetter.com/how-and-why-to-use-textmate-for-latex/#comment-595219 ... by the way excellent blog for help with Teaching. I then did a restart, which may not be necessary. Works wonderfully. I cannot comment on the value of the tweaking above, Red Herrings abound, the extent of the absenteeism may have indicated the initial installation was off (a guess). Thanks
I had a similar problem, all the builts stoped working after I cleaning up some bundles that I do not need and installing some new ones. The solution was that I deinstalled the Bundle "Bundle Support", even if it says "no not uninstall" in the description.
Reactivating "Bundle Support" solved this issue for me.

undefined method `configure' for Savon:Module

I'm getting the above error in a gem with this code snippet
Savon.configure do |config|
config.log = false
config.log_level = :error
HTTPI.log = false
end
This code used to pass in past runs on Travis, so I'm not sure why this changed when I altered the Readme.
Part of this confusion comes from my situation--inheriting a gem to maintain--along with this line in the gemspec:
gem.add_dependency 'savon'
There's no version number specified, so the newest run switched over to using Savon 2, which ditched the Savon.configure global behavior. If you're in the same boat as me, changing this line to the last pre-2.0 version of Savon will resolve the issue:
gem.add_dependency 'savon', '~>1.2.0'
Then bundle install and you should be good.
Or you want to upgrade your code. I know I do.
Savon.configure was removed from Savon 2.0 because the "problem was global state". The quickest way to keep the behavior the same in your app would be to define a app-level global hash in the same place. You'd then pass this hash into every Savon.client call you make. For instance:
# Where Savon.configure was called
APP_OPTS = {
# disable request logging, silences HTTPI as well
log: false,
# Don't log Laundry xmls to STDOUT
log_level: :error,
#... etc
}
# Elsewhere
#client = Savon::Client.new(APP_OPTS)
I'd consider this a starting point to migrating to the 2.0 configuration style. Ideally, you should always consider the client-specific 2.0 options available when initializing each Savon client.

What is ths error in Ruby Watir (WIN32OLERuntimeError: unknown property or method `document')?

I have this code in Ruby waitr ..
$LOAD_PATH.unshift File.join(File.dirname(__FILE__),'..') if $0 == __FILE__
require 'test/unit'
require 'Watir'
require 'Watir/contrib/enabled_popup'
class TC_Dialog_Test<Test::Unit::TestCase
$ie=Watir::IE.new
$ie.bring_to_front()
$myDir = File.expand_path(File.dirname(__FILE__))
def setup
$ie.goto "file://#{$myDir}/aa.html"
end
def test_confirm_OK
sleep(3)
$ie.button(:id, 'btnConfirm').click_no_wait
$hwnd = $ie.enable_popup(5)
if ($hwnd)
$popup =WinClicker.new
$popup.makeWindowsActive($hwnd)
sleep(3)
# $popup.clickWindowsButton($hwnd,"OK")
puts "you pressed Comfirm-ok"
sleep(3)
end
end
end
when runnung this code get this error results ...
test_confirm_OK(TC_Dialog_Test):
WIN32OLERuntimeError: unknown property or method `document'
HRESULT error code:0x800706b5
The interface is unknown.
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/ie.rb:417:in `method_missing'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/ie.rb:417:in `document'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/container.rb:767:in `ole_inner_elements'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/container.rb:838:in `locate_input_element'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/input_elements.rb:10:in `locate'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/element.rb:47:in `assert_exists'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/element.rb:278:in `enabled?'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/element.rb:53:in `assert_enabled'
c:/ruby/lib/ruby/gems/1.8/gems/watir-1.5.3/./watir/element.rb:214:in `click_no_wait'
Mo.rb:16:in `test_confirm_OK'
You are using Watir 1.5.3, but the current stable is 1.8.1. I suggest you to update your gem to the latest and try again. There is a good chance that the WIN32OLE object for IE has changed it's behavior and old gem is conflicting with it. (Have you updated IE or smth since last successful run?)
I got the same error using Watir 1.8.1. I don't know if there is anything wrong with your code, but in my case the tests ran fine on other machines.
I am running my tests in RubyMine 3.1.x. Running RubyMine as Administrator allowed Ruby to have the rights to interact with IE properly and the problem went away.
Edit:
Found the forum post which originally helped me solve the problem.

SOAP - Need to understand the error I get

I'm trying to initialize a variable called proxy like this:
proxy = Savon::Client.new "http://192.168.1.1:8080"
The thing is, when I run my code, I only get the error:
NameError: uninitialized constant NameOfTheClass::Savon
Thanks for any help!
PD: I'm using Ruby 1.9.2
PD2: I'm trying to run this from console.
You found probably the documentation for versions < 0.8.x.
Unfortunately the syntax has changed! Have a look here: https://github.com/rubiii/savon/blob/master/README.md
Savon works with blocks now.
Your example should now look like this
require 'savon'
require 'pp'
proxy = Savon::Client.new do
wsdl.document = "http://my.webservices.net/service?wsdl"
end
pp proxy.wsdl.soap_actions

Resources