Zsh'de, işlev arama yolu ($ fpath), içerdikleri işleve ilk kez ihtiyaç duyulduğunda otomatik olarak yüklenebilecek dosyaları içeren bir dizin dizisi tanımlar.
Zsh'ın iki otomatik yükleme dosyası modu vardır: Zsh'nin yerel yolu ve ksh'ın otomatik yükleme işlevine benzeyen başka bir mod. KSH_AUTOLOAD seçeneği ayarlanmışsa, ikincisi etkindir. Zsh'nin yerel modu varsayılandır ve burada başka bir yoldan tartışmayacağım (ksh tarzı otomatik yükleme hakkında ayrıntılar için bkz. "Man zshmisc" ve "man zshoptions").
Tamam. Bir dizinin `~ / .zfunc 'olduğunu ve işlev arama yolunun bir parçası olmasını istediğinizi varsayalım:
fpath=( ~/.zfunc "${fpath[@]}" )
Bu, özel dizini arama yolunun önüne ekler . Bu, zsh'nin kurulumundaki işlevleri kendikiyle geçersiz kılmak istiyorsanız (örneğin, zsh'ın CVS deposundaki '_git' gibi güncellenmiş bir tamamlama işlevini kullanarak kabuğun daha eski bir sürümüyle kullanmak istediğinizde) önemlidir.
Ayrıca, $ fpath dizinindeki dizinlerin özyinelemeli olarak aranmadığını da belirtmek gerekir. Özel dizininizin yinelenerek aranmasını istiyorsanız, bunun gibi kendinizle ilgilenmeniz gerekir (aşağıdaki kod parçası `EXTENDED_GLOB 'seçeneğinin ayarlanmasını gerektirir):
fpath=(
~/.zfuncs
~/.zfuncs/**/*~*/(CVS)#(/N)
"${fpath[@]}"
)
Eğitimsiz bir göze şifreli görünebilir, ancak gerçekten sadece ~ / .zfunc altındaki tüm dizinleri $ fpath'a eklerken, "CVS" (yani bir bütününüzü kontrol etmeyi planlıyorsanız yararlıdır) işlev ağacını zsh’ın CVS’sinden özel arama yolunuza ekleyin).
Aşağıdaki satırı içeren bir dosya `~ / .zfunc / hello 'olduğunu varsayalım:
printf 'Hello world.\n'
Şimdi yapmanız gereken tek şey , ilk referansı üzerine otomatik olarak yüklenecek işlevi işaretlemektir :
autoload -Uz hello
“-Ez neyle ilgili?” Diye soruyorsunuz? Bu, sadece hangi seçeneklerin ayarlandığı fark etmeksizin, “autoload” ın doğru olanı yapmasına neden olacak bir seçenek kümesidir. “U”, işlev yüklenirken takma adın genişlemesini devre dışı bırakır ve “z”, “KSH_AUTOLOAD”, ne nedenle olursa olsun ayarlanmış olsa bile, zsh tarzı otomatik yüklemeyi zorlar.
Bundan sonra, yeni `merhaba 'işlevinizi kullanabilirsiniz:
% zsh merhaba
Selam Dünya.
Bu dosyaları bulmakla ilgili bir kelime: Bu sadece yanlış . Bu ~ / .zfunc / hello 'dosyasını besleyecekseniz, sadece "Merhaba dünya" yazacaktır. bir Zamanlar. Daha fazlası değil. Hiçbir fonksiyon tanımlanmayacak. Ve ayrıca, fikir olduğunda yalnızca işlevin kodunu yüklemektir gerekli . `Autoload sonra' işlevin tanımı çağrının değil okuyun. İşlev, gerektiğinde otomatik olarak yüklenecek şekilde işaretlendi.
Ve son olarak, $ FPATH ve $ fpath hakkında bir not: Zsh, bunları bağlantılı parametreler olarak tutar. Küçük harf parametresi bir dizidir. Büyük harfli sürüm, girişler arasında iki nokta üst üste gelen bağlantılı diziden gelen girişleri içeren bir skalar dizisidir. Bu yapılır, çünkü skalerlerin bir listesini kullanmak, skaler parametresini kullanan kodun geriye dönük uyumluluğunu korurken, aynı zamanda diziler kullanarak daha doğaldır. $ FPATH (skalar biri) kullanmayı seçerseniz, dikkatli olmanız gerekir:
FPATH=~/.zfunc:$FPATH
çalışacak, aşağıdaki çalışmaz:
FPATH="~/.zfunc:$FPATH"
Bunun nedeni, tilde genişlemesinin çift tırnak içinde gerçekleştirilmemesidir. Bu muhtemelen problemlerin kaynağı. Eğer echo $FPATH
yaklaşık işareti değil genişletilmiş yol yazdırır o zaman çalışmaz. Güvende olmak için, böyle bir tilde yerine $ HOME kullanırdım:
FPATH="$HOME/.zfunc:$FPATH"
Olduğu söyleniyor, bu açıklamanın en üstünde yaptığım gibi array parametresini kullanmak istiyorum.
Ayrıca $ FPATH parametresini vermemelisiniz. Sadece mevcut kabuk işlemine ihtiyaç duyuyor, çocuklarından hiçbirine ihtiyaç duymuyor.
Güncelleme
'$ Fpath' içerisindeki dosyaların içeriği ile ilgili olarak:
Zsh tarzı otomatik yükleme ile, bir dosyanın içeriği tanımladığı işlevin gövdesidir. Böylece bir satır içeren "merhaba" adlı bir dosya echo "Hello world."
tamamen "merhaba" adlı bir işlevi tanımlar. hello () { ... }
Kodu koymakta özgürsün
, ama bu gereksiz olurdu.
Bir dosyanın yalnızca bir işlev içerebileceği iddiası tam olarak doğru değildir.
Özellikle, fonksiyon bazlı tamamlama sisteminden (compsys) bazı fonksiyonlara bakarsanız, bunun yanlış bir kavram olduğunu hemen anlarsınız. Bir işlev dosyasında ek işlevler tanımlamakta özgürsünüz. Ayrıca, işlevin ilk çağrıldığı zaman yapmanız gerekebilecek herhangi bir başlatma işlemini de yapabilirsiniz. Ancak, her zaman dosyadaki dosya gibi adlandırılmış bir işlev tanımlayacak ve dosya sonunda bu işlevi çağıracaksınız , bu nedenle işleve ilk başvuruda bulunacak şekilde çalışacaktır.
Eğer - alt fonksiyonlarla - dosya içindeki dosya gibi bir fonksiyon tanımlamamışsanız, içinde fonksiyon tanımları olan (yani dosyadaki alt fonksiyonlarınkiler) bu fonksiyonla bitirdiniz. Dosya gibi adlandırılmış işlevi her çağırdığınızda, tüm alt işlevlerinizi etkin bir şekilde tanımlayacaksınız. Normalde, istediğiniz şey bu değildir , bu nedenle dosyadaki dosya gibi adlandırılan bir işlevi yeniden tanımlarsınız.
Size nasıl çalıştığı hakkında bir fikir verecek kısa bir iskelet ekleyeceğim:
# Let's again assume that these are the contents of a file called "hello".
# You may run arbitrary code in here, that will run the first time the
# function is referenced. Commonly, that is initialisation code. For example
# the `_tmux' completion function does exactly that.
echo initialising...
# You may also define additional functions in here. Note, that these
# functions are visible in global scope, so it is paramount to take
# care when you're naming these so you do not shadow existing commands or
# redefine existing functions.
hello_helper_one () {
printf 'Hello'
}
hello_helper_two () {
printf 'world.'
}
# Now you should redefine the "hello" function (which currently contains
# all the code from the file) to something that covers its actual
# functionality. After that, the two helper functions along with the core
# function will be defined and visible in global scope.
hello () {
printf '%s %s\n' "$(hello_helper_one)" "$(hello_helper_two)"
}
# Finally run the redefined function with the same arguments as the current
# run. If this is left out, the functionality implemented by the newly
# defined "hello" function is not executed upon its first call. So:
hello "$@"
Bu aptal örneği çalıştırırsan, ilk çalıştırma şöyle görünür:
% zsh merhaba
initialising ...
Selam Dünya.
Ve ardışık çağrılar şöyle görünecek:
% zsh merhaba
Selam Dünya.
Umarım bu işleri temizler.
(Tüm bu püf noktaları kullanan daha karmaşık gerçek dünya örneklerinden biri, zsh'nin fonksiyon tabanlı tamamlama sisteminden daha önce bahsedilen ' _tmux ' işlevidir.)