Полезный ответ Scepticalist предоставляет эффективное решение для активации вашей prompt
функции во время импорта .
Подход в вашем вопросе для активации функции по требованию , путем последующего точечного поиска функции, в которой функция prompt
является вложенной , принципиально не может работать как написано , если эта функция импортирована из модуля , как объяснено далее; решение см. В нижнем разделе .
Что касается того, что вы пытались :
. prompt
Это не точечный источник определения функции prompt
, он выполняет функцию в области поиска.
- In эффект, он (бессмысленно) печатает (один раз, как вывод), какой должна быть строка приглашения, и заставляет локальные переменные функции оставаться в области действия вызывающего.
Следовательно, вложенность определение функции prompt
внутри функции PromptShortenPath
, точечный источник , который определяет функцию prompt
в области действия вызывающего абонента автоматически вместе с функцией shorten-path
[1]
Если ваша функция PromptShortenPath
определена вне модуля , точечный источник означает, что источник scope - это (немодульная) текущая область вызова вызывающего абонента , которая определяет вложенные функции там и с появлением нового prompt
f. Кроме того, строка интерактивного приглашения изменяется, как и предполагалось.
В отличие от этого, если ваша PromptShortenPath
функция определена внутри модуля , точечный источник означает, что область поиска - это модуль происхождения , что означает, что текущая область действия *1074* вызывающего абонента не затронута и никогда не видит вложенные функции shorten-path
и prompt
- таким образом, строка интерактивного приглашения не изменяется.
- Повторяется: точечный источник функция (в отличие от сценария ) запускает функцию в текущей области действия области происхождения , а не текущей области вызова вызывающей стороны ; то есть точечная выборка функции из модуля неизменно запускает ее в текущей области этого модуля, которая отличается от области действия *1095* вызывающей стороны и не связана с ней (если только вызывающая сторона не является область верхнего уровня внутри того же модуля).
Напротив, решение Scepticalist, сделав функции shorten-path
и prompt
верхнего уровня функции модуля неявно (экспортирует и) импортируют их как в область вызова с помощью Import-Module
, и, опять же, появление новой функции prompt
в области вызова изменяет строку интерактивного приглашения, хотя в время импорта .
Альтернативный подход, который также работает с модулями:
Самое простое решение - определить вложенную функцию со спецификатором области действия global:
, который непосредственно определяет это в глобальной области видимости, независимо от того, какая область содержит определение.
В качестве полезного побочного эффекта вам больше не нужно ставить точечный источник функция быстрого вызова при вызове.
Обратите внимание, что решение ниже включает вспомогательную функцию shorten-path
в функцию global:prompt
, чтобы обеспечить ее доступность для последней; альтернативой может быть также определение shorten-path
как global:shorten-path
, но нет необходимости загромождать глобальную область действия вспомогательными функциями, особенно если учесть, что могут возникнуть конфликты имен.
# Use a dynamic module to simulate importing the `Set-Prompt` function
# from a (regular, persisted) module.
$null = New-Module {
function Set-Prompt {
# Note the `global:` prefix.
Function global:prompt {
# Note the *embedded* definition of helper function shorten-path,
# which makes it available to the enclosing function only and avoids
# the need to make the helper function global too.
Function shorten-path([string] $path) {
$loc = $path.Replace($HOME, '~')
# remove prefix for UNC paths
$loc = $loc -replace '^[^:]+::', ''
# make path shorter like tabs in Vim,
# handle paths starting with \\ and . correctly
return ($loc -replace '\\(\.?)([^\\])[^\\]*(?=\\)', '\$1$2')
}
# our theme
$cdelim = [ConsoleColor]::DarkCyan
$chost = [ConsoleColor]::Green
$cloc = [ConsoleColor]::Cyan
Write-Host "$([char]0x0A7) " -n -f $cloc
Write-Host ([net.dns]::GetHostName()) -n -f $chost
Write-Host ' {' -n -f $cdelim
Write-Host (shorten-path (pwd).Path) -n -f $cloc
Write-Host '}' -n -f $cdelim
return ' '
}
}
}
# Now that Set-Prompt is imported, invoke it as you would
# any function, and the embedded `prompt` function will take effect.
Set-Prompt
[1] Обратите внимание, что, хотя shorten-path
в принципе следует соглашению об именах существительных глаголов PowerShell, shorten
отсутствует в списке утвержденных глаголов .