Понимание лексической области видимости — верна ли Википедия?

Я пытался изучить лексическую область видимости (меня не убеждает использование слова лексический, но это другой разговор), и я посмотрел на запись из Википедии.

Согласно довольно простому примеру сценария Bash

$ x=1 
$ function g () { echo $x ; x=2 ; }
$ function f () { local x=3 ; g ; }
$ f # does this print 1, or 3?
3
$ echo $x # does this print 1, or 2?
1

вывод сценария Bash равен 3, 1. Однако мне кажется, что должно быть 3, 2, потому что функция g печатает (динамическое) значение x, а затем устанавливает значение x = 2.

Нужно ли мне исправлять запись в Википедии или корректировать свое понимание?


person Edwardo    schedule 09.01.2018    source источник
comment
Он устанавливает локальную переменную в f на 2, когда f заканчивается, переменная помещается в корзину. Поместите echo $x после g;   -  person 123    schedule 09.01.2018
comment
Спасибо. Это проясняет для меня ситуацию.   -  person Edwardo    schedule 09.01.2018


Ответы (3)


Переменные Bash используют динамическую область видимости, как и на упомянутой вами вики-странице.

Примеры языков, использующих динамическую область видимости, включают Logo, Emacs Lisp и языки оболочки bash, dash и PowerShell.

Динамическую область видимости довольно легко реализовать. Чтобы найти значение идентификатора, программа может пройтись по стеку среды выполнения, проверяя каждую запись активации (фрейм стека каждой функции) на наличие значения идентификатора.

Как это можно использовать, см. в разделе Bash: передача переменных по ссылке.

person pynexj    schedule 09.01.2018

Из описания bash справочной страницы встроенного local (выделено мной)

Когда local используется внутри функции, это приводит к тому, что имя переменной имеет видимую область действия, ограниченную этой функцией и ее дочерними элементами.

Когда вызывается g, значение x (не помеченное как local) используется из ближайшего включающего контекста runtime. Когда g вызывается из f, это означает локальную переменную x, определенную f, а не глобальную переменную x. Это относится как к поиску , так и к назначению x. Когда g вызывается из глобальной области видимости, x ссылается на глобальную переменную x.

Это контрастирует с лексической областью видимости, в которой x в функции g всегда будет ссылаться на глобальную x, потому что g определено в глобальной области видимости. Где вызывается функция из, значения не имеет.

person chepner    schedule 09.01.2018
comment
Извините за беспокойство. Надеюсь, можно спросить. :) Я сижу перед программой-оболочкой, которая почти не использует динамическую область видимости, в основном для передачи массивов между функциями. Переменные используются в различных функциях и комбинациях функций, и эти функции распределены по пяти исходным файлам. На мой взгляд, этот код менее удобочитаемый/следующий, а тот факт, что функции тесно связаны, делает его подверженным ошибкам и трудным в обслуживании. Вы бы сказали, что это обычная практика для шелл-кода, и я должен ожидать этого, или вы согласны? - person hek2mgl; 28.09.2018

g присваивает 2 локальному x функции f. Когда f заканчивается, его активационная запись извлекается из стека, затем второе эхо ищет в стеке и находит x = 1 начала.

person Alvaro Frias    schedule 09.06.2018