2013-04-08 31 views
6

Ben Ruby satır içi hata işleyicileriİstisnalar: parantez ekleme neden bir şey değiştirir?

Durum 1

Bu beklendiği gibi çalışan bir yaygın kullanım şeklidir

def foo 
    raise Error 
end 

bar = foo rescue 1 
# => 1 
bar 
# => 1 

olduğunu nasıl değerlendireceğini anlamak istediğim birkaç şey vardır. foo rescue 1 ifadesi 1 değerini döndürür ve doğru olarak bar'a atanır.

Durum 2

Yakut descructuring diziler olanak tanıdığından, bu davranış tuhaf görünüyor.

baz = 'a' 
baz, bar = foo rescue [1, 2] 
# => [1, 2] 
baz 
# => 'a' 
bar 
# => nil 

ekspresyon dizisi [1, 2] verir, ancak yapısızlaştırabileceğimizi veya atamak etmez. Tamamen atamayı tamamen atlar. 3

olarak parantez içinde hata sarın

Vaka Ancak yapısöküm çalışır.

baz, bar = (foo rescue [1, 2]) 
# => [1, 2] 
baz 
# => 1 
bar 
# => 2 

Vaka 4

Bonus puan: Hata Raising ve satır içi ele çalışırken de atama

baz = raise Error rescue 1 
# => 1 
baz 
# => nil 

atlar Ama parantez ekleyerek işe yapar.

Düzenleme:

Ben 2.0.0

Düzenleme 2 Yakut 1.9.3-p392 ve Ruby bu test:

Ben durumlarda etiket eklendi

Düzenleme 3:

Görünüşe göre bazı insanlar bunu bir soru değil, belki de başlık yeterince açık değildi. İşte tam metinde soru:

Neden bu tutarsızlıklar oluyor ve neden parantez ekleniyor bir şey değiştiriyor?

+0

"Rescue" satırında çok dikkatli olun. Bir sözdizimi hatası veya IO istisnasıyla karşılaşıncaya kadar çok yararlı görünür ve bu 'kurtarma' gizler. Ayağını hedef alan yüklü ve eğimli bir silahtır. –

+0

Daha önce benzer bir sorun [http://www.ruby-forum.com/topic/152260] [tek satırlı kurtarma ve atama önceliği] var. Ama 'Yukihiro Matsumoto' bir sorun olarak kabul edildi ve şimdi düzeltildi.Onu bir hata bileti olarak yükseltebilirsiniz. –

+1

Hata, https://bugs.ruby-lang.org/issues/8239 –

cevap

1

Vakanız 2 bu aynıdır: foo yana

baz = 'a' 
(baz, bar = foo) rescue [1, 2] 

baz için değerlerin bir hata, atama yükseltir ve bar böylece baz"a" olmaya devam etmektedir, başarısız ve barnil, bir olmaya devam etmektedir ayrıştırma aşamasında atanan değer. Ardından, ödev kurtarılır ve dönüş değeri [1, 2] olur.

(baz = raise Error) rescue 1 

atama righthand tarafı hata harekete geçiren beri baz için atama başarısız olur ve baznil olmak kalacağını, bu ayrıştırma sırasında atandı:

Vakanız 4 bu aynıdır sahne. Ardından, atama kurtarıldı ve dönüş değeri 1.

+0

olarak bildirildi Neden = 1 = foo kurtarma 1 'durum 4'le aynı olmaz ve' (bar = foo) kurtarma olarak değerlendirilmeli? 1 ' – gmalette

+0

Sanırım, modifee tek bir belirteç olduğunda, "kurtarma", "if", "while" vb. Gibi değiştiricilerin birleşme gücü kuvvetlidir. – sawa

+2

Yani, her şey akış kontrolünün önceliğine göre atama işleçleri karşısında aşağı doğru kayıyor mu? – gmalette

1

Güncelleme: Üzgünüz, benim örneğim işe yaramadı. Bu, ayrıştırıcıda basit bir ödevin bu sorunu yaşamadıkça bir hata olduğunu tahmin ediyorum.

bar, baz = 1,2 # bar == 1, baz == 2 
bar = foo rescue [3,4] # bar == [3,4], baz == 2 
bar, baz = 1,2 # bar == 1, baz == 2 
bar, baz = foo rescue [3,4] # no assignment done: bar == 1, baz == 2 

Kurtarma önceliği bile, basit atamanın neden yapıldığını ve çoğulluğunun nedenini açıklayamaz.