2009-11-06 9 views
19

Sprawdziłem najnowszą wersję Ruby, aby zagrać z ostatnimi zmianami. Pierwszą rzeczą, którą próbowałem zrobić, było wywołanie Ruby lambda/block/proc, tak jak w przypadku wywołania Pythona.Dlaczego wywołanie lambda w Ruby 1.9 nie jest możliwe bez kropki przed nawiasami?

a = lambda {|x| puts x} 
a.call(4) # works, and prints 4 
a[4] # works and prints 4 
a.(4) # same 
a(4) # undefined method 'a' for main:Object 

Dlaczego nie jest to ostatnie połączenie możliwe? Czy kiedykolwiek tak będzie?

Odpowiedz

10

AFAIK to dlatego, że ruby ​​nie pozwala zdefiniować metody dla obiektu (). Przyczyna, dla której nie można zdefiniować metody (), wynika prawdopodobnie z faktu, że nawiasy są opcjonalne w wywołaniach metod.

I za to, co warte, oto hack aby wywołać lambdy użyciu ()http://github.com/coderrr/parenthesis_hacks/blob/master/lib/lambda.rb

+0

Czy możesz wyjaśnić nieco skrypt lambda? – Geo

+0

ok, przy próbie wywołania metody o nazwie 'blah()' i 'method_missing' jest wyzwalana, sprawdza, czy lambda o nazwie' blah' jest zdefiniowana w odpowiednim kontekście. Jeśli taka lambda jest zdefiniowana, to po prostu wywołuje lambdę przy użyciu zwykłej składni "blah.call", przekazuje również wszystkie parametry, które zostały podane – horseyguy

+0

Myślę, że jest to niesamowity hack. Dziękuję Ci. – Geo

6

Ruby jest w zasadzie w 100% zorientowany obiektowo, ale czasami próbuje ukryć ten fakt dla ... wygody? Znajomość?

Zasadniczo funkcje zdefiniowane "na najwyższym poziomie" są naprawdę zdefiniowane jako metody na obiekcie globalnym. Aby to wykonać, wywołanie bez specyfikatora jest naprawdę konwertowane na wywołanie metody o tej nazwie na wymienionym obiekcie globalnym. Ten styl sprawia, że ​​rzeczy wyglądają bardziej scenariuszowo. Ruby próbuje to zrobić na ostatnim przykładzie.

Pierwsze dwa przykłady są parsowane, ponieważ Ruby wie, że próbujesz uzyskać dostęp do metod obiektu proc. - pamiętaj, że nawet [] to tylko metoda, którą możesz zdefiniować. Ta z wyraźną kropką działa również, ponieważ kropka oznacza "wyślij tę wiadomość do tego obiektu" (w tym przypadku, a).

Wiem, że niczego nie "rozwiązuje", ale mam nadzieję, że to trochę pomaga.

+1

fakt, że Ruby jest OOP nie wyjaśnia, dlaczego nie można użyć '()' do wywoływania lambda. Wiele języków pozwala zdefiniować metodę '()' dla twoich obiektów. Pytanie brzmi: dlaczego ruby ​​nie pozwalają ci zdefiniować operatora '()'? – horseyguy

+1

(Właśnie teraz zobaczyłem ten komentarz ...) Dobre pytanie. Może ma to coś wspólnego z tym, jak można pominąć nawiasy w pewnych sytuacjach; byłoby dziwne mieć niejawną przeciążoną wywołanie operatora. –