2012-11-07 16 views
16

Bazen aralarında rescue, else, ensure vb. Ifadeler olmadan ruby'de kullanılan begin...end bloklarını görüyorum. Örneğin:Ruby'nin `code 'start-end` end `un bir kod bloğu olarak kullanılmadan istenmeyen sonuçları var mı?

foo = begin 
    whatever = 3 
    "great" 
    42 
end 

kodlayıcının niyet, öyle görünüyor ki, sadece kendi blok-gruplama kalitesi için begin...end blok kullanmaktır (begin sanki do vardı). Şahsen ben bu kullanım türünün en az sürpriz ilkesini ihlal ettiğini düşünüyorum (begin benim için istisna-taşıma anlamına gelir).

begin...end'un bu şekilde kullanılmasının istenmeyen sonuçları var mı? begin...end blokları, bu kullanımı tehlikeli hale getiren herhangi bir anlamsal farklılığa sahiptir (belki istisnai kullanımda?).

Ruby'nin sözdizimi inanılmaz derecede incelikli ve burada beklemekte tuhaf tuhaflıklar varsa şaşırmam.

+0

Daha önce hiç böyle bir kod görmedim. Bir genel kaynak dosyasına işaret edebilir misiniz? –

+0

@SergioTulentsev: Bir kaynak dosya bulana kadar, bir blog yorumu: http://blog.rubybestpractices.com/posts/rklemme/003-The_Universe_between_begin_and_end.html # comment-9011441 – pje

+0

Nasıl tehlikeli olacağını bilmiyorum, ama IMO yanlış: bir yöntem olmalı. –

cevap

27

Bazen bir değişkene bir şey atamak istiyorsam ancak önce atamak istediğim değeri hesaplamak zorundayım. Kodu bu şekilde biraz daha düzenli hale getirir. Bence kullanıcı tercihi. Temel olarak diyorsunuz: Ben bir şeyler atamadım, ama istediğim değeri elde etmek için ilk önce bazı şeyler yapmam gerekiyor. bunun yerine

if @cache.nil? 
    do_something! 
    @cache = read_value 
end 

arasında, Memoization yaparken It

@cache ||= begin 
    do_something! 
    read_value 
end 

Burada ne yararlanmakta olup Yakut tercüman bir yığın olmasıdır yapabileceği özellikle yararlıdır ve her ifade genellikle bir şey itecektir Yığın veya yığından bir şey alın. Atama sadece son şeyi yığından alır ve atayacaktır (bu durumda başlangıç ​​/ sondan son satır). Bunu çoğu kez bilmek (Ruby'de yığın yaklaşımı) yararlı olabilir.

En azından ihmalkarlığı ihlal etse de, sanırım onu ​​kullanmak isteyip istemediğiniz kullanıcı tercihidir.

Sen buna Ruby MRI 1.9 oluşturduğu neler baytkodu talimatları bakarak beklenmedik bir şey yapmaz görebilirsiniz:

RubyVM::InstructionSequence::compile("c = begin; a = 5; 6; end").to_a 

[:trace, 1], 
[:trace, 1], 
[:putobject, 5], 
[:setlocal, 2], 
[:trace, 1], 
[:putobject, 6], 
[:dup], 
[:setlocal, 3], 
[:leave] 

İz yığın izlerini adildir, bunu göz ardı edebilirsiniz. Dup, yığındaki son öğeyi çoğaltır. Bu örnekte, a yerel değişkenin numarası 2 ve c yerel değişkenin numarası 3'dir (dolayısıyla a değişkenine atanacaktır). a = 5; c = 6 ile karşılaştırıldığında bunun tek yan etkisi, dup yönergesidir; bu, yönteminizin yığın boyutunun 1 yuvalı daha büyük olacağı anlamına gelir. Fakat bu özellikle önemli değildir, çünkü yorumlayıcı bu özel yöntemde iken herhangi bir etkiye sahiptir ve yığın için bellek zaten önceden ayrılmış olduğundan, yalnızca yığın göstergesinin aksi takdirde 1'den daha fazla azaltılacağı anlamına gelir. Yani temelde hiç bir değişiklik yok. En iyi duruma getirme seçenekleri dup olsa bile muhtemelen kaybolacaktır.

+1

Bu benim soruma cevap vermiyor. – pje

+0

Dediğim gibi, bu kesinlikle geçerli, bu yüzden istenmeyen sonuçlar yok. Bu sadece kod tarzı bir şey. – mrbrdo

+0

ve bunun için iyi bir fikir, ancak "istenmeyen sonuçlar yoktur" cevabınızda yok. – pje

İlgili konular