2013-12-20 7 views
7

Wie behandelt man Ruby 2.0.0 Schlüsselwort Argumente von einer C-Erweiterung?Ruby Schlüsselwort Argumente in C-Extensions

Hintergrund

def example(name: 'Bob' hat_color: 'red') 
    puts "#{name} has a #{hat_color} hat!" 
end 

example         #=> "Bob has a red hat!" 
example(name: 'Joe', hat_color: 'blue') #=> "Joe has a blue hat!" 

Schlüsselwort Argumente (wie oben) sind sehr nützlich, wenn Methoden der Handhabung, die eine Menge von verschiedenen Call-Sequenzen oder Optionen. Ich habe eine solche Methode in einer C-Erweiterung (eine blit Methode, die die meisten der OpenGL-Zeichnung in meinem Projekt behandelt) und ich frage mich, wie ich die Methode Schlüsselwortargumente von Ruby behandeln könnte.

Ideen

Basierend auf einigen Recherchen habe ich getan, ich glaube, dass eine solche Behandlung könnte durch die : Option auf die Funktion rb_scan_args C durchgeführt werden. Ich konnte jedoch keine Informationen darüber finden, wie ich es verwenden könnte.

Antwort

5

Es gibt keine Kernmethode, die derzeit Schlüsselwortargumente direkt verwendet, d. H. klass.instance_method(:method).parameters gibt nie :key für integrierte Klassen zurück.

Sie müssen wahrscheinlich eine Methode definieren, die ein Argument akzeptiert, in diesem Fall einen Hash und es selbst analysieren. Um dies zu tun, können Sie rb_scan_args mit dem : Argument verwenden, um ein Hash vom letzten Argument (z. B.) oder Code ähnlich dem OPTHASH_GIVEN_P Makro (in array.c) zu erhalten. Aus dem Hash können Sie rb_get_kwargs verwenden, um die gewünschten Werte zu erhalten. Ich habe nicht untersucht, wie Sie einen Fehler für nicht erkannte Schlüsselwortargumente erzeugen können, wenn Sie dies wünschen. Ich denke, dass die meisten Kernmethoden diese Überprüfung nicht durchführen (zumindest noch).

Sie können Ihre Methode in Ruby mit den Schlüsselwortelementen definieren und von dort eine interne C-Methode aufrufen. Dies würde Ihnen für freie unbekannte Schlüssel überprüfen und eine ordnungsgemäße parameters Signatur geben.

Ich hoffe, dass diese Situation mit einem überarbeiteten api zur Verbesserung der Methoden in Ruby 2.2 zu definieren, die es natürliches Schlüsselwort Argumente in C-Funktionen haben würden, unter anderem

+0

Ok (this issue sehen), danke! Wenn Schlüsselwortargumente nicht von der C-Erweiterungs-API verarbeitet werden können, was macht dann die Option ':' zu 'rb_scan_args'? – tophat

+0

@tophat: Antwort bearbeitet, HTH. –