2009-11-06 7 views
19

En son değişikliklere sahip olmak için en yeni Ruby sürümünü inceledim. Yapmaya çalıştığım ilk şey, bir Ruby lambda/block/proc'u, bir Python ile yapılabildiği gibi çağırmaktı.Neden Ruby 1.9 lambda çağrıları parantezin önünde nokta olmadan mümkün değil?

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 

Neden son çağrı mümkün değil mi? Hiç olacak mı?

cevap

10

AFAIK, çünkü Ruby bir nesne için () yöntemini tanımlamanıza izin vermez. () yöntemini tanımlamanıza izin vermeme nedeni, büyük olasılıkla yöntem aramalarında parantezlerin isteğe bağlı olması gerçeğinden kaynaklanmaktadır.

Ve buna değer ne için

, burada () http://github.com/coderrr/parenthesis_hacks/blob/master/lib/lambda.rb

+0

lambda betiğini biraz açıklayabilir misiniz? – Geo

+0

tamam, 'blah()' adında bir yöntemi çağırmaya çalıştığınızda ve 'method_missing' tetiklendiğinde, uygun bağlamda 'blah' adı verilen bir lambda olup olmadığını kontrol eder. Eğer böyle bir lambda tanımlanmışsa, o zaman lambdayı her zamanki 'blah.call' sözdizimini kullanarak çağırır, ayrıca – horseyguy

+0

verilen parametreler boyunca geçer, bu harika bir hack olduğunu düşünüyorum. Teşekkür ederim. – Geo

6

Ruby temelde% 100 nesne yönelimli, ancak bazen bu gerçeği gizlemek için ... kolaylık? Aşinalık? Temel olarak "üst düzeyde" tanımlanan işlevler, gerçekten genel bir nesne üzerindeki yöntemler olarak tanımlanır. Bu işi yapmak için, belirteci olmayan bir çağrı, söz konusu global nesnede bu adı taşıyan bir yöntemi çağırmaya gerçekten dönüştürülür. Bu stil, işleri daha çok bet-y yapar. Ruby son örneğinizle yapmaya çalışıyor.

İlk iki örnek paramparça ayrılıyor çünkü Ruby sizden proc nesnesinin yöntemlerine erişmeye çalıştığınızı biliyor - unutmayın bile [] tanımlayabileceğiniz bir yöntemdir. Açık noktaya sahip olanı da çalışır çünkü nokta "bu iletiyi bu nesneye gönder" anlamına gelir (bu durumda, a).

Bunun bir şeyi "çözmediğini" biliyorum, ama umarım biraz yardımcı olur.

+1

yakut() 'Bir lambda çağırmak için' sen neden kullanamazsınız cepten açıklamaz olması kullanarak lambdas çağırmak bildirmek için bir beygir. Birçok dil, nesneleriniz için bir '()' yöntemi tanımlamanıza izin verir. Soru şu ki, neden ruby ​​yapmayan bir '()' operatörünü tanımlayalım? – horseyguy

+1

(Şimdilik bu yorumu gördünüz ...) İyi soru. Belki de belirli durumlarda parantezleri nasıl çıkarabileceğinizle ilgili bir şey vardır; örtülü aşırı yüklenmiş operatör çağrısına sahip olmak garip olurdu. –

İlgili konular