Üstten Kesme ve Quote Fonksiyonu

Giriş

Benim tecrübelerime göre, AutoLISP’de kesme işareti () sembolünün amacını açıklayan çok az dokümantasyon var ve mevcut eğitimlerle karşılaştığım açıklamalar genellikle oldukça kısa ve bu operatöre ait asıl amacı atlamaktadır.

Sonuç olarak, birçok acemi AutoLISP programcısının, mevcut kodda bu sembolle karşılaştığında sıklıkla kafasının karıştığını ve kod yazarken kesme işaretinin ne zaman kullanılıp kullanılmayacağının farkında olmadığını fark ettim.

Bu nedenle, hem kesme işareti operatörünün hem de AutoLISP quote  fonksiyonunun amacını ve bunların kullanımının sonuçlarını ayrıntılarıyla anlatan bu makaleyi yazmaya karar verdim.

Üstten Kesme (‘)

Kesme işareti veya tek tırnaklı karakter, bir ifadeyi veya sembolü, açıklama olarak alınmak üzere, gerçek bir ifade olarak işaretler ve AutoLISP yorumlayıcısı tarafından değerlendirilmemesini sağlar.

Alınan ifade AutoLISP verilerinin herhangi bir biçimi olabilir, ancak kesme işareti genellikle liste veya sembollerle kullanılır, zira çoğu diğer AutoLISP veri biçimi (dizeler, tamsayılar, reel sayılar) kelimesi kelimesine sabitlerdir ve dolayısıyla bu veri biçimleri için, kesme işareti kullanımı gerekmez.

Sabit Veri

Sabit veya sabit veriler içeren ifadeler (yani değerlendirildiğinde değiştirilmeyen veriler), ifade edilecek ifadede sembol olmadıkları ve dolayısıyla veri içeriğinin değişmesine neden olacakları için, ifadeler olarak alıntılanabilir.

Örneğin, aşağıdaki tamsayının listesini düşünün:

_$ (list 1 2 3 4 5)

(1 2 3 4 5)

Yukarıdaki liste, her bir tam sayıyı list  fonksiyona argüman olarak geçirerek oluşturulmuştur. list  fonksiyonu daha sonra sağlanan bağımsız değişkenlerin her birini değerlendirecek ve tüm bağımsız değişkenleri fonksiyona aktarılan sırayla içeren bir liste döndürecektir.

Bununla birlikte, her bir tamsayı sabit olduğu için, verilerin list  fonksiyonu tarafından değerlenmesine gerek yoktur.

Bu nedenle, bu liste ile aynı sonucu elde etmek için kesme işaretini kullanarak gerçek bir ifade olarak alıntı yapabilir:

 

_$ ‘(1 2 3 4 5)

(1 2 3 4 5)

Benzer şekilde, eş çiftlerin bir listesini oluşturma işlemini düşünün:

_$ (list (cons 1 “a”) (cons 2 “b“) (cons 3 “c”))

((1 . “a”) (2 . “b”) (3 . “c”))

Burada, her tam sayı ve dize çifti bağımsız değişken olarak iletilir ve eş çift döndüren cons fonksiyonuyla değerlendirilir (iki atom verildiğinden); sonuç eş çiftlerin her biri argüman olarak geçirilir ve listeyi gösterildiği gibi döndürmek için list fonksiyonu tarafından değerlendirilir.

Bununla birlikte, her aşamada, en içerdeki veriler tamamen değişmeden kalır ve dolayısıyla cons ve list  fonksiyonlarının her değerlendirilmesi gereksizdir ve koda verimsizlik getirir.

Sabit eş veri çiftleri eşdeğeri olarak üç fonksiyonun değerlendirilmesine gerek kalmadan aynı sonuca ulaşmak için kesme işaretini kullanarak gerçek bir ifade olarak kesme işareti kullanılabilir:

_$ ‘((1 . “a”) (2 . “b”) (3 . “c”))

((1 . “a”) (2 . “b”) (3 . “c”))


Pratik bir örnek sunmak için, ssget fonksiyonuna filtre listesi argümanı olarak sağlanabilecek eş çiftlerin listesini düşünün.

Aşağıdaki örnek, çizim veri tabanındaki tüm Kapalı Ensiz sürekli çizgi “LWPolyline” nesnelerinin bir seçim setini alacaktır:

(ssget “_X” ‘((0 . “LWPOLYLINE”) (-4 . “&=”) (70 . 1)))

Yukarıdaki filtre listesi yalnızca sabit verileri içerdiğinden, liste kesme işaretini kullanarak gerçek bir ifade olarak alıntılanabilir.

Değişken Veri

Elbette AutoLISP verilerini alıntılamak için kesme işaretinin ne zaman kullanılabileceği konusunda sınırlamalar vardır. Bu tür bir sınırlama, veriler sabit olmadığı zaman olmakla birlikte, değerlendirildiğinde farklı sonuçlar verilecek simgeler veya ifadeler içerir.

Aşağıdaki örneği düşünün:

_$ (setq x 5)

5

_$ (list 1 2 3 4 x)

(1 2 3 4 5)

Burada x sembolüne 5 tam sayı değeri atanır; bu sembol ve 1’den 4’e kadar olan tamsayılar daha sonra list  fonksiyonuna argümanlar olarak aktarılır.

Sağlanan her argüman list  fonksiyonu tarafından değerlendirildiğinden x sembolü 5 değerini verecek şekilde değerlendirilir ve yukarıda gösterildiği gibi sembolün değerlendirilen değeri içeren liste geri döndürülür.

Bununla birlikte, kesme işareti kullanılarak liste alıntılandığında, aşağıda görüldüğü üzere sonuç değişecektir:

_$ (setq x 5)

5

_$ ‘(1 2 3 4 x)

(1 2 3 4 X)

Kesme işareti, listeyi gerçek bir ifade olarak işaretlediğinden, liste içeriği AutoLISP yorumlayıcısı tarafından değerlendirilmez ve x sembolü listede bir sembol olarak kalır.


Önceki pratik örneğimizi genişleterek, kullanıcıya, ssget  ifadesi tarafından seçilecek Kapalı Ensiz sürekli çizgi “LWPolyline” içeren bir tabakanın “layer” adını belirtmesini isteyelim:

(if (snvalid (setq lay (getstring t “\nTabakayı belirleyin: “)))

    (ssget “_X” (list ‘(0 . “LWPOLYLINE”) ‘(-4 . “&=”) ‘(70 . 1) (cons 8 lay)))

)

Artık filtre listesi, lay değişkenin bir sonucu olarak değişken veriyi içerdiğinden, liste artık bir değişmez ifade olarak alıntılanamaz, ancak list fonksiyonu kullanılarak oluşturulmalıdır.

Bununla birlikte, filtre listesinde bulunan dört eş çiftten üçü sabit veri içerdiğinden, eş çiftler kesme işareti kullanılarak gerçek anlamda ifadeler olarak alıntılanabilir. Son nokta çiftleri ise, değerlendirilen iki bağımsız değişkenin cons  fonksiyonuna aktarılması ile oluşturulmuştur.

Fonksiyon Argümanları

Yukarıdaki örneklerde, alıntılanan listelerin diğer setq fonksiyonu gibi fonksiyonlara argüman olarak neredeyse daima aktarılacağını unutmayın:

Bununla birlikte, genel olarak, aşağıdaki örnekte gösterildiği gibi, verilen argümanın bir liste olması gerekmez:

_$ (mapcar+ ‘(1 2 3 4 5) ‘(6 7 8 9 10))

(7 9 11 13 15)

Burada, kesme işareti + fonksiyonu, sabit veri içerdiği için iki liste bağımsız değişkeninin de belirtildiği şekilde mapcar  fonksiyonu için bir argüman olarak işaretlenmek için kullanılır.

Bu fonksiyon argümanı alıntılanmadıysa fonksiyon sembolü, işaretçiyi fonksiyon tanımına getirmek için mapcar  fonksiyonu tarafından değerlendirilecek ve mapcar  fonksiyonu sonuç olarak bir geçersiz fonksiyon “’bad function” hatası döndürecektir.

Aynı mantık, aşağıdaki örnekte, iki nokta arasındaki orta noktanın hesaplanmasında gösterildiği gibi, mapcar  ifadesinin listesindeki her bir öğe üzerinde mapcar  fonksiyonu tarafından değerlendirilecek fonksiyonel argüman olarak isimsiz bir lambda fonksiyonu sağlanırken de geçerlidir:

_$ (mapcar ‘(lambda ( a b ) (/ (+ a b) 2.0)) ‘(12.3 45.6 78.9) ‘(32.1 65.4 98.7))

(22.2 55.5 88.8)

mapcar  fonksiyonunun işleyişini açıklayan daha fazla bilgi için, AutoLisp’te Mapcar & Lambda Fonksiyonları makalesine bakınız.

Başka bir örnek olarak aşağıdaki getvar ifadesine bir göz atın:

_$ (getvar osmode)

255

Burada simgenin, getvar fonksiyonuna bir argüman olarak geçirildiğinde değerlendirilmemesini sağlamak için, osmode  sembolü alıntılanır. Hem getvar hem de setvar fonksiyonları bir dizge veya sembol argümanını kabul ettiğinden, bu ifade yukarıda gösterildiği gibi OSMODE sistem değişkeninin değerini döndürür.

Şayet simge argümanı alıntılanmadıysa, getvar fonksiyonu argümanı, etkin belge ad alanındaki sembole atanan herhangi bir değeri (örneğin, bir setq veya set ifadesi yoluyla) verecek şekilde değerlendirecektir; Sembol hiçbir değeri tutmazsa (veya geçerli bir dizge veya sembol argümanından farklı bir değer taşıyorsa) getvar ifadesi hatalı bir argüman türü: (veya stringp sembolp) hatasıyla sonuçlanır.

 

Son olarak, Visual LISP ActiveX getboundingbox yöntemini çağıran aşağıdaki ifadeyi izleyin:

(if (setq ent (car (entsel)))

    (vla-getboundingbox (vlax-ename->vla-object ent) ‘pt1pt2)

)

Getboundingbox yöntemi üç parametre gerektirir: sınırkutusu hesaplanacak VLA-Nesnesi ve yöntem tarafından çıktı değerlerini tutmak için iki simge parametresi.

Çıkış parametrelerinin kullanılması, yöntemin fonksiyon değerlendirmesinden sonra döndürülen tek değer yerine, birden çok değer döndürmesini sağlar (ki bu, bu yöntem için boş “nil” olamaz).

Yöntemi çağırırken, sembolün kendisinin, böyle bir sembol değerlendirildiğinde elde edilen değer yerine yöntemin argümanı olarak sağlandığından emin olmak için, sembol parametreleri alıntılanır. Yöntemin başarıyla değerlendirilmesinin ardından, verilen simgeler, sağlanan VLA-Nesnesinin sınırlayıcı kutusunu açıklayan sol alt ve sağ üst WCS koordinatlarına atanır.

Quote Fonksiyonu

AutoLISP’in  quote fonksiyonu, kesme işaretinin işlevsel eşdeğerdir. Bu fonksiyon, herhangi bir AutoLISP ifadesi olabilir ve yalnızca sağlanan ifadeyi değerlendirmeden döndüren tek bir bağımsız değişkeni kabul eder.

Bu nedenle, ilk örneğimizde, kesme işaretinin yerine şu şekilde quote fonksiyonu kullanılabilir:

_$ (quote (1 2 3 4 5))

(1 2 3 4 5)

Burada tamsayılar listesi quote fonksiyonuna bir argüman olarak aktarılır ve listedeki ilk öğe yerine tüm fonksiyon olarak değerlendirilir ve (şayet listenin değeri hesaplanırsa) tanımsız fonksiyon “bad function” hatasıyla sonuçlanır. Verilen argüman değerlendirilmez; ancak sadece quote fonksiyonuyla döndürülür.


Benzer şekilde, daha önceki örneklerimizdeki mapcar ifadeleri, kesme işareti yerine quote fonksiyonu kullanılarak yeniden yazılabilir:

_$ (mapcar (quote +) (quote (1 2 3 4 5)) (quote (6 7 8 9 10)))

(7 9 11 13 15)

Bununla birlikte, ikinci mapcar örneğinde, kesme işareti veya quote fonksiyonu yerine function  fonksiyonunun yerine geçerek kod VLX veya FAS dosyasına derlendiğinde, lambda fonksiyonu optimize edilebilir:

_$ (mapcar (function (lambda ( a b ) (/ (+ a b) 2.0))) (quote (12.3 45.6 78.9)) (quote (32.1 65.4 98.7)))

(22.2 55.5 88.8)

function fonksiyonu, görsel LISP derleyicisine kapalı sembolün veya lambda ifadesinin derleme sırasında bağlanıp optimize edilebilecek bir fonksiyon argümanı olduğunu söylemesi dışında, quote fonksiyonu ile aynıdır.

lambda ifadeleri çalışma zamanında tanımlandığından, Visual LISP derleyicisi, yerleşik AutoLISP fonksiyonları veya defun ile tanımlanan isimlendirilmiş fonksiyonlarla mümkün olduğu gibi derleme sırasında bu ifadeleri optimize edemez. Benzer şekilde, kesme işareti veya quote fonksiyonu kullanılarak alıntılandığında, derleyici, işlevi bağlamadan veya optimize etmeden, verilen lamda ifadesini sadece veri olarak görür.

Bununla birlikte, derleyiciye, fonksiyon sırasında, değerlendirme sırasında yerleşik veya isimlendirilmiş fonksiyonlara benzer performans vermek üzere derleme sırasında lambda işlevini en iyi duruma getirme talimatı verilir.

Ayrıca function fonksiyonu her hangi bir yerleşik veya isimlendirilmiş fonksiyon tarafından tanımlanan sembollerle de kullanılabilir. Bununla birlikte, bu fonksiyonlar derlendiği zaman, hali hazırda optimize edilmiş olduğu için, performansta çok fazla kazanç sağlanmaz.


Çalışma Zamanı Değerlendirmesi

quote  fonksiyonu, kesme işaretiyle aynı şekilde çalıştığı için, görünüşte kesme işaretinin yerine çok daha az tuş vuruşu ile kullanılabileceğinden, bu fonksiyonun gereksiz olduğu anlaşılabilir.

Bununla birlikte, arzulanan sonucu elde etmek için kesme işaretinin yerine quote  fonksiyonunun kullanılması gerektiği durumlar vardır.

Buna örnek, çalışma zamanında tanımlanan gerçek ifadelerdir.

Aşağıdaki basitleştirilmiş örneğe bir göz atın:

_$ (eval (listdefun-q fun ‘( / lst ) (listsetq ‘lst (listquote (list 0.0 (* pi 0.5) pi (* pi 1.5))))))

FUN

Değerlendirildiğinde, yukarıdaki ifade lst yerel değişkenine dört sayısal öğenin bir listesini (π’nin katları) atayan tek bir setq ifadesi içeren fun fun fonksiyonu tanımlar.

Yukarıdaki işleve defun-q ifadesini kullanarak kasıtlı olarak tanımladım, böylece fun sembolü değerlendirildiğinde fonksiyon tanımının sonucu ortaya çıkacaktır:

_$ fun

((/ LST) (SETQ LST (QUOTE (0.0 1.5708 3.14159 4.71239))))

Fonksiyonun tanımını takiben, setq ifadesinin, liste öğelerinin tekrar hesaplanmasına gerek kalmadan, lst simgesine şimdi bir değişmez liste atadığını ve daha da önemlisi, her öğenin hiçbir kesinlik kaybı olmadan bir liste atadığını gözlemleyin.

Aynı sonucu, alıntılanmış bir dize listesi kullanarak elde edebilmek için, aynı hassaslığı elde etmek için, π’nin her bir irrasyonel katının, kodda ondalık basamakların yaklaşık olarak ifade edilmesi gerekeceğini düşünün.

Alternatif olarak, fonksiyon, aritmetik ifadelerin fonksiyon tanımına dahil edileceği şekilde tanımlanabilir:

_$ (defun-q fun ( / lst ) (setq lst (list 0.0 (* pi 0.5) pi (* pi 1.5))))

FUN

 

_$ fun

((/ LST) (SETQ LST (LIST 0.0 (* PI 0.5) PI (* PI 1.5))))

Bununla birlikte, bu şekilde tanımlanan fonksiyonla, π‘nin katları hesaplanır ve fonksiyon her değerlendirildiğinde gereksiz yere yeniden hesaplanır ve verimsizlik ortaya çıkar. Yukarıdaki örnek için bu performans kaybı elbette önemsizdir ve çalışma zamanında fonksiyonu tanımlamayı seçerken kodun okunabilirliği üzerindeki olumsuz etkisini de göz önüne almalıdır; Bununla birlikte, şayet liste potansiyel olarak binlerce giriş içeriyorsa, tekrarlanan hesaplama fark edilir hale gelecektir.

Dolayısıyla, bu yapı, yönetilebilir olabilen ve doğrudan doğruluğu koruyan ve verimliliği arttıran, aynı zamanda çalışma zamanında oluşturulacak program kaynak koduna dahil edilebilen büyük listelere izin verir.

Hakkında Sertan Türkan

AutoCAD Beyni

Bunu da Kontrol edin

Revitte Filtreler Listesi

Revit’te çeşitli iletişim kutularında, kategorileri disipline göre filtrelemek için Filtre “Filter” listesini kullanabilirsiniz. Kategorilerini listelemek …

Bir cevap yazın

Yardıma mı ihtiyacınız var? Chat with us
Bir görüşme başlatmak için lütfen önce gizlilik politikamızı kabul edin.