У програмирању, област видљивости (eng. scope ) је део програмског кода у коме је везивање имена (eng. name binding ) валидно, при чему се име може користити за упућивање на ентитет. Таква област назива се scope block . У осталим деловима кода име се може односити на други ентитет (може бити другачије везано) или може бити неповезано.
Област везивања је такође позната као видљивост ентитета, посебно у старијој литератури - из перспективе наведеног ентитета, а не референтног назива.
Oбласт видљивости променљиве је део програма који је или може бити област скупа везивања - тешко је прецизно дефинисати, али у пракси у великој мери одговара блоку, функцији или датотеци, зависно од програмског језика и типа ентитета. Израз "scope" користи се и за упућивање на скуп свих видљивих ентитета или имена која важе у делу програма или у одређеној датој тачки програма, што се прецизније назива context или окружење.
У пракси се за већину програмских језика „део програма“ упућује на „део изворног кода (подручје текста)“ и познат је као лексичка област видљивости (lexical scope). Међутим, у неким програмским језицима се „део програма“ односи на „део времена извођења (време извршавања кода)“ и познат је као динамичка област видљивости(dynamic scope).
У већини случајева name resolution заснована на лексичкој области видљивости релативно је једноставна за употребу и за примену, јер се током употребе може прочитати уназад у изворном коду да би се утврдило на који се ентитет једно име односи, а у имплементацији се може одржавати листа имена и контекста приликом компајлирања или интерпретације програма. Потешкоће настају при маскирању имена и хостовању, док знатно суптилније настају код нелокалних променљивих, посебно у затворењима.
Дефиниција Лексичка област видљивости имена (идентификатора) је „део изворног кода на који се односи везивање имена са ентитетом“ - и дефиниција је практично непромењена у односу на исту из 1960. године по спецификацији ALGOL 60. Следе спецификације језика ALGOL 60.
ALGOL 60 (1960)
Разликују се следеће врсте величина: једноставне променљиве, низови, ознаке, промене и процедуре. Област видљивости величине је скуп исказа и израза у којима је декларација идентификатора повезаног с том величином валидна.
C (2007)
Идентификатор може означавати објекат, функцију, члана структуре, везе или набрајања, typedef name, име ознаке, име макро-a или макро параметар. Исти идентификатор може означавати различите ентитете у различитим тачкама програма. За сваки различити ентитет који означи идентификатор, идентификатор је видљив (тј. може се користити) само у подручју текста програма који се зове његова област видљивости.
Go (2013)
Декларација везује non-blank идентификатор за константу, тип, променљиву, функцију или пакет. Област видљивости декларисаног идентификатора је опсег изворног текста у којем идентификатор означава наведену константу, тип, променљиву, функцију или пакет.
Најчешће се област видљивости односи на то када се одређено име може односити на дату променљиву - када декларација има ефекта - али може да се примењује и на друге ентитете, као што су функције, типови, класе, ознаке, константе и набрајања.
Лексички опсег насупрот динамичком опсегу
Основна разлика у опсегу обухвата значење „дела програма“. У језицима с лексичким опсегом (који се називају и статички опсег), резолуција имена зависи од локације у изворном коду и лексичког контекста, која је дефинисана местом дефинисане именоване променљиве или функције. Супротно томе, у језицима са динамичким опсегом резолуција имена зависи од стања програма у коме се појављује име које је одређено контекстом извршавања или контекстом позива. У пракси, са лексичким опсегом дефиниција променљиве решава се претрагом њеног блока који садржи или функцију, затим ако то не успе у претраживању спољног блока и слично, док се са динамичким опсегом тражи функција позива, тада функција која је позвала тај позив функцију, и тако даље, напредовање на низу позива. Наравно, у оба правила прво тражимо локалну дефиницију променљиве.
Већина савремених језика користи лексичко одређивање за променљиве и функције, мада се динамички опсег користи у неким језицима, нарочито у неким дијалектима Лисп-а, неким „скриптним“ језицима и неким језицима шаблона. Перл 5 нуди и лексички и динамички опсег. Чак и у лексички обухваћеним језицима, простор за затворење може бити збуњујући, јер они зависе од лексичког контекста где је затворење дефинисано, а не где се назива.
Лексичка резолуција се може одредити у току превођења, а позната је и као рано везивање, док се динамичка резолуција у целини може одредити само током извођења, па је стога позната и као касно везивање.
Сродни концепти У објектно оријентисаном програмирању динамичко обавештење одабира објектну методу за време извођења, иако се стварно везивање имена врши у време превођења или време извођења у зависности од језика. De facto динамички опсег је уобичајен у макро језицима, који не омогућавају директно разрешавање имена, већ се уместо тога проширују.
Неки програмски оквири попут AngularJS користе израз „домет“ да би значили нешто сасвим друго од начина на који се користи у овом чланку. У тим је оквирима само предмет програмског језика који користе (ЈаваСкрипт у случају АнгуларЈС) који се на одређени начин користи оквиром за опонашање динамичког опсега на језику који за своје променљиве користи лексички опсег. Ти опсези AngularJS могу сами бити у домету или изван његовог домета(користећи уобичајено значење термина) у било ком делу програма, следећи уобичајена правила променљивог опсега језика као и било који други објекат и користећи сопствено наслеђивање и правила о искључивању. У контексту AngularJS, понекад се користи термин „$опсег“ (са знаком долара) да се избегне забуна, али употреба знака долара у променљивим именима често обесхрабрујуће водиче за стил.
Употреба Опсег је важна компонента name resolution, која је за узврат основна за језичку семантику. Резолуција имена (укључујући опсег) варира између програмских језика и унутар програмског језика, овисно о врсти ентитета; правила за обим се називају правила о опсегу или правила за обим. Заједно са именима простора, правила за опсег су кључна за модуларно програмирање, тако да промена у једном делу програма не прекида неповезани део.
Преглед Када се говори о домету, постоје три основна концепта: обим, обим и контекст. Конкретно „опсег“ и „контекст“ често се мешају: обим је особина идентификатора и фиксан је, док је контекст особина програма, који се разликује зависно од положаја. Тачније, контекст је особина положаја у програму, било позиције у изворном коду (лексички контекст) или тачке током времена извођења (контекст извршења, контекст извођења или контекст позива). Контекст извршења састоји се од лексичког контекста (у тренутној извршној тачки) плус додатног стања извршења, као што је стог позива. Дакле, када се тачка извршења програма налази у опсегу имена променљиве, "променљива (име) је у контекст "(што значи" у контексту у овој тачки "), а када извршна тачка" напушта опсег променљиве (име) ", као што је повратак из функције," променљива (име) излази из контекста " . Уско речено, током извођења програм улази и излази из различитих опсега, а на месту извршења идентификатори су "у контексту" или "нису у контексту", дакле идентификатори "долазе у контекст" или "излазе из контекста" како програм улази или излази из опсега - међутим, у пракси је употреба много слабија. Опсег је концепт нивоа изворног кода и својство идентификатора, посебно променљивих или функција, функција - идентификатори у изворном коду су референце на ентитете у програму - и део је понашања преводиоца или преводиоца језика.
Као таква, питања опсега слична су показивачима, који су врста референце која се генерално користи у програмима. Употреба вредности променљиве када је име у контексту, али променљива је неиницијализована и аналогна је дереференцирању (приступу вредности) дивљег показивача, јер је недефинисана. Међутим, како се променљиве не уништавају све док не изађу из контекста, аналогни висећи показивач не постоји.
За ентитете као што су променљиве, опсег је подскуп животног века (познат и као обим) - име се може односити само на променљиву која постоји (вероватно са недефинисану вредност), али променљиве које постоје нису нужно видљиве: променљива може постојати, али бити неприступачна (вредност се чува, али се не односи у датом контексту) или је доступна, али не преко датог имена; у том случају је ван контекста (програм је "ван опсега имена"). У другим случајевима „животни век“ је ирелевантан - налепница (именована позиција у изворном коду) има век трајања идентичан програму (за статички компајлиране језике), али може бити у или изван контекста у одређеној тачки програма, и слично за статичке променљиве - статичка глобална променљива је у контексту за цео програм, док је статична локална променљива само у контексту неке функције или другог локалног контекста, али обе имају век трајања читавог програма.
Нивои опсега Опсег може варирати од само једног израза до читавог програма, са много могућих градација између. Најједноставније правило за оцењивање је глобални опсег - сви субјекти су видљиви током целог програма. Најосновније модуларно правило за опсег обухвата опсег на два нивоа, са глобалним опсегом било где у програму и локалним опсегом унутар функције. Софистицираније модуларно програмирање омогућава засебан домет модула, где су имена видљива унутар модула (приватна за модул), али нису видљива изван њега. У оквиру неке функције, неки језици, као што је C, дозвољавају опсег блока да ограничи опсег на подскуп функције; други, посебно функционални језици, омогућавају опсег израза да ограничи опсег на један израз. Остали обим обухвата опсег датотека (посебно на Ц) који се понаша слично као опсег модула и блокира опсег изван функција (посебно на Перлу).
Суптилно питање је то када се опсег започиње и када се заврши. У неким језицима, као што је Ц, опсег имена започиње његовом декларацијом, тако да различита имена декларисана у одређеном блоку могу имати различите домете. Ово захтева декларисање функција пре употребе, мада их не мора нужно и дефинисати, и захтева преношење декларације у неким случајевима, посебно за међусобну рекурзију. У осталим језицима, као што су JavaScript или Python опсег имена почиње на почетку релевантног блока (попут покретања функције), без обзира на то где је дефинисан, и сва имена унутар одређеног блока имају исти опсег; у JavaScript је то познато као дизање променљивих. Међутим, када се назив веже за неку вредност варира, а понашања у контекстним именима која имају недефинисану вредност се разликују.
Опсег израза Многи језици, нарочито функционални језици, нуде функцију која се зове let-expressions, која омогућава да опсег декларације буде самосталан израз. То је погодно ако је, на пример, потребна једна средња вредност за рачунање. На пример, у стандардном ML if f() returns 12, then let val x = f() in x * x end је израз који има вредност 144, користећи привремену променљиву x како би се избегло двоструко позивање f(). Неки језици са опсегом блока приближавају ову функцију нудећи синтаксу за уметање блока у израз; на пример, горе поменути стандардни МЛ израз може се написати у Перлу као do { my $x = f(); $x * $x },или у GNU C као ({ int x = f(); x * x; }).
У Python-u помоћне променљиве у изразима генератора имају опсег израза.
У C-u, имена променљивих у прототипу функције имају опсег израза, у овом контексту познат као опсег протокола функције.
Scope block