如果gem安装不支持,本机扩展将回溯到纯Ruby

我正在开发一个宝石,这是一个Ruby,但是我也为其中一个功能开发了一个更快的C变体.该功能在纯Ruby中可用,但有时较慢.缓慢只会影响一些潜在的用户(取决于他们需要哪些功能,以及它们如何使用它们),因此如果无法在目标系统上编译,则将宝石提供给仅限于Ruby的功能是有意义的.

我想在一个宝石中保留该功能的Ruby和C变体,并从安装的gem中提供最佳(即最快)的体验.这将使我能够从我的一个项目中支持最广泛的潜在用户.它还将允许其他人的依赖宝石和项目对目标系统使用最佳可用依赖关系,而不是兼容性的最低公分母版本.

我希望在运行时需要在主要的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/1479http://rubyforge.org/pipermail/rubygems-developers/2007-November/003220.html意味着Ruby宝石并不真正支持功能.没有什么最新的,所以我希望有一个人有一些更新的知识?

我的理想解决方案是在尝试构建扩展之前,检测到目标Ruby不支持(或者根本不想在项目级别)C本机扩展.但是,如果不是太脏,也可以尝试/捕捉机制.

这是可能的吗?或者是发布两个宝石变体的建议(例如foo和foo_ruby),当我搜索时,我找到了当前的最佳实践?

解决方法

这是一个想法,根据 http://guides.rubygems.org/c-extensions/http://yorickpeterse.com/articles/hacking-extconf-rb/的信息.

看来你可以将逻辑放在extconf.rb中.例如,查询RUBY_DESCRIPTION常量并确定您是否位于支持本机扩展的Ruby中:

$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]"

所以你可以尝试像在extconf.rb中的条件(在extconf.rb)中的代码

unless RUBY_DESCRIPTION =~ /jruby/ do

  require 'mkmf'

  # stuff    
  create_makefile('my_extension/my_extension')

end

显然,您将需要更复杂的逻辑,抓取“宝石安装”等参数.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...