Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving a name collision in 3rd party gem code

Tags:

ruby

rubygems

My project depends on Sunspot, which in turn depends on progress_bar. progress_bar defines a class (outside of any module/namespace) called ProgressBar.

My test code depends on minitest-reporters, which in turn depends on ruby-progressbar. ruby-progressbar defines a class (also outside of any module/namespace) called ProgressBar.

Being new to Ruby, it took me an embarassing amount of time to track down the fact that the two ProgressBar classes were conflicting. I know how to namespace my own code to prevent such problems, but is there any way to resolve such a collision in 3rd party code?

Update:

The owner of minitest-reporters very kindly replaced his usage of the (apparently abandoned) ProgressBar with yet another progress library, PowerBar. So this addressed my problem. But guess what- PowerBar also pollutes the global namespace! This just seems pathological in Ruby...

like image 919
George Armhold Avatar asked Jul 04 '12 21:07

George Armhold


2 Answers

If you're faced with

# alice_bad_code.rb

class ProgressBar
  def initialize
    puts "Alice bad code progress bar created"
  end
end

class AliceBadCode
  def initialize
    @progress_bar = ProgressBar.new
  end
end

and

# bob_bad_code.rb

class ProgressBar
  def initialize
    puts "Bob bad code progress bar created"
  end
end

class BobBadCode
  def initialize
    @progress_bar = ProgressBar.new
  end
end

Then I'd try something like

require "alice_bad_code"
class AliceBadCode
  ProgressBar = ::ProgressBar
end
Object.send(:remove_const, "ProgressBar")

require "bob_bad_code"
class BobBadCode
  ProgressBar = ::ProgressBar
end
Object.send(:remove_const, "ProgressBar") # Just in case

Welcome to Ruby metaprogramming!

However, the best way to monkey patch a third-party library is not to monkey patch it at all, and file a bug report as per Jorg W Mittag's answer.

like image 93
Andrew Grimm Avatar answered Oct 02 '22 13:10

Andrew Grimm


  • If it's in your own code (not applicable in this particular case): namespace your friggin constants!
  • If it's in someone else's code: file a bug telling them to namespace their friggin constants! … and wait for them to release a new version …

There's really not more you can do.

like image 40
Jörg W Mittag Avatar answered Oct 02 '22 13:10

Jörg W Mittag