คั่นเนมสเปซสำหรับฟังก์ชั่นและตัวแปรในเชลล์ POSIX


13

ในเส้นประฟังก์ชั่นและตัวแปรดูเหมือนจะอยู่ในเนมสเปซที่แยกต่างหาก:

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

นี่เป็นคุณลักษณะเฉพาะหรือการรับประกัน POSIX หรือไม่


2
รหัสของคุณไม่ได้พิสูจน์ว่าfnฟังก์ชันนั้นอยู่ในเนมสเปซแยกต่างหาก หากดำเนินการครั้งเดียวได้ลบล้างคำจำกัดความของเราจะเห็นพฤติกรรมเดียวกัน คุณควรแสดงให้เห็นว่าฟังก์ชั่นยังคงถูกกำหนดเช่นtype fnหลังจากนั้น
alexis

คำตอบ:


13

การรับประกัน :

2.9.5 คำสั่งนิยามฟังก์ชัน

ฟังก์ชั่นเป็นชื่อที่ผู้ใช้กำหนดซึ่งใช้เป็นคำสั่งง่าย ๆ ในการเรียกคำสั่งผสมกับพารามิเตอร์ตำแหน่งใหม่ ฟังก์ชั่นถูกกำหนดด้วย "คำสั่งนิยามฟังก์ชั่น" [ ... ]

ฟังก์ชั่นชื่อ fname; แอปพลิเคชันจะต้องทำให้แน่ใจว่าเป็นชื่อ (ดูชื่อ XBD) และไม่ใช่ชื่อของยูทิลิตี้ในตัวพิเศษ การใช้งานอาจอนุญาตให้ตัวละครอื่น ๆ ในชื่อฟังก์ชั่นเป็นส่วนขยาย การดำเนินการจะต้องรักษาพื้นที่ชื่อที่แยกต่างหากสำหรับฟังก์ชั่นและตัวแปร


โปรดทราบว่าunsetมี-vและ-fให้เลือกระหว่างการยกเลิกการตั้งค่าตัวแปรหรือฟังก์ชั่นด้วยชื่อที่กำหนด bash(เมื่อเทียบกับเปลือกหอยอื่น ๆ ส่วนใหญ่) จะล้างค่าfoo ฟังก์ชั่นที่มีunset fooถ้าไม่มีfooตัวแปร (!), พฤติกรรมได้รับอนุญาตจาก POSIX นั่นเป็นเหตุผลที่ในสคริปต์ POSIX ก็ปฏิบัติที่ดีในการใช้อย่างใดอย่างหนึ่ง-vหรือ-f(และแน่นอนในbashสคริปต์เช่นกัน แต่ทราบว่าunsetอาจไม่เคยล้างค่าตัวแปรในbash, bashการกำหนดขอบเขตตัวแปรค่อนข้างมีปัญหาไม่กี่)
Stéphane Chazelas

โปรดทราบว่าใน pre-shellshock bash คุณจะมีปัญหาเมื่อส่งออกทั้งตัวแปรและฟังก์ชั่นด้วยชื่อที่กำหนดเนื่องจาก bash จะจบลงด้วยการใช้ชื่อตัวแปรสภาพแวดล้อมเดียวกันสำหรับทั้งสอง (วางไว้สองครั้งในสภาพแวดล้อม หนึ่งในนั้น)
Stéphane Chazelas

8

ตัวแปรและฟังก์ชั่นอยู่ในเนมสเปซที่แตกต่างกันในเส้นประและนี่ยังระบุโดยPOSIX :

การดำเนินการจะต้องรักษาพื้นที่ชื่อที่แยกต่างหากสำหรับฟังก์ชั่นและตัวแปร

นอกจากนั้นตัวแปรมีขอบเขตทั่วโลกตามค่าเริ่มต้น เชลล์บางตัว (เช่น bash, ksh และ zsh) จัดเตรียมlocalคีย์เวิร์ดเพื่อประกาศตัวแปรในฟังก์ชันที่มีขอบเขตโลคัลเท่านั้น

ดังนั้นใช่พฤติกรรมที่คุณเห็นนั้นรับประกันโดย POSIX

POSIX ยังไม่ได้มาตรฐาน local , ยัง :

คำอธิบายของฟังก์ชั่นในข้อเสนอแรกนั้นขึ้นอยู่กับความคิดที่ว่าฟังก์ชั่นควรทำงานเหมือนสคริปต์เชลล์ขนาดเล็ก นั่นคือยกเว้นตัวแปรที่ใช้ร่วมกันองค์ประกอบส่วนใหญ่ของสภาพแวดล้อมการดำเนินการควรทำตัวเหมือนเป็นสภาพแวดล้อมการดำเนินการใหม่ [.. ]

[.. ] ตัวแปรท้องถิ่นภายในฟังก์ชั่นได้รับการพิจารณาและรวมอยู่ในข้อเสนอก่อนหน้าอื่น (ควบคุมโดย built-in พิเศษlocal) แต่ถูกลบออกเพราะพวกเขาไม่พอดีกับโมเดลที่พัฒนาขึ้นสำหรับฟังก์ชั่นอย่างง่ายและเพราะยังมีการคัดค้าน ในตัวพิเศษใหม่ที่ไม่ได้เป็นส่วนหนึ่งของการปฏิบัติทางประวัติศาสตร์ การใช้งานควรสำรองตัวบ่งชี้local(รวมถึงtypesetที่ใช้ใน KornShell) ในกรณีที่มีการนำกลไกตัวแปรท้องถิ่นมาใช้ในเวอร์ชันอนาคตของมาตรฐานนี้

(เน้นที่เหมือง)


แอช (จากช่วงปลายยุค 80) ซึ่งเป็นไปตาม dash ก็มีlocalหนึ่งในอินเตอร์เฟซที่สอดคล้องกันมากที่สุดออกไปที่นั่น (เมื่อเทียบกับที่แตกอย่างรุนแรงในการทุบตีเช่น) ทุบตีเมื่อเร็ว ๆ นี้ (4.4) ยืมlocal -(สำหรับขอบเขตท้องถิ่นสำหรับ ตัวเลือก) จากขี้เถ้า (ใช้การกำหนดขอบเขตแบบ Ash สำหรับ$-ตัวแปรเดียวเท่านั้น) ksh และ yash ไม่มีlocal(เฉพาะตัวแปร pdksh เท่านั้นlocal) แต่มีtypesetแทน (ใน ksh93 typesetแสดงขอบเขตภายใน (คงที่) เฉพาะในฟังก์ชันที่ประกาศโดยใช้ไวยากรณ์ ksh)
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.