tonytonyjan / jaro_winkler

Ruby & C implementation of Jaro-Winkler distance algorithm which supports UTF-8 string.
MIT License
192 stars 29 forks source link

Fall back to pure ruby implementation on LoadError #29

Closed milch closed 5 years ago

milch commented 5 years ago

Fixes #28

Tested on a similiar environment as described by the OP in #28, by manually patching the file with this code here

tonytonyjan commented 5 years ago

@milch Really appreciate your contribution. May I ask you how to reproduce the same environment so that I can verify your pull request? A Dockerfile is preferred. :)

milch commented 5 years ago

Hmm this is something that's not exactly easy to reproduce. This is what worked for me:

$ bundle install
$ bundle exec rake gem
$ gem install pkg/jaro_winkler-1.5.2.gem
$ ruby -r jaro_winkler -e 'puts $LOAD_PATH'
/usr/local/Cellar/rbenv/1.1.2/rbenv.d/exec/gem-rehash
~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/did_you_mean-1.3.0/lib
~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/jaro_winkler-1.5.2/lib
~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-17/2.6.0-static/jaro_winkler-1.5.2
~/.rbenv/versions/2.6.3/lib/ruby/site_ruby/2.6.0
~/.rbenv/versions/2.6.3/lib/ruby/site_ruby/2.6.0/x86_64-darwin17
~/.rbenv/versions/2.6.3/lib/ruby/site_ruby
~/.rbenv/versions/2.6.3/lib/ruby/vendor_ruby/2.6.0
~/.rbenv/versions/2.6.3/lib/ruby/vendor_ruby/2.6.0/x86_64-darwin17
~/.rbenv/versions/2.6.3/lib/ruby/vendor_ruby
~/.rbenv/versions/2.6.3/lib/ruby/2.6.0
~/.rbenv/versions/2.6.3/lib/ruby/2.6.0/x86_64-darwin17
$ rm -rf ~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-17/2.6.0-static/jaro_winkler-1.5.2
$ rm -rf ~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/jaro_winkler-1.5.2/lib/jaro_winkler/jaro_winkler_ext.bundle

Now if you try to require jaro_winkler you'll notice a new error message:

$ ruby -r jaro_winkler -e 'puts $LOAD_PATH'
Ignoring jaro_winkler-1.5.2 because its extensions are not built. Try: gem pristine jaro_winkler --version 1.5.2
Traceback (most recent call last):
        1: from ~/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
~/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- jaro_winkler (LoadError)

However, the error here is thrown because jaro_winkler is not in the $LOAD_PATH anymore, as per the first line. If we add it back:

$ pry
[1] pry(main)> jaro_winkler_path = File.expand_path("~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/jaro_winkler-1.5.2/lib")
[2] pry(main)> $LOAD_PATH << jaro_winkler_path
[3] pry(main)> require 'jaro_winkler'
=> true

Our system sets the $LOAD_PATH for required gems, so this works for us. Now if we try the same with the version currently on RubyGems:

$ gem install jaro_winkler
$ rm -rf ~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/jaro_winkler-1.5.2/lib/jaro_winkler/jaro_winkler_ext.bundle
$ rm -rf ~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-17/2.6.0-static/jaro_winkler-1.5.2/
$ pry
Ignoring jaro_winkler-1.5.2 because its extensions are not built. Try: gem pristine jaro_winkler --version 1.5.2
[1] pry(main)> jaro_winkler_path = File.expand_path("~/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/jaro_winkler-1.5.2/lib")
[2] pry(main)> $LOAD_PATH << jaro_winkler_path
[3] pry(main)> require 'jaro_winkler'
LoadError: cannot load such file -- jaro_winkler/jaro_winkler_ext
from ~/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'

I know this is some really esoteric stuff, and not really something required in 99.999% of cases

tonytonyjan commented 5 years ago

@milch Thanks for your great work and making the gem better 🍻