SWIG: Ruby overloading problems - ruby

I have a sinatra web application and a C++ library that I can 'require' in sinatra (ruby) using bindings created by swig.
I also have a second -very similar- library, in which the function names are partially the same as in the first one. When I require them both, the one that is loaded first 'wins', i.e. calls to the ambiguous function names are always mapped to this library.
The reason is that 'require' does only load stuff that is not already loaded, whereas 'load' reloads no matter what. However, 'load' seems not to be applicable to .so files, only to ruby source files. Any help?
Thank you

require looks in $" array to determine if a module should be reloaded. You could try deleting it and requiring. Not sure if this will work for your use case, though, as it seems that the namespace still can be left polluted.
irb(main):001:0> require 'mysql'
=> true
irb(main):002:0> require 'mysql'
=> false
irb(main):003:0> $".delete('mysql.so')
=> "mysql.so"
irb(main):004:0> require 'mysql'
/usr/lib64/ruby/site_ruby/1.8/x86_64-linux/mysql.so: warning: already initialized constant MysqlRes
/usr/lib64/ruby/site_ruby/1.8/x86_64-linux/mysql.so: warning: already initialized constant MysqlField
/usr/lib64/ruby/site_ruby/1.8/x86_64-linux/mysql.so: warning: already initialized constant MysqlError
/usr/lib64/ruby/site_ruby/1.8/x86_64-linux/mysql.so: warning: already initialized constant VERSION
/usr/lib64/ruby/site_ruby/1.8/x86_64-linux/mysql.so: warning: already initialized constant OPT_CONNECT_TIMEOUT
/usr/lib64/ruby/site_ruby/1.8/x86_64-linux/mysql.so: warning: already initialized constant OPT_COMPRESS
/usr/lib64/ruby/site_ruby/1.8/x86_64-linux/mysql.so: warning: already initialized constant OPT_NAMED_PIPE
<snip>
=> true

Related

uninitialized constant Neo4j::Session (NameError)

Reading the instructions contained in the address https://neo4j.com/developer/ruby/ I built the following code:
require 'neo4j'
session = Neo4j::Session.open(
:server_db,
"http://neo4j:password#localhost:7687"
)
I have this error:
uninitialized constant Neo4j::Session (NameError).
I don't understand if it is necessary to instantiate Neo4j or if it is necessary to redefine Session. Do you have any suggestions?

Unable to autoload constant controller (in production). No error in development

File name -
app/controllers/invoice/inventory/department/pharmacy_invoices_controller.rb
File content -
class Invoice::Inventory::Department::PharmacyInvoicesController < ApplicationController
...
end
I get no error in development but in production I get this error -
F, [2016-04-25T13:08:00.754597 #13500] FATAL -- :
LoadError (Unable to autoload constant Invoice::Inventory::Department::PharmacyInvoicesController, expected /xxxxxx/yyyyyyy/app/controllers/invoice/inventory/department/pharmacy_invoices_controller.rb to define it):
I did ssh and checked every file on server. Its the same as development, which is obvious. I can't figure out why its throwing such an error in production.
This is covered in the rails docs, specifically in Autoloading and Reloading Constants and Nesting.
This is because defining nesting can be done in 2 ways and are very different in terms of how its seen by rails. You can check this by using Module.nesting:
module Foo
class Bar
Module.nesting
end
end
=> [Foo::Bar, Foo]
class Foo::Bar
Module.nesting
end
=> [Foo::Bar]
If you want to know more I recommend this really good blog post by Simon Coffey: Rails Autoloading Hell

rake error: "warning: already initialized constant FileUtils::OPT_TABLE"

I've seen similar questions regarding this error, but all of them rails-related. I'm not using rails; I'm working on a local rake task that reads from a yaml file and then does stuff with the data. I'd rather not install bundler for this (the solutions for the similar rails issues suggest prepending with bundle exec), since this script is simple and thus shouldn't need it.
Here's the simplified code, (which gets the same error as the code I'm working on):
require 'FileUtils'
require 'yaml'
SOME_FILE = "#{Dir.pwd}/some_file.yaml"
task default: :foo
task :foo do
bar = File.open(SOME_FILE) { |yf| YAML::load( yf ) }
bar.each {|k,v| puts k}
end
And here's the list of errors:
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:93: warning: already initialized constant FileUtils::OPT_TABLE
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:93: warning: previous definition of OPT_TABLE was here
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1272: warning: already initialized constant FileUtils::Entry_::S_IF_DOOR
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1272: warning: previous definition of S_IF_DOOR was here
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1535: warning: already initialized constant FileUtils::Entry_::DIRECTORY_TERM
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1535: warning: previous definition of DIRECTORY_TERM was here
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1537: warning: already initialized constant FileUtils::Entry_::SYSCASE
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1537: warning: previous definition of SYSCASE was here
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1656: warning: already initialized constant FileUtils::LOW_METHODS
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1656: warning: previous definition of LOW_METHODS was here
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/FileUtils.rb:1662: warning: already initialized constant FileUtils::METHODS
/Users/jpalmieri/.rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/fileutils.rb:1662: warning: previous definition of METHODS was here
The script will run fine despite the warnings; the above code would puts the keys as expected, right after the warnings.
This warning shows up when I write require 'FileUtils'. If I write require 'fileutils' (all lower case) warning disappears.
This link may be helpful explaining the behavior. I think in essence ruby thinks FileUtils and fileutils are different modules, therefore imports it twice. Then the redeclaration of constants give warning messages.
Wanted to answer this clearly (two years after it was asked) in case anyone wanders in here.
First, note that require in Ruby does not load a Module, as in the object FileUtils that is in memory. It loads the file "fileutils.rb" from your hard drive. The ".rb" is omitted by convention but you could write require 'fileutils.rb'.
The purpose of require in Ruby is to load a file only once, as opposed to load which will reload the file every time it is used. The way require avoids loading a file multiple times is by recording the filename argument and skipping it if it if that filename is passed again.
When you first require a file, Ruby responds with true to indicate that it was loaded. If you require the same file again it will return false to indicate that it was already loaded:
> require 'fileutils'
=> true
> require 'fileutils'
=> false
Since the filename stored by require is case-sensitive, but the actual file lookup is not, fileutils.rb will still be found if you use caps in the name:
> require 'FileUtils'
=> true
But if something in your Ruby program already loaded that file without caps (in your case "yaml.rb" probably requires "fileutils" as well) you will reload the file and may see warnings:
> require 'fileutils'
=> true
> require 'FileUtils'
/bin/ruby/lib/ruby/2.3.0/FileUtils.rb:96: warning: already initialized constant FileUtils::OPT_TABLE
etc.
By convention Ruby files should be named in lowercase with underscores, e.g. "my_class.rb", so you would always use require 'my_class'.
Things get a little trickier if you are requiring using absolute or relative paths, e.g. require 'special_classes/my_class'. I suggest reading about require_relative and the Ruby load path ($LOAD_PATH).
I solved this similar issue when I list my gem items which named "fileutils" has two versions
fileutils (1.1.0, default: 1.0.2)
then I run
sudo gem uninstall fileutils -v 1.1.0
and solved
I found that these warnings don't appear and the script runs perfectly if I simply comment out or remove line 1 of my original code (require 'FileUtils'). Although I haven't browsed the code for Rake, it must already include FileUtils (which makes sense).
For the sake of completeness, here is my revised code (note that I removed the require 'FileUtils' line:
require 'yaml'
SOME_FILE = "#{Dir.pwd}/some_file.yaml"
task default: :foo
task :foo do
bar = File.open(SOME_FILE) { |yf| YAML::load( yf ) }
bar.each {|k,v| puts k}
end
I was having the same issue with Travis and the problem was that I forgot to use bundle exec rake db:setup instead of rake db:setup. Hope it helps someone :)

Trying to create a proper ruby application (gem) for my Boulder codeschool class: lib classes not communicating correctly ('Uninitialized constant')

You can see everything in the file structure at github.com/ddd1600/simple_angel
I'm getting alot of errors while trying to create a ruby application (soon to be a gem) "the correct way", viz. by thoroughly dividing the logic into classes and "loader files" and all of that. Point is, I know how to do this code the simpler way, without obeying OO principles, but I want to do it "correctly".
So, first of all, the file structure is as follows---
root folder = ~/Develop/simple_angel
inside /simple_angel
- /lib
- Gemfile
- Rakefile
- simple_angel.gemspec
inside /lib
- simple_angel.rb
- /simple_angel
inside /lib/simple_angel
- company.rb
- search.rb
- version.rb
But, here are some basics.
Here is what I'm calling to run this program from the terminal (PATH when running is ~/Develop/simple_angel)
ruby -Ilib lib/simple_angel/search.rb
Here is search.rb
#these 'requires' are supposed to be loaded in lib/simple_angel.rb, so here I show
#them commented out
#
#require 'rubygems'
#require 'httparty'
#require 'json'
#require 'company'
module SimpleAngel
class Search
SEARCH_URL = "http://api.angel.co/1/startups"
def search(user_input)
response = HTTParty.get("#{SEARCH_URL}/#{user_input}")
parsed_response = JSON.parse(response.body)
Company.new(parsed_response)
end
end
s = SimpleAngel::Search.new
s = Search.new
x = s.search(6702)
p x
end
Here is the "loader" file, lib/simple_angel.rb (PS: what is a more formal title for this sort of file?)
require 'httparty'
require 'json'
require 'simple_angel/search'
require 'simple_angel/version'
require 'simple_angel/company'
module SimpleAngel
end
Lastly, when I (again), run "ruby -Ilib lib/simple_angel/search.rb" (with all of search.rb's 'requires' commented out (^&^), this is my error message:
[ddouglas#coders:~/Develop/simple_angel on master]
% ruby -Ilib lib/simple_angel/search.rb
lib/simple_angel/search.rb:15:in `search': uninitialized constant SimpleAngel::Search::HTTParty (NameError)
from lib/simple_angel/search.rb:24:in `<module:SimpleAngel>'
from lib/simple_angel/search.rb:8:in `<main>'
^&^ - now that we're all up to speed here, I might as well include the error that happened when I left search.rb's "requires" in place
% ruby -Ilib lib/simple_angel/search.rb ✹
/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- company (LoadError)
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from lib/simple_angel/search.rb:6:in `<main>'
I can't say I understand the point the class is trying to make regarding splitting up your files.
The first error (uninitialized constant SimpleAngel::Search::HTTParty) is because from within SimpleAngel::Search, you call HTTParty. Try changing that to ::HTTParty to specify the root namespace.
The big picture issue, looking back on this issue, was that I probably just needed to activate my /lib folder within rails via this addition to config/application.rb
config.autoload_paths += Dir["#{config.root}/lib/**/"]
from there, code can be directly loaded via the file_name.rb => FileName class system from anywhere within rails

Call one Ruby Script from Another

I am having a perplexing problem. I want to call one ruby script from another.
With this in mind, I create a testscript.rb and executed it, it contains this code,
require './paypal.rb'
puts paypal['L_AMT0']
This code returns a number, which is my paypal balance. It relies on a paypal.rb file which uses the ruby-paypal gem. When I do ruby testscript.rb I get the output of my paypal balance, which means it is working properly. This tells me that my method for calling one RB from another is okay, since, in the above scenario, testscript.rb is getting a variable that is returned from paypal.rb.
Using this same logic, I inserted the above code into another program which is called SiriProxy. It is a ruby program. I need it to get my paypal balance.
So Inside that program, I did a require paypal.rb, it failed because it could not find it, so I set an absolute path in require which fixed it.
However, when SiriProxy (the other ruby rb giving me an issue) trys to run puts paypal['L_AMT0'] it results in an error and ends the program.
This is the error,
[Info - Plugin Manager] Say: Checking Paypal Balance
/home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/gems/siriproxy-0.3.0/plugins/siriproxy-example/lib/siriproxy-example.rb:47:in `block in <class:Example>': undefined local variable or method `paypal' for #<SiriProxy::Plugin::Example:0x931a228> (NameError)
from /home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/bundler/gems/cora-1edcfb9073d5/lib/cora/plugin.rb:47:in `instance_exec'
from /home/siriproxy/.rvm/gems/ruby-1.9.3-p194#SiriProxy/bundler/gems/cora-1edcfb9073d5/lib/cora/plugin.rb:47:in `block (2 levels) in process'
In the above output it appears the issue is it does not understand "paypal", as seen here:
undefined local variable or method `paypal'
However, I do not understand why, since in testscript.rb I do the exact same thing and it works.
Can anyone help? Thank you.
Seems like #CodeGnome is right.
From the Kernel documentation:
require(name) → true or false
Loads the given name, returning true if successful and false if the
feature is already loaded.
require_relative(string) → true or false
Ruby tries to load the library named string relative to the requiring
file’s path. If the file’s path cannot be determined a LoadError is
raised. If a file is loaded true is returned and false otherwise.
Loading Files from the Current Directory
I don't know anything about your library or its internals, but it looks like your require statement may be wrong. If you want to load a file from the current directory in Ruby 1.9.3, you should use:
require_relative 'paypal'
Bundler and Gems
If it's a gem that you've installed as part of a bundle (e.g. the gem is defined in a Gemfile), then providing a path in your require statement is wrong. Instead, you need to require the bundled gem as follows:
require 'bundler/setup'
require 'paypal'

Resources