SORU
3 NİSAN 2010, CUMARTESİ


Tam olarak neden eval kötü olduğunu?

Lisp ve Scheme programcılar genellikle eval kesinlikle gerekli olmadıkça kaçınılmalıdır demek olduğunu biliyorum. Birçok programlama dilleri için aynı öneri gördüm ama henüz eval kullanımına karşı açık deliller listesini gördüm. Burada eval kullanarak potansiyel sorunların bir hesap bulabilirim?

Örneğin, biliyorum sorunların GOTO yapısal programlama (yapan programlar okunmaz ve sabit korumak yapar güvenlik sorunları bulmak zor, vb), ama ben hiç görmedim argümanlar karşı eval.

İlginçtir ki, aynı argümanlar karşı GOTO geçerli olacaktır karşı devamı için, ama görüyorum ki bu üçkağıtçılar, örneğin, varsayalım ki bu devam filmi, "kötü" siz ... sadece kullanırken dikkatli olun. Kod üzerine devamı (yanılıyor olabilirim -- görebildiğim kadarıyla) kullanarak daha fazla kod üzerine eval kullanarak kaşlarını olasıdır.

Düzenleme:VAY, bu çok hızlıydı! Beş dakikadan az bir sürede üç cevap! Yani cevap şu ana kadar

  • Kullanıcıların giriş doğrulama ve değerlendirme için gönderme kötülük değil
  • Kullanarak derlenmiş yerine yorumlanmış kod ile mümkün olabilir eval
  • Eval kod okunmaz (okunamayan bir kod yazabilir bence, ancak herhangi bir "güçlü bu çok bir sorun değil yani" özellikler) . olmadan yapabilir
  • Yeni başlayanlar olabilir karışık karıştırma derleme ve değerlendirme-zaman zaman karıştırma eval ve makrolar (ama bence sorun olmaz bir kez olsun bir firma kavramak dilinizi nasıl çalışır-Lisp veya diğer)

Şimdiye kadar, öyle görünüyor ki eğer ben kod oluşturun ve doğrudan kullanmak şey kullanıcı giriş doğrudan); eğer bildiklerimi çevre eval olacak; ve eğer ben değilim bekliyor süper hızlı kod, eval, TAMAM.

CEVAP
3 NİSAN 2010, CUMARTESİ


EVAL kullanmamalıdır çeşitli nedenleri vardır.

Yeni başlayanlar için ana nedeni: gerek yok.

Örnek (varsayarak Common Lisp):

Farklı operatörler ile ifade EVALualte:

(let ((ops '(  *)))
  (dolist (op ops)
    (print (eval (list op 1 2 3)))))

Bu iyi yazılmış gibi:

(let ((ops '(  *)))
  (dolist (op ops)
    (print (funcall op 1 2 3))))

Yeni başlayanlar Lisp öğrenme EVAL, ne işe yarayacak ki burada bir çok örnek var ama ifade olarak değerlendirilir ve bir de işlev bölümü değerlendirebilir beri gerek yok. Çoğu zaman EVAL kullanımı değerlendiricisi anlayış eksikliği gösterir.

Makrolar ile aynı sorun. Genellikle yeni başlayanlar fonksiyonlar yazmak gerekir nerede makrolar, - gerçekten ne olduğunu anlamak değil ve bir fonksiyon zaten iş yok değil anlama yazma.

Genellikle iş EVAL kullanmak için yanlış bir araçtır ve genellikle yeni başlayanlar için her zamanki Lisp değerlendirme kurallarını anlamak olmadığını gösterir.

Eğer EVAL, ihtiyacınız varsa Eğer FUNCALL, REDUCE APPLY gibi bir şey yerine kullanılabilecek olmadığını kontrol edin.

  • FUNCALL - bağımsız değişken bir işlev çağrısı: (funcall ' 1 2 3)
  • REDUCE - değerler listesi bir işlev çağrısı ve sonuçları birleştirmek için: (reduce ' '(1 2 3))
  • APPLY - bağımsız olarak bir liste ile bir arama fonksiyonu: (apply ' '(1 2 3)).

S: gerçekten eval ihtiyaç ya da derleyici/istiyorum zaten değerlendiricisi mu?

Ana sebep biraz daha ileri düzey kullanıcılar için EVAL önlemek için:

  • istediğiniz emin olmak için kodunuzu derlenmiş, çünkü derleyici onay kodu için birçok sorun oluşturur ve daha hızlı bir kod bazen çok çok çok ÇOK (bu faktör 1000 ;-) )daha hızlı kod

  • inşa ve değerlendirmesi gereken kod mümkün olduğunca erken derlenmiş olamaz.

  • keyfi kullanıcı girişi eval güvenlik sorunları açılır

  • EVAL ile değerlendirme bazı kullanın, yanlış zamanda gerçekleşmesi ve sorunlara inşa edebilirsiniz

Basit bir örnek ile son nokta açıklamak için:

(defmacro foo (a b)
  (list (if (eql a 3) 'sin 'cos) b))

Yani ya SIN COS ilk parametre kullanır dayalı bir makro yazmak istiyorum.

(foo 3 4) (sin 4) ve (foo 1 4) (cos 4).

Şimdi olabilir:

(foo (  2 1) 4)

Bu istenen sonucu vermez.

Bir değişkeni Değerlendirerek 32**: makro tamir etmek isteyebilir

(defmacro foo (a b)
  (list (if (eql (eval a) 3) 'sin 'cos) b))

(foo (  2 1) 4)

Ama bu hala çalışmıyor:

(defun bar (a b)
  (foo a b))

Değişkenin değerini sadece derleme zamanında bilinmiyor.

Genel önemli bir nedeni EVAL önlemek için:genellikle çirkin kesmek için kullanılır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • androidandme

    androidandme

    10 Mart 2009
  • MrSuicideSheep

    MrSuicideShe

    9 NİSAN 2010
  • The Fashion Sight

    The Fashion

    22 AĞUSTOS 2011