Я разрабатываю драгоценный камень, который в настоящее время является чистым Ruby, но я также разрабатываю более быстрый вариант C для одной из функций. Функция доступна, но иногда медленная, в чистом Ruby. Медленность будет влиять только на некоторых потенциальных пользователей (зависит от того, какие функции им нужны и как они их используют), поэтому имеет смысл иметь доступный камень с грациозным откатом для функций Ruby, если он не может скомпилироваться в целевой системе.
Я хотел бы сохранить варианты Ruby и C этой функции в одном драгоценном камне и обеспечить лучший (то есть самый быстрый) опыт от жемчужины при установке. Это позволило бы мне поддерживать самый широкий набор потенциальных пользователей из одного моего проекта. Это также позволит другим людям, зависимым от камней и проектов, использовать наилучшую доступную зависимость от целевой системы, в отличие от версии с наименьшим общим знаменателем для совместимости.
Я ожидал, что require
вернется во время выполнения, чтобы он появился в основном файле lib/foo.rb
, просто так:
begin
require 'foo/foo_extended'
rescue LoadError
require 'foo/ext_bits_as_pure_ruby'
end
Однако я не знаю, как заставить установку gem проверять (или пытаться и терпеть неудачу) на встроенную поддержку расширения, чтобы gem правильно установил, может ли он построить foo_extended. Когда я исследовал, как это сделать, я в основном нашел обсуждения с нескольких лет назад, например. http://permalink.gmane.org/gmane.comp.lang.ruby.gems.devel/1479 и http://rubyforge.org/pipermail/rubygems-developers/2007-November/003220.html, которые подразумевают Ruby драгоценные камни действительно не поддерживают эту функцию. Ничего недавнего, так что я надеюсь, что кто-то из SO будет иметь некоторые более современные знания?
Мое идеальное решение было бы способом обнаружить, прежде чем пытаться построить расширение, чтобы целевой Ruby не поддерживал (или, возможно, просто не хотел, на уровне проекта) родные расширения C. Но также, механизм try/catch будет в порядке, если не слишком грязный.
Возможно ли это, если да, то как? Или совет, чтобы опубликовать два варианта драгоценных камней (например, foo
и foo_ruby
), которые я нахожу при поиске, по-прежнему актуальной лучшей практике?