POSIX mermilerindeki işlevler ve değişkenler için ayrı ad alanları


13

Kısa çizgide, işlevler ve değişkenler ayrı ad alanlarında yaşıyor gibi görünüyor:

fn(){
    fn="hello world"
}
fn; echo "The value is $fn!" #prints: The value is hello world!
fn; echo "The value is $fn!" #prints: The value is hello world!
#the fn variable doesn't conflict with the fn function

Bu, tireye özgü bir özellik mi yoksa POSIX garantisi mi?


2
Kodunuz fnişlevin ayrı bir ad alanında olduğunu kanıtlamaz ; bir kez yürütmek tanımını ortadan kaldırsaydı, tam olarak aynı davranışı görürdük. Fonksiyonun hala tanımlanmış olduğunu göstermelisiniz, örneğin type fndaha sonra.
alexis

Yanıtlar:


13

Bir garanti :

2.9.5 İşlev Tanım Komutu

İşlev, yeni bir komut parametresi ile bir bileşik komutu çağırmak için basit bir komut olarak kullanılan kullanıcı tanımlı bir addır. Bir işlev, "işlev tanımlama komutu" ile tanımlanır. [...]

Bu işleve fname adı verilir; Başvuru, bir ad (bkz. XBD Adı) olduğundan ve özel bir yerleşik yardımcı programın adı olmadığından emin olmalıdır. Bir uygulama, işlev adındaki diğer karakterlerin uzantı olarak kullanılmasına izin verebilir. Uygulama, işlevler ve değişkenler için ayrı ad boşlukları bulundurmalıdır.


Ayrıca unutmayınız unsetvardır -vve -fverilen adıyla değişken veya fonksiyon unsetting arasında seçim yapmak. bash(diğer birçok kabukları aksine) unset olacak foo işlevi ile unset foohiçbir varsa foodeğişken (!), POSIX tarafından izin verilen bir davranış. Bu yüzden POSIX komut dosyalarında her zaman ya -vda -f(ve elbette bashkomut dosyalarında da kullanmak iyi bir uygulamadır , ancak unsetbir değişkenin her zaman ayarlanamayabileceğini unutmayın bash, bashdeğişken kapsam belirleme işleminin oldukça az sorunu vardır).
Stéphane Chazelas

Kabuk öncesi bash'de, hem değişkeni hem de işlevi belirli bir adla dışa aktarırken sorun yaşayacağınıza dikkat edin, çünkü bash her ikisi için de aynı ortam değişkeni adını kullanır (çevreye iki kez koyarak bazı komutlar kaldırabilir) bunlardan biri)
Stéphane Chazelas

8

Değişkenler ve işlevler tire içinde farklı ad alanlarında bulunur ve bu POSIX tarafından da belirtilir :

Uygulama, işlevler ve değişkenler için ayrı ad boşlukları bulundurmalıdır.

Buna ek olarak, değişkenlerin varsayılan olarak genel kapsamı vardır. Bazı kabuklar (örn. Bash, ksh ve zsh), localanahtar kelimeyi yalnızca yerel kapsamı olan bir işlevde değişkenleri bildirmek için sağlar.

Evet, gördüğünüz davranış POSIX tarafından garanti edilmektedir.

POSIX henüz standardize local , henüz :

Erken bir teklifteki işlevlerin tanımı, işlevlerin minyatür kabuk komut dosyaları gibi davranması gerektiği fikrine dayanıyordu; yani, değişkenleri paylaşmak dışında , bir yürütme ortamının çoğu öğesi yeni bir yürütme ortamıymış gibi davranmalıdır, [..]

[..] Bir işlev içindeki yerel değişkenler dikkate alındı ​​ve başka bir erken teklife dahil edildi (özel yerleşik tarafından kontrol edildi local), ancak işlevler için geliştirilen basit modele uymadıkları ve henüz eklemeye bazı karşıtlıklar olduğu için kaldırıldı tarihsel pratiğin bir parçası olmayan yeni bir özel yerleşik. Bu yerel değişken mekanizmanın bu standardın gelecekteki bir versiyonunda benimsenmesi durumunda uygulamalar tanımlayıcıyı ayırmalıdır local( typesetKornShell'de kullanıldığı gibi).

(benimkini vurgula)


(80'lerin sonlarından itibaren) temelli çizgi de bulunan kül local, oradaki en tutarlı arabirimlerden birine sahipti (örneğin bash'daki ciddi kırıklara kıyasla), bash sadece yakın zamanda (4.4) ödünç aldı local -(yerel kapsam için) seçenekler) külten ( $-sadece bu bir değişken için kül tarzı kapsam belirleme ). ksh ve yash yok local(yalnızca pdksh varyantları var local), ancak typesetbunun yerine (ksh93'te typesetyalnızca ksh sözdizimi kullanılarak bildirilen işlevlerde yerel (statik) kapsam sağlar).
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.