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
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.
Neden &; ad std quot;" kötü olara...
Neden JavaScript eval fonksiyonu kötü ...
Sihirli bir numara, ne olduğunu ve ned...
AngularJS : ng-bind daha iyi olduğunu ...
Neden Bahar'In ApplicationContext...