Search code examples
rubyrubygemscross-platformcode-organization

How should I manage platform specific code in my Ruby gem?


I'm writing a gem that will have a platform specific (OSX, Windows and Linux) portion, as well as a platform independent portion. Each platform specific section will probably also depend on other platform specific gems.

I'm not very sure how to organize this.

Should I write a shared gem for the platform independent part, then three gems for the platform specific parts, and specify the shared gem as a dependency for each of them?

Or is there a clever way to use the platform to set the (platform specific) dependencies in my gemspec?

Or something else entirely?


Solution

  • This will probably sound like a cop-out answer, but it really depends on the gem and its internals. I would say it would make a decent amount of sense to have, in your main require file, logic that requires the platform-specific files for your gem based on the platform. For example:

    # a user requires your library
    require 'that_awesome_gem'
    
    # in your gem's lib/that_awesome_gem.rb
    if PLATFORM.os_x? # or whatever
      require 'that_awesome_gem/os_x/module1'
      require 'that_awesome_gem/os_x/module2'
    elsif PLATFORM.win?
      require 'that_awesome_gem/win/module1'
      require 'that_awesome_gem/win/module2'
    end
    

    You could also allow the user to specify which version they want via their require statement.

    # lib/that_awesome_gem/os_x.rb
    PLATFORM.set_manual(:os_x)
    require 'that_awesome_gem'
    
    # lib/that_awesome_gem/win.rb
    PLATFORM.set_manual(:win)
    require 'that_awesome_gem'
    
    # in the user's app
    require 'that_awesome_gem/os_x'
    

    (Note: obviously defining a global constant in your app isn't a great idea, but you get the general idea. :)