A partir de ceci:
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
Si vous regardez votre code généré, la fonction backtrack
est définie sur la ligne 29:
static VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del) { ... }
Il a sept arguments, les six originaux, plus VALUE self
comme il a été converti en une méthode sur la classe Scan
.
L'appel à cette fonction, sur la ligne 67 ressemble à ceci:
end = backtrack(ss, s, p, mm, ins, del);
Il n'a que six arguments. RubyInline ne convertit pas cela en un appel à une méthode sur l'objet, il le copie simplement textuellement. C'est également de là que proviennent les avertissements concernant makes integer from pointer without a cast
: la définition de la fonction a été convertie pour prendre VALUE
s, mais vous appelez avec les types d'origine.
Le message d'erreur indique que l'erreur est de la ligne 73 dans backtrack_inline.rb
en raison de la directive sur la ligne 54 du code généré:
# line 61 "./backtrack_inline.rb"
qui indique essentiellement le compilateur de « réinitialiser » les valeurs de ligne et le fichier pour les erreurs, et traitez la ligne suivante (55) comme étant la ligne 61 dans le fichier ./backtrack_inline.rb
. La ligne réelle est 67, 12 en avant de 55, mais le compilateur le signale comme étant 73, 12 en avant de 61 (la valeur à laquelle il a été réinitialisé) et d'un fichier differnt. Cette technique ne fonctionne pas vraiment dans ce cas car elle ne prend pas en compte les lignes supplémentaires ajoutées par RubyInline. La ligne réelle dans la source est 69.
Une solution simple pour cela est de changer la définition de la fonction backtrack
pour qu'elle soit juste une fonction C plutôt que de l'ajouter en tant que méthode sur l'objet. Remplacez builder.c
par builder.prefix
(sur la ligne 38 de votre fichier Ruby). Cela ne fonctionnera pas si vous souhaitez avoir backtrack
disponible en tant que méthode sur l'objet dans Ruby. Si c'est le cas, vous pourriez avoir besoin de créer une autre fonction pour la méthode, qui enveloppe alors la fonction "réelle" de retour arrière.
Ensuite, regardant
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
Cela fait référence à la ligne 61 du code généré, qui ressemble à:
char* s = StringValuePtr(rb_iv_get(self, "@seq"));
StringValuePtr
est un macro which is defined as:
#define StringValue(v) rb_string_value(&(v))
Cette est où le &
en lvalue required as unary '&' operand
vient de. Vous devez ajouter une variable locale à la lvalue:
VALUE seq = rb_iv_get(self, "@seq");
char* s = StringValuePtr(seq);
ces deux modifications Dans mon cas (Mac OS X Snow Leopard, Ruby 1.9.3-p0, RubyInline 3.11.0) a fait l'exécution du script sans erreurs , mais a donné l'avertissement:
backtrack_inline.rb:47: warning: implicit conversion shortens 64-bit value into a 32-bit value
Cela fait référence à la ligne 46 du fichier ruby:
return (s - ss) - 1;
s
et ss
sont char *
, soit 64 bits pointe rs (sur cette machine), et le type de retour de la fonction est int
- 32 bits. Ajout d'un casting explicite fixe ceci:
return (int)((s - ss) - 1);
Il fonctionne maintenant proprement:
ruby-inline $ ruby backtrack_inline.rb
14
ruby-inline $
(je l'espère 14 est la bonne réponse!)
est ici un version of the script with these changes.
Il visse mon installation rubis tout en expérimentant :) – RocketR