Migrating to rubinius - ruby

I'm trying to migrate my project from mri to rubinius to get concurrency advantage.
I've started the server and open first page and then got error:
Puma caught this error: undefined method `=~' for Pathname (NameError)
kernel/common/module.rb:212:in `instance_method'
kernel/common/module.rb:354:in `undef_method'
kernel/bootstrap/array.rb:66:in `each'
kernel/common/module.rb:352:in `undef_method'
...
My Gemfile
source 'https://rubygems.org'
ruby '2.1.0', :engine => "rbx", engine_version: '2.2.1'
gem "rubysl" # Ruby Standard Library meta-gem for rubinius
# Server requirements
gem 'puma'
...
What might be a problem here?
UPDATE: full stack trace

I examined your stack trace and looked at the Rubinius source code. The offending line is:
class Pathname
undef =~ # THIS IS IT
end
#=~ is an instance method on Object so normally undef =~ should work on any class... unless it has been undef'd on Object or on Pathname already.
I'm wondering if this is happening because you have the rubysl gem in your Gemfile. I don't know Rubinius, but from what I can see, it doesn't seem to require you to specifically include this gem. Or maybe it did in past versions, but doesn't now. If the standard library is being loaded twice, that would explain why undef =~ fails the second time.
If that doesn't help, I recommend you try temporarily removing as many gems as possible and see if the problem disappears. If so, add them back one by one until you find which one is causing the problem.

Related

How to prevent warnings in ruby 2.7

In ruby 2.7 I having a lot of warnings like this:
<main>: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead
/Users/user/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/pry-nav-0.3.0/lib/pry-nav.rb:17:
warning: in `eval'
The RUBYOPT with such parameters doesn't work:
-W:no-deprecated -W:no-experimental
This is pry specific and it should have been fixed, see this commit.
Update pry (which pry-rails has a dependency) to v0.13.0
Edit: On the other hand, pry-nav which also seems to be involved in your issues currently asks for something lower than v0.13.0, so it might not work just like this out of the box. You have to get it to run with the latest pry.

LoadError when requiring a renamed gem

I started building Ruby bindings for the Marvel Comics API earlier this month. At the time, there was no gem named marvel on RubyGems, so I fired up jeweler, created a project, and began making a crude, but useable first release. I tested it by rake installing it locally and requiring it in a dummy project that let me play with it in pry:
require 'marvel'
require 'dotenv'
require 'pry'
Dotenv.load
#client = Marvel::Client.new
#client.configure do |config|
config.api_key = ENV['API_KEY']
config.private_key = ENV['PRIVATE_KEY']
end
binding.pry
When I got to the point where I had exposed several endpoints (at this commit) I attempted releasing it to rubygems.org, but discovered someone by then had released a marvel gem. I hastily altered my Rakefile and renamed mine to marvel_api and released it.
I let it sit for a few days before I came back and started experimenting with adding in Faraday middleware to try and clean it up. However, I never seem to have tested whether the name change to marvel_api worked. Now, whenever I try to require marvel_api, I'm met with this LoadError:
/Users/Raevynheart/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- marvel_api (LoadError)
from /Users/Raevynheart/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from test.rb:1:in `<main>'
I'm trying to understand if this is happening because my process for renaming the gem was incorrect, or if this is some separate issue. The gem's source is here: https://github.com/O-I/marvel. Note that the repo name and gem name are different — I don't know if that is an issue. Let me know if there is any other information I need to add to help troubleshoot this. Thanks for any help!
I think you are facing this issue since within your gem's lib directory, you still have the file named as marvel.rb.
From http://guides.rubygems.org/make-your-own-gem/ :
Code for your package is placed within the lib directory. The convention is to have one Ruby file with the same name as your gem, since that gets loaded when require 'hola' is run. That one file is in charge of setting up your gem’s code and API.
So, I believe your issue will resolve by changing your filename within lib to marvel_api.rb.

Native extensions fallback to pure Ruby if not supported on gem install

I am developing a gem, which is currently pure Ruby, but I have also been developing a faster C variant for one of the features. The feature is usable, but sometimes slow, in pure Ruby. The slowness would only impact some of the potential users (depends which features they need, and how they use them), so it makes sense to have the gem available with graceful fallback to Ruby-only functions if it cannot compile on a target system.
I would like to maintain the Ruby and C variants of the feature in a single gem, and provide the best (i.e. fastest) experience from the gem on installation. That would allow me to support the widest set of potential users from a single project of mine. It would also allow other people's dependent gems and projects to use the best available dependency on a target system, as opposed to a lowest-common-denominator version for compatibility.
I would expect the require to fallback at runtime to appear in the main lib/foo.rb file simply like this:
begin
require 'foo/foo_extended'
rescue LoadError
require 'foo/ext_bits_as_pure_ruby'
end
However, I don't know how to get the gem installation to check (or try and fail) for native extension support so that the gem installs correctly whether or not it can build 'foo_extended'. When I researched how to do this, I mainly found discussions from a few years back e.g. http://permalink.gmane.org/gmane.comp.lang.ruby.gems.devel/1479 and http://rubyforge.org/pipermail/rubygems-developers/2007-November/003220.html that imply Ruby gems do not really support this feature. Nothing recent though, so I am hoping someone on SO has some more up-to-date knowledge?
My ideal solution would be a way to detect, prior to attempting a build of the extension, that the target Ruby did not support (or perhaps simply not want, at the project level) C native extensions. But also, a try/catch mechanism would be OK if not too dirty.
Is this possible, if so how? Or is the advice to have two gem variants published (e.g. foo and foo_ruby), that I am finding when I search, still current best practice?
This is my best result attempting to answer my own question to date. It appears to work for JRuby (tested in Travis and on my local installation under RVM), which was my main goal. However, I would be very interested in confirmations of it working in other environments, and for any input on how to make it more generic and/or robust:
The gem installation code expects a Makefile as output from extconf.rb, but has no opinion on what that should contain. Therefore extconf.rb can decide to create a do nothing Makefile, instead of calling create_makefile from mkmf. In practice that might look like this:
ext/foo/extconf.rb
can_compile_extensions = false
want_extensions = true
begin
require 'mkmf'
can_compile_extensions = true
rescue Exception
# This will appear only in verbose mode.
$stderr.puts "Could not require 'mkmf'. Not fatal, the extensions are optional."
end
if can_compile_extensions && want_extensions
create_makefile( 'foo/foo' )
else
# Create a dummy Makefile, to satisfy Gem::Installer#install
mfile = open("Makefile", "wb")
mfile.puts '.PHONY: install'
mfile.puts 'install:'
mfile.puts "\t" + '#echo "Extensions not installed, falling back to pure Ruby version."'
mfile.close
end
As suggested in the question, this answer also requires the following logic to load the Ruby fallback code in the main library:
lib/foo.rb (excerpt)
begin
# Extension target, might not exist on some installations
require 'foo/foo'
rescue LoadError
# Pure Ruby fallback, should cover all methods that are otherwise in extension
require 'foo/foo_pure_ruby'
end
Following this route also requires some juggling of rake tasks, so that the default rake task doesn't attempt to compile on Rubies that we're testing on that don't have capability to compile extensions:
Rakefile (excerpts)
def can_compile_extensions
return false if RUBY_DESCRIPTION =~ /jruby/
return true
end
if can_compile_extensions
task :default => [:compile, :test]
else
task :default => [:test]
end
Note the Rakefile part doesn't have to be completely generic, it just has to cover known environments we want to locally build and test the gem on (e.g. all the Travis targets).
I have noticed one annoyance. That is by default you will see Ruby Gems' message Building native extensions. This could take a while..., and no indication that the extension compilation was skipped. However, if you invoke the installer with gem install foo --verbose you do see the messages added to extconf.rb, so it's not too bad.
https://stackoverflow.com/posts/50886432/edit
I tried the other answers and could not get them to build on recent Rubies.
This worked for me:
Use mkmf#have_* methods in extconf.rb to check for everything you need. Then call #create_makefile, no matter what.
Use the preprocessor constants generated by #have_* to skip things in your C file.
Check which methods/modules are defined in Ruby.
If you want to support JRuby et al, you'll need a more complex release setup.
A simple example where the whole C extension is skipped if something is missing:
1.
ext/my_gem/extconf.rb
require 'mkmf'
have_struct_member('struct foo', 'bar')
create_makefile('my_gem/my_gem')
2.
ext/my_gem/my_gem.c
#ifndef HAVE_STRUCT_FOO_BAR
// C ext cant be compiled, ignore because it's optional
void Init_my_gem() {}
#else
#include "ruby.h"
void Init_my_gem() {
VALUE mod;
mod = rb_define_module("MyGemExt");
// attach methods to module
}
#endif
3.
lib/my_gem.rb
class MyGem
begin
require 'my_gem/my_gem'
include MyGemExt
rescue LoadError, NameError
warn 'Running MyGem without C extension, using slower Ruby fallback'
include MyGem::RubyFallback
end
end
4.
If you want to release the gem for JRuby, you need to adapt the gemspec before packaging. This will allow you to build and release multiple versions of the gem. The simplest solution I can think of:
Rakefile
require 'rubygems/package_task'
namespace :java do
java_gemspec = eval File.read('./my_gem.gemspec')
java_gemspec.platform = 'java'
java_gemspec.extensions = [] # override to remove C extension
Gem::PackageTask.new(java_gemspec) do |pkg|
pkg.need_zip = true
pkg.need_tar = true
pkg.package_dir = 'pkg'
end
end
task package: 'java:gem'
Then run $ rake package && gem push pkg/my_gem-0.1.0 && gem push pkg/my_gem-0.1.0-java to release a new version.
If you just want to run on JRuby, not distribute the gem for it, this will suffice (it will not work for releasing the gem, though, as it is evaluated before packaging):
my_gem.gemspec
if RUBY_PLATFORM !~ /java/i
s.extensions = %w[ext/my_gem/extconf.rb]
end
This approach has two advantages:
create_makefile should work in every environment
a compile task can remain prepended to other tasks (except on JRuby)
Here is a thought, based on info from http://guides.rubygems.org/c-extensions/ and http://yorickpeterse.com/articles/hacking-extconf-rb/.
Looks like you can put the logic in extconf.rb. For example, query the RUBY_DESCRIPTION constant and determine if you are in a Ruby that supports native extensions:
$ irb
jruby-1.6.8 :001 > RUBY_DESCRIPTION
=> "jruby 1.6.8 (ruby-1.8.7-p357) (2012-09-18 1772b40) (Java HotSpot(TM) 64-Bit Server VM
1.6.0_51) [darwin-x86_64-java]"
So you could try something like wrap the code in extconf.rb in a conditional (in extconf.rb):
unless RUBY_DESCRIPTION =~ /jruby/ do
require 'mkmf'
# stuff
create_makefile('my_extension/my_extension')
end
Obviously, you will want more sophisticated logic, grabbing parameters passed on "gem install", etc.

Sinatra cannot find views on Ruby 1.9.2-p0

I'm quite new to Ruby language (up to now I developed in Groovy + Grails) but since I was curious about it I wanted to try Sinatra on Ruby 1.9.2-p0.
I have a trivial website that is contained in /mywebpage and has 2 files:
# blog.rb
get '/' do
'Hello World!'
end
get '/impossible' do
haml :index
end
and
#config.ru
path = File.expand_path "../", __FILE__
$LOAD_PATH << (File.expand_path ".") + "/views"
require 'haml'
require 'sinatra'
require "#{path}/blog"
run Sinatra::Application
then in the same folder I have a /views/ folder that contains index.haml.
I try to run the server with rackup -p8080 but when I try to get /impossible I receive the following error:
Errno::ENOENT at /impossible
No such file or directory - /home/jack/mywebpage/<internal:lib/rubygems/views/index.haml
By searching over internet it seems that this maybe caused by "." not being included in $LOAD_PATH so I tried to add it or add directly views ./views so that actually $LOAD_PATH.inspect gives me correct path: ..., "/home/jack/mywebpage/views"]
But still it doesn't seem to work. Being quite new to the framework and the language I was wondering if I'm doing something wrong. any clues?
Running Sinatra with Ruby 1.9.2 the template directory is no longer implicitly 'views', you need to set it yourself.
set :views, File.dirname(__FILE__) + "/views"
Note that currently Ruby also has Kernel#__dir__() method that is equivalent to File.dirname(__FILE__).
This, and other issues with 1.9, will be have been solved in Sinatra 1.1. You could use this fork: http://github.com/rkh/sinatra/tree/1.1
I ran into a similar problem, and solved it like this. I didn't dig into the problem, but this is what I found and it works. It'll supposedly be fixed in the next version of Sinatra (which they should really get out the door, just to fix these few 1.9.2 bugs).
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
enable :run
get '/' do
"Hello, world!"
end
Edit: It seems there are multiple bugs with Sinatra on 1.9.2. This one will fix Sinatra apps not starting on 1.9.2. I don't use a views directory (I like to keep my apps single-file), so I didn't run into your particular problem. This fix most likely won't help you at all. I probably should have read your problem more closely..
gem install sinatra --pre
I ran into that last week and didn't find a suitable fix on the Sinatra site short of tweaking the sinatra code. I'm using rvm for my development and switched to try sinatra on Ruby 1.8.7 and it works fine again, so that's where I left it.
Oh, since you're new to Ruby, you might not know about rvm, so here's the lowdown. RVM is Mac only and highly recommended for managing your Ruby version and gems. It makes it trivial to have multiple Ruby versions and alternate groups of gems for development and testing. Everything is stored in your ~/.rvm directory so it's easy to blow it all away if you need to.
http://rvm.beginrescueend.com/
I just looked at the Sinatra site again about the problem to see if there was anything new, but it appears they consider the following to be an acceptable fix:
http://github.com/sinatra/sinatra/issues/#issue/50
I'm a bit adverse to having to edit the source of Sinatra as recommended by issue #50, but it's not real hard to do. I'd like to see them put out an update so we'd have an official fix but I haven't seen anything yet:
gem env will tell you the "GEM PATHS". Sinatra's gem will be in one of those. The line mentioned in issue #50 goes into base.rb. On my machine it's something like ...gems/ruby-1.9.2-p0/gems/sinatra-1.0/lib/sinatra/base.rb.
Insert:
/<internal:/, # ruby 1.9.2-p0 hacks
at line 1020.
Save the file and you should be good to go.

Why does my Sproutcore development server drop connections with "invalid byte sequence in US-ASCII"?

Here's the stack: Sproutcore 1.0.1046. Ruby 1.9.1, in RVM. Thin 1.2.7. Thor 0.13.8. Rack 1.2.1. Eventmachine 0.12.10. Erubis 2.6.6.
When I start the sc-server on any application, my first request to this server produces this in the console log:
ArgumentError: invalid byte sequence in US-ASCII
...followed by this stack trace. (I've listed gems which appear in the stack trace above, but there's a complete gemset list in the same gist as the stack trace.)
Research on the error message points out that this is a common problem with Ruby 1.9, but the stack trace suggests that the problem is in one of the gems somewhere.
I have:
Upgraded my OS (Mac OS X 10.5 to 10.6) in order to get the latest gcc Apple provides.
Reinstalled RVM.
Reinstalled Ruby.
Reinstalled all the relevant gems.
And yet I still have this problem on one system, but not on another. (N.B. there are several devs working on this code, and I'm the only one seeing this problem. I'm 99% certain it's not our code.) I guess what I'm saying is that I've cleared and rebuilt a lot of gems to try to isolate or remove this glitch, and yet I still haven't gotten rid of it.
Where should I look next?
You have some special setting in your bash environment that is setting ruby to use US-ASCII , this happened to me trying to execute sc-server from a remote terminal... I'm not really sure what it is, but it doesn't use UTF-8 and that's when it runs into trouble.
You can probably also change Encoding.default_external
Thanks so much for the Encoding.default_external suggestion. I was having the same problem, despite correctly set magic comments and environment variables. In Rails 2.3.9 I added this before_filter in application_controller.rb, resolved the issue:
def set_encoding
Encoding.default_external = 'UTF-8'
end
I had the same issue with RSS Feeds that I was displaying in a Rails 2.3.8 app with Ruby 1.9.2. My issue wasn't solved by the application_controller.rb before_filter technique mentioned here. The fix was to put the following into "RAILS_ROOT/config/initializers/string_encodings.rb":
Encoding.default_external = 'UTF-8'
That worked for me site-wide, instead of on a controller level.
In my case the ArgumentError occurred during a Capistrano deploy call that envolves ruby's net-ssh (ruby 1.9.2p290, net-ssh 2.3.0). None of the solutions afore mentioned worked and none of the other reasons I've read about so far: i.e. "strange character in key file", etc..
Finally, I found a none ASCII-character in a comment(!) line in my ASCII encoded ~/.ssh/config file. BINGO!

Resources