2013-03-07 30 views
9

Dlaczego to nie działa?Dlaczego `wyślij` kończy się niepowodzeniem z ulepszeniem Ruby 2.0?

module StringRefinement 
    refine String do 
    def bar 
     length 
    end 
    end 
end 

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

Czy ktoś może wyjaśnić dlaczego tutaj nie działa send? I czy istnieje sposób dynamicznego wywoływania metod zdefiniowanych w wyrafinowaniu? Nie mogę znaleźć dobrego, pełnego wyjaśnienia, jak udoskonalenia działają w Ruby 2.0.

+1

Ponieważ jest eksperymentalna? – texasbruce

+0

@oldergod Naprawdę? Właśnie wypróbowałem to ponownie, kopiując i wklejając powyższy kod bezpośrednio do podważenia i otrzymałem dokładnie ten sam błąd. Używam również wersji 2.0.0-p0. Czy na pewno robisz dokładnie to, co napisałem? –

+0

@SeanMackesey masz rację, moje złe. – oldergod

Odpowiedz

9

Ponieważ the specification mówi tak:

metoda pośrednia dostęp

Każda metoda pośrednia dostępu, takich jak Kernel#send, Kernel#method i Kernel#respond_to? nie będą honorować udoskonaleń w kontekście metody rozmówcy podczas odnośnika.

+0

Dzięki za wyjaśnienie, że Jorg. Wiesz dlaczego? –

0

Kusiło mnie, aby powiedzieć "To jest zgodne z projektem". Ale znowu it's quite possible this design is not entirely stable. Na przykład, funkcja określania zakresu module i class została już kilka miesięcy temu objęta removed.

W tej chwili nawet na Ruby HEAD jedynym sposobem jest skorzystanie z korzeniem wszelkiego zła:

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

Ale tak naprawdę, to tylko dla laboratorium, prawda? Nie odrywaj takiego kodu, kotek umrze.

Powiązane problemy