Ruby/GSL online documentation for wrong version? - ruby

After successfuly installing Ruby/GSL library on my Debian (via *deb), with Ruby 1.9.3, I am having troubles running most of the GSL methods. Specifically, this webpage shows several code samples, but (in Arrays), right from the top line, require "GSL" is obsolete, it is require "gsl" today. The remaining methods also do not work.
For another example of my problem, consider another online reference to Ruby/GSL.
GSL::VERSION
#=> 1.15
GSL::pow_2( 4 )
#=> 16
But when I flip the page,
GSL::Complex.new( 0.9, 1.1 )
#=> ArgumentError: wrong number of arguments(2 for 0)
The simplest explanation to me would be that Ruby/GSL has more than one version hanging online, and the documentation I found is for the old one. For example, there is this abandoned version (https://github.com/codahale/ruby-gsl), so perhaps the version history is a bit complicated? Which is the authoritative version, and where can I finde the up-to-date documentation?

Following methods do work for the Complex module:
> c = GSL::Complex[0.9, 1.1]
=> GSL::Complex
[ 9.000e-01 1.100e+00 ]
> c.real
=> 0.9
> c.imag
=> 1.1
> c.pow 2
=> GSL::Complex
[ -4.000e-01 1.980e+00 ]

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.

Ohai thinks my plugin is version 6. Why?

I'm trying to write a plugin for ohai. It seems like a pretty straightforward task:
Ohai.plugin(:Uname) do
provides 'uname'
depends 'kernel'
collect_data do
uname Mash.new
uname[:message] = `uname -a`
end
end
To me this looks like the online examples provided by Opscode, O'Reilly and others. But here's what happens when I try to test it:
% irb -rohai
irb(main):001:0> Ohai::Config[:plugin_path] << "."
=> ["/home/ll0359/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/ohai-8.3.0/lib/ohai/plugins", "."]
irb(main):002:0> o = Ohai::System.new
=> #<Ohai::System:0x007fed82e43078 #plugin_path="", #data={}, #provides_map=#<Ohai::ProvidesMap:0x007fed82e42fd8 #map={}>, #v6_dependency_solver={}, #d82e42f38 #controller=#<Ohai::System:0x007fed82e43078 ...>, #v6_plugin_classes=[], #v7_plugin_classes=[]>, #runner=#<Ohai::Runner:0x007fed82e42ec0 #prp:0x007fed82e42fd8 #map={}>, #safe_run=true>>
irb(main):003:0> o.all_plugins
And here's where the fun begins. I get this output, over and over and over:
[2015-05-20T03:13:09+00:00] WARN: Plugin Definition Error: <./ohai_uname.rb>: collect_data already defined on platform default
[2015-05-20T03:13:09+00:00] WARN: [DEPRECATION] Plugin at ./test_ohai.rb is a version 6 plugin. Version 6 plugins will not be supported in future releases....
your plugin to version 7 plugin syntax. For more information visit here: docs.chef.io/ohai_custom.html
(the text on my second line was clipped by my screen but you get the idea)
I've tried running this code with and without the 'depends' line. Same result.
I've tried running this code with and without the Mash line, substituing 'uname uname -a' for the assignment line. Same result.
I've tried running with and without passing ":linux" as a parameter to collect_data. The only difference is I get a warning about collect_data(:linux) already being defined instead of :default.
I've tried renaming the plugin to a random 8 character identifier just in case it was tripping over being called :Uname. Same result.
I've tried passing "uname" (capital and lower) as a parameter to o.all_plugins. Same result.
So my questions are:
Why does ohai (8.3, running under Ruby 2.2.1) think this is a version 6 plugin? I can't see anything in it that would make it look like it's not version 7.
How can I get this working?
Thanks
Note to self: Next time you do this, don't try to test from the directory your plugin is in and add "." to your plugin_path. Moving to a different directory and adding the absolute path to the plugin solved the problem.
I plan to leave this up in case someone else has this happen to them.

How to use interactive_editor when REPL console is run in context of a particular object

I am trying to programmatically launch a console such that:
Its context is bound to a particular object (link to Stack Overflow).
It allows me to use tools (i.e. vim command) provided by the interactive_editor Gem (link to GitHub).
It would be appear that the two conditions I am trying to meet are mutually exclusive. Below I write a script that fires up a REPL that is bound to the context of a [1,2,3] list.
# test.rb
require 'ripl'
require 'interactive_editor'
Ripl.start :binding => [1,2,3].instance_eval { binding }
If you run ruby test.rb, you can see that you are in the context of [1,2,3]:
>> self
=> [1, 2, 3]
>> map { |a| a * 2 }
=> [2, 4, 6]
But if you try using interactive_editor's features:
>> vim "something"
=> [1, 2, 3]
This last line fires up vim and actually writes to the file "something" (without my explicit saving):
# something
---
- 1
- 2
- 3
Is there any way for me to resolve this problem? Should I file this as an issue on the interactive_editor Gem? The same kinds of error occur when I use IRB along with interactive_editor or irbtools.
My guess is that changing the context makes it rather difficult for interactive_editor to resolve its object definitions but I am not sure how this works.
Thanks in advance and please let me know if I omitted important information.
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]
iteractive_editor (0.0.10)
irbtools (2.0.1, 1.7.1)
ripl (0.7.1)
ripltools (0.7.0)
I am running OS X Yosemite 10.10.3 but have managed to replicate this issue on several other Linux boxes.
I found a way around this:
def edit(*args)
system("$EDITOR #{args.join(' ')")
end
This still doesn't explain why I can't get this example to work with interactive_prompt.

Ruby 2.0p0 and XMLRPC::Client

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

Which format should the version constant of my project have

Ive seen lots of stuff
Foo::VERSION::STRING
Foo::VERSION
Foo::Version
any suggestions what the best/most-common default is ?
First of all, Foo::Version seems wrong to me. That implicates that version is a Class or a Module, but should be a constant, as first two of your examples.
Apart from that, there is no golden rule here. Here are a few examples:
Rails:
Rails::VERSION::STRING
(Note: a module VERSION with all capitals.)
SimpleForm:
SimpleForm::VERSION
Nokogiri:
Nokogiri::VERSION
RSpec:
RSpec::Version::STRING
(Note, a module Version, compare with Rails above.)
Cucumber:
Cucumber::VERSION
SimpleForm:
SimpleForm::VERSION
Most of the above have their version defined in the lib/[name]/version.rb file, except for Rails, which has a version.rb in the root of the project, and Cucumber, which has buried it in the lib/cucumber/platform.rb file.
Also note that all of the above use Strings as a version. (Rails even concatenates MAJOR, MINOR, TINY, and PRE constants into a single VERSION constant.) This allows for easy comparison of versions:
"1.2.3" > "0.4.2" # => true
"1.2.3" > "1.2.2" # => true
"1.2.3" > "1.2" # => true
However, such a comparison fails when you run into double digits for the patch level:
"1.2.3" > "1.2.12" # => true
To me, defining Foo::VERSION is your best bet, define it in lib/foo/version.rb, and make it a String value.

Resources