2013-03-07 4 views
9

Warum funktioniert das nicht?Warum schlägt `send` mit der Verfeinerung von Ruby 2.0 fehl?

module StringRefinement 
    refine String do 
    def bar 
     length 
    end 
    end 
end 

using StringRefinement 
"abcdefghijklmnopqrstuvwxyz".send(:bar) 
#NoMethodError: undefined method 'bar' for "abcdefghijklmnopqrstuvwxyz":String 

Kann jemand erklären, warum send hier nicht funktioniert? Und gibt es eine Möglichkeit, Methoden, die in einer Verfeinerung definiert sind, dynamisch aufzurufen? Ich kann keine gute, vollständige Erklärung dafür finden, wie Verfeinerungen in Ruby 2.0 funktionieren.

+1

Weil es experimentell ist? – texasbruce

+0

@oldergod Wirklich? Ich habe es gerade noch einmal versucht, indem ich den oben genannten Code direkt in den HTML-Code kopiert und eingefügt habe und den exakt gleichen Fehler erhalten habe. Ich benutze auch 2.0.0-p0. Bist du sicher, dass du genau das machst, was ich gepostet habe? –

+0

@SeanMackesey du hast recht, mein schlechtes. – oldergod

Antwort

9

Weil the specification sagt so:

Indirekte Methode greift

Jede indirekte Methode Zugang wie Kernel#send, Kernel#method und Kernel#respond_to? dürfen nicht Verfeinerungen in der Anruferkontext während Methodensuche ehren.

+0

Danke für die Klärung, dass Jorg. Weißt du, warum? –

0

Ich bin versucht zu sagen "Das ist mit Absicht". Aber wieder it's quite possible this design is not entirely stable. Zum Beispiel die module und class Scoping-Funktion wurde vor ein paar Monaten removed.

Im Moment sogar auf Ruby-HEAD den einzige Weg ist, um die Wurzel aller Übel zu verwenden:

eval "puts 'abcdefghijklmnopqrstuvwxyz'.bar" # => 26 

Aber wirklich, das ist nur für das Labor, nicht wahr? Löse diesen Code nicht, Kätzchen würde sterben.