Tôi đang phát triển một gem, hiện là Ruby thuần túy, nhưng tôi cũng đang phát triển một biến thể C nhanh hơn cho một trong các tính năng. Tính năng này có thể sử dụng được, nhưng đôi khi chậm, trong Ruby thuần khiết. Sự chậm chạp sẽ chỉ ảnh hưởng đến một số người dùng tiềm năng (phụ thuộc vào các tính năng họ cần và cách họ sử dụng chúng), do đó, nó có ý nghĩa khi có sẵn đá quý với dự phòng duyên dáng đối với các hàm chỉ có Ruby nếu nó không thể biên dịch trên hệ thống đích.Native extensions fallback thành Ruby tinh khiết nếu không được hỗ trợ trên gem install
Tôi muốn duy trì các biến thể Ruby và C của đối tượng địa lý trong một đá quý và cung cấp trải nghiệm tốt nhất (tức là nhanh nhất) từ đá quý khi cài đặt. Điều đó sẽ cho phép tôi hỗ trợ nhóm người dùng tiềm năng rộng nhất từ một dự án duy nhất của tôi. Nó cũng sẽ cho phép các đá quý và dự án phụ thuộc của người khác sử dụng sự phụ thuộc tốt nhất có sẵn trên một hệ thống đích, trái ngược với một phiên bản mẫu số chung thấp nhất để tương thích.
tôi mong chờ các require
để dự phòng trong thời gian chạy để xuất hiện trong tập tin chính lib/foo.rb
chỉ đơn giản như thế này:
begin
require 'foo/foo_extended'
rescue LoadError
require 'foo/ext_bits_as_pure_ruby'
end
Tuy nhiên, tôi không biết làm thế nào để có được quá trình cài đặt đá quý để kiểm tra (hoặc cố gắng và không) cho hỗ trợ tiện ích mở rộng gốc để đá quý cài đặt chính xác cho dù nó có thể xây dựng 'foo_extended' hay không. Khi tôi nghiên cứu cách thực hiện điều này, tôi chủ yếu tìm thấy các cuộc thảo luận từ vài năm trước, ví dụ: http://permalink.gmane.org/gmane.comp.lang.ruby.gems.devel/1479 và http://rubyforge.org/pipermail/rubygems-developers/2007-November/003220.html có nghĩa là đá quý Ruby không thực sự hỗ trợ tính năng này. Không có gì gần đây mặc dù, vì vậy tôi hy vọng một người nào đó trên SO có một số kiến thức up-to-date?
Giải pháp lý tưởng của tôi sẽ là cách phát hiện, trước khi thử xây dựng phần mở rộng, mục tiêu mà Ruby không hỗ trợ (hoặc có thể không muốn ở cấp độ dự án). Nhưng cũng có, một cơ chế thử/nắm bắt sẽ ổn nếu không quá bẩn.
Điều này có thể thực hiện được không? Hoặc là lời khuyên để có hai biến thể đá quý được xuất bản (ví dụ: foo
và foo_ruby
), mà tôi đang tìm kiếm khi tôi tìm kiếm, vẫn là phương pháp hay nhất hiện tại?
Hai đá quý là tốt, ví dụ: đá quý json có hai biến thể: ['json'] (https://rubygems.org/gems/json) (với phần mở rộng C) và [' json_pure'] (https://rubygems.org/gems/json_pure) (Ruby thuần khiết) – Stefan
@Stefan: Trong cuộc trò chuyện tôi đã liên kết, tác giả/người bảo trì 'json' và' json_pure' dường như sẽ thích nó hơn. Cũng như công việc phụ xuất bản hai biến thể của đá quý, các dự án phụ thuộc có thể là phụ thuộc cho cái gì đó khác, cuối cùng phải sử dụng mẫu số thấp nhất hoặc cũng phải cung cấp hai biến thể để quản lý các phụ thuộc mà chúng không mã hóa . Tôi sẽ không gọi đó là "tốt", nhưng nếu nó là tốt nhất có thể, thì đó là tất cả tôi có thể làm quá –
@Stefan: Chắc chắn ý định thiết kế của Neil thể hiện trong OP là đúng. Câu hỏi của anh ấy rất tuyệt vời và rất quan trọng, tôi quan tâm đến câu trả lời cho bản thân, xin vui lòng upvote nó. –