Bắt đầu với điều này:
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
Nếu bạn nhìn vào mã được tạo của bạn, chức năng backtrack
được định nghĩa trên dòng 29:
static VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del) { ... }
Nó có bảy đối số, bản gốc sáu, cộng VALUE self
vì nó đã được chuyển đổi thành một phương thức trên lớp Scan
.
Các cuộc gọi đến chức năng này, trên dòng 67 trông như thế này:
end = backtrack(ss, s, p, mm, ins, del);
Nó chỉ có sáu đối số. RubyInline không chuyển đổi điều này thành một cuộc gọi đến một phương thức trên đối tượng, nó chỉ đơn giản là sao chép nó đúng nguyên văn. Đây cũng là nơi các cảnh báo về makes integer from pointer without a cast
đến từ: định nghĩa chức năng đã được chuyển đổi thành số VALUE
giây, nhưng bạn đang gọi với các loại ban đầu.
Các thông báo lỗi nói rằng lỗi là từ dòng 73 trong backtrack_inline.rb
vì chỉ thị trên dòng 54 của mã được tạo:
# line 61 "./backtrack_inline.rb"
mà về cơ bản cho trình biên dịch để "thiết lập lại" dòng và tập giá trị của nó lỗi và xử lý dòng tiếp theo (55) là dòng 61 trong tệp ./backtrack_inline.rb
. Dòng thực tế là 67, 12 trước 55, nhưng trình biên dịch báo cáo nó là 73, 12 trước 61 (giá trị được đặt lại thành) và từ một tệp differnt. Kỹ thuật này không thực sự làm việc trong trường hợp này vì nó không tính đến các dòng bổ sung được thêm bởi RubyInline. Dòng thực tế trong nguồn là 69.
Sửa lỗi đơn giản cho việc này là thay đổi định nghĩa của hàm backtrack
thành hàm C chứ không phải thêm hàm đó làm phương thức trên đối tượng. Thay đổi builder.c
thành builder.prefix
(trên dòng 38 của tệp Ruby). Điều này sẽ không hoạt động nếu bạn muốn có backtrack
sẵn có như một phương thức trên đối tượng trong Ruby. Nếu đó là trường hợp bạn có thể cần tạo một hàm khác làm phương thức, sau đó kết thúc hàm backtrack "thực".
Tiếp theo, nhìn vào
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
Điều này thực sự đề cập đến dòng 61 của mã được tạo, trông giống như:
char* s = StringValuePtr(rb_iv_get(self, "@seq"));
StringValuePtr
là một macro which is defined as:
#define StringValue(v) rb_string_value(&(v))
này là nơi &
trong lvalue required as unary '&' operand
xuất phát từ. Bạn cần phải thêm một biến địa phương để được vế trái:
VALUE seq = rb_iv_get(self, "@seq");
char* s = StringValuePtr(seq);
Trong trường hợp của tôi (Mac OS X Snow Leopard, Ruby 1.9.3-p0, RubyInline 3.11.0) hai sự thay đổi này đã chạy kịch bản mà không có lỗi , nhưng đã đưa ra cảnh báo:
backtrack_inline.rb:47: warning: implicit conversion shortens 64-bit value into a 32-bit value
Điều này thực sự đề cập đến dòng 46 của file ruby:
return (s - ss) - 1;
s
và ss
là char *
, tức là 64 bit pointe rs (trên máy này), và kiểu trả về của hàm là int
- 32 bit. Thêm một diễn viên rõ ràng cố định này:
return (int)((s - ss) - 1);
Nó bây giờ chạy sạch:
ruby-inline $ ruby backtrack_inline.rb
14
ruby-inline $
(Tôi hy vọng 14 là câu trả lời đúng!)
Dưới đây là một version of the script with these changes.
Nó hơi say cài đặt ruby của tôi trong khi thử nghiệm :) – RocketR