I am running ruby 1.9.3 on a linux box. I would like to use SOCKSSocket, however, I continue to run into the following error:
uninitialized constant SOCKSSocket
simple test using IRB
irb(main):001:0> require 'resolv-replace'
=> true
irb(main):002:0> SOCKSSocket
NameError: uninitialized constant SOCKSSocket
from (irb):2
from /usr/local/bin/irb:12:in `<main>'
here is the source code directly from resolv-replace.rb
class SOCKSSocket < TCPSocket
# :stopdoc:
alias original_resolv_initialize initialize
# :startdoc:
def initialize(host, serv)
original_resolv_initialize(IPSocket.getaddress(host), port)
end
end if defined? SOCKSSocket
I can't help but think that I need to install some dependency needed to enable socks or something. Anything would be helpful.
Ok, it seems the configure script does not have --enable-socks as part of it's list of valid options and that is the reason for the WARNING: unrecognized options ...
I did not track down how to add --enable-socks to the list of valid options, however, I did rig the script.
Edit: configure
find the section: Initialize some vars... and add enable_option_checking=no
# Initialize some variables set by options.
enable_option_checking=no
Now, run:
./configure --prefix=/usr/local --enable-socks
make
sudo make install
>ruby --version => 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux]
then, try it out in irb
irb(main):001:0> require 'socket'
=> true
irb(main):002:0> require 'resolv-replace'
=> true
irb(main):003:0> SOCKSSocket
=> SOCKSSocket
irb(main):004:0>
I haven't done anything using SOCKSSocket yet, however, at least now it looks like I have it accessible to my code. Also, I assume there is some ENV var to disable option checking or a better way around it. I just did not track that down.
Thanks for your help!!
SOCKSSocket appears to be an optional component of ruby. That's why
resolv-replace only monkey-patches the class if it already exists.
As an illustration, 'net/ftp' defines the following method:
def open_socket(host, port)
if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
#passive = true
return SOCKSSocket.open(host, port)
else
return TCPSocket.open(host, port)
end
end
Perhaps you could do something similar (i.e. create a SOCKS socket if
you have SOCKS enabled, otherwise create a boring old TCP socket).
And if you really need the proxy behaviour, a quick google search
revealed the following gem: http://socksify.rubyforge.org/ which
might be useful.
Related
I just finished setting up another development server for my API built using Ruby and Sinatra, however on this server I can't get the curl gem to work properly.
I've installed libcurl and libcurl-devel, and installed the curl gem without any errors, but when I try to use it in code, it always fails. Below is an example in irb:
irb(main):001:0> require 'curl'
=> true
irb(main):002:0> http = Curl.get("http://www.mysuperawesomeapi.com/someendpoint") do|http|
irb(main):003:1* http.headers['accept'] = 'application/JSON'
irb(main):004:1> end
NameError: uninitialized constant Curl
from (irb):2
from /usr/bin/irb:11:in `<main>'
The difference between this development server, and the other one is that this one is using Fedora 21 32bit (hardware limitation) while the other is using CentOS 7 64bit and is a virtual machine. When I try the same code above on irb on the CentOS VM, it works as expected. Any insight would be greatly appreciated.
It looks like in curl (unlike as in curb), there is a class CURL, but not Curl.
Inside gemfile include:
gem 'curl'
gem 'curb'
I'm trying to require hiredis in irb and it's already sending me an error:
irb(main):001:0> require "hiredis"
WARNING: could not load hiredis extension, using (slower) pure Ruby implementation.
=> true
irb(main):002:0>
Upon further investigation, I notice that it's crashing at this part of the code.
# hiredis-rb/lib/hiredis/connection.rb
module Hiredis
begin
require "hiredis/ext/connection"
Connection = Ext::Connection
rescue LoadError
warn "WARNING: could not load hiredis extension, using (slower) pure Ruby implementation."
require "hiredis/ruby/connection"
Connection = Ruby::Connection
end
end
So, I required the file hiredis/ext/connection and the error I get is the following error:
irb(main):001:0> require "hiredis/ext/connection"
LoadError: /home/***/projects/***/.gemset/extensions/x86_64-linux/2.1.0-static/hiredis-0.5.2/hiredis/ext/hiredis_ext.so:
undefined symbol: redisReaderFree -
/home/***/projects/***/.gemset/extensions/x86_64-linux/2.1.0-static/hiredis-0.5.2/hiredis/ext/hiredis_ext.so
from /home/***/.rbenv/versions/2.1.5/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
I'm using Ubuntu and latest stable version of Redis (2.8.18). How do I fix this? Thanks!
EDIT:
So after looking at the hiredis-rb page: https://github.com/redis/hiredis-rb, it says that I should do the following:
To use hiredis with redis-rb, you need to require
redis/connection/hiredis before creating a new connection.
So I did a require "redis/connection/hiredis" on irb and then require "hiredis" and everything worked fine, no more warnings.
But now the warnings don't happen at all anymore now. I assumed that I'd need to require "redis/connection/hiredis" everytime for it to work but now it just works. So I dunno why it's not warning me anymore now. I thought calling require "redis/connection/hiredis" during that irb session was only for that session, not all succeeding sessions.
I'm trying to log into a remote machine using SSH in my Ruby code and then trying to cd into another directory once I SSHed in. Here is my Ruby code to do it
require 'net/ssh'
require 'rubygems'
require 'needle'
Net::SSH.start('host', 'shui', :password => "password") do |ssh|
output = ssh.exec!("hostname")
shell = ssh.shell.open
shell.pwd
shell.cd "/svn"
puts shell.pwd
end
when I run my script, it gives me this error:
testssh.rb:8:in `block in <main>': undefined method `shell' ... (NoMethodError)
I'm pretty sure I've installed the gems that are needed to do this. Any suggestions on how to fix this? Thanks!
There is no shell method in Net:SSH v2, the yielded object is a Net::SSH::Connection::Session.
This net-ssh extension gives you the feature you are looking for: https://github.com/mitchellh/net-ssh-shell
Can you check your version?
gem list --local | grep ssh
i have 2.5.2
I found multiple references online, but you should use:
http://net-ssh.rubyforge.org/ssh/v2/api/classes/Net/SSH.html
here is the reference to v1
http://net-ssh.github.com/ssh/v1/chapter-5.html
the later, uses the shell method. But i don't think you have that gem installed.
So have a look at the 1st one (v2). Thats working fine for me.
Here's my irb session:
irb(main):001:0> class User
irb(main):002:1> include MongoMapper::Document
irb(main):003:1> key :name, String
irb(main):004:1> key :age, Integer
irb(main):005:1> many :hobbies
irb(main):006:1> end
NameError: uninitialized constant User::MongoMapper
from (irb):2
irb(main):007:0>
which is right off of http://mongomapper.com/
I'm in windows 7, ruby 1.8.7 patchlevel 249. My gem list includes mongo, mongo_mapper, bson, and bson_ext (among others). I tried 'require'ing 'mongo_mapper' and/or 'mongo', and just got error messages about those 'require's.
I'm sure it's something simple, but as a ruby newbie, I'm stumped.
TIA
You have to
require "rubygems"
first on 1.8.7.
Ruby 1.9.2 automatically does it for you.
On 1.8.7 you can set an environment variable called "RUBYOPT" to do this for you.
See here.
Then after you have RubyGems loaded, you can load MongoMapper and everything should work.
require "mongo_mapper"
Is there a way to check if some gem is currently installed, via the Gem module? From ruby code, not by executing 'gem list'...
To clarify - I don't want to load the library. I just want to check if it's available, so all the rescue LoadError solutions don't help me. Also I don't care if the gem itself will work or not, only whether it's installed.
In Ruby 1.9.3 only there is also:
Gem.available?('somegem')
You can use regex expressions too. Handy if I want to allow 'rcov' and GitHub variants like 'relevance-rcov':
Gem.available?(/-?rcov$/)
Looking at the Gem API documentation, using Gem::Specification::find_all_by_name to test for gem availability seems reasonable.
if Gem::Specification::find_all_by_name('gemname').any?
do stuff
end
find_all_by_name always returns an array (of Specification objects), as opposed to find_by_name which raises an exception if no match is found.
IMHO the best way is to try to load/require the GEM and rescue the Exception, as Ray has already shown. It's safe to rescue the LoadError exception because it's not raised by the GEM itself but it's the standard behavior of the require command.
You can also use the gem command instead.
begin
gem "somegem"
# with requirements
gem "somegem", ">=2.0"
rescue Gem::LoadError
# not installed
end
The gem command has the same behavior of the require command, with some slight differences. AFAIK, it still tries to autoload the main GEM file.
Digging into the rubygems.rb file (line 310) I found the following execution
matches = Gem.source_index.find_name(gem.name, gem.version_requirements)
report_activate_error(gem) if matches.empty?
It can provide you some hints about how to make a dirty check without actually loading the library.
Since Gem.available? is deprecated (argh!), you have to rescue again (double aaargh). Yes, find_by_name throws an exception if the gem is not found. So to be backwards-compatible with older rubygems, the common solution seems to be :
def gem_available?(name)
Gem::Specification.find_by_name(name)
rescue Gem::LoadError
false
rescue
Gem.available?(name)
end
Note that the new method allows you to pass a specific version to see if that's loaded:
Gem::Specification.find_by_name('rails', '3.0.4')
You could:
begin
require "somegem"
rescue LoadError
# not installed
end
This wouldn't, however, tell you if the module was installed through gem or some other means.
I use this code and it works smoothly.
def gem_available?(gem_name, version = nil)
version.nil? gem(gem_name) : gem(gem_name, version)
rescue Gem::LoadError
false
end
Examples to use
Let's assume you have rack 1.9.1 installed.
puts gem_available?('rack') # => true
puts gem_available?('rack', '>=2') => # false
Didn't see this anywhere here, but you can also pass fuzzy version strings to find_by_name and find_all_by_name:
Gem::Specification.find_all_by_name('gemname', '>= 4.0').any?