Переменная не обновляется при вызове функции - PullRequest
5 голосов
/ 01 июля 2011

У меня есть это в моем профиле сценария.

$AddablePaths = @{
    "python3"=";C:\Python32";
    "python2"=";C:\Python27";
    "D"=";C:\D\dmd2\windows\bin";
    "gcc"=";C:\MinGW\bin";
    "verge"=";C:\Users\Cold\Dev\Verge\tools";
    "ruby"=";C:\Ruby192\bin";
    "git"=";C:\Program Files\Git\cmd";
    "cmake"=";C:\Program Files\CMake 2.8\bin";
    "emacs"=";C:\Users\Cold\Dev\emacs\bin";
    "notepad++"=";C:\Program Files\Notepad++";
    "boost-build"=";C:\Users\Cold\Dev\C++\boost-build\bin";
    "svn"=";C:\Program FIles\SlikSvn\bin";
    "gtk2"=";C:\Program Files\GTK2-Runtime\bin";
    "qt"=";C:\Qt\bin";
    "komodo"=";C:\Program Files\ActiveState Komodo Edit 6\";
    "hg"=";C:\Program Files\TortoiseHg\"
}

$AddedPaths = @()

function AddPath($keys)
{
    if ($keys.Count -eq 0) { return }

    foreach ($key in $keys)
    {
        if ($AddablePaths.Contains($key))
        {
            if (!($AddedPaths -contains $key))
            {
                $env:Path += $AddablePaths[$key]
                $AddedPaths += $key
            }
        }
        else
        {
            Write-Host "Invalid path option. Options are:"
            foreach ($key in $AddablePaths.keys) {
                Write "    $key"
            }
        }
    }
}

Его цель - дать мне возможность легко добавлять на мой путь только то, что мне нужно. Например, я могу позвонить AddPath("ruby","git","notepad++"), чтобы добавить эти три вещи к моему пути. Я хочу, чтобы он не добавлял элементы, если я их уже добавил, поэтому я создал массив $AddedPaths, чтобы отслеживать, что уже было добавлено. Тем не менее, он не обновляется, когда я вызываю функцию, поэтому дубликаты все еще могут быть добавлены. Что я делаю не так?

Ответы [ 3 ]

6 голосов
/ 01 июля 2011

Вам нужно будет сделать это:

$Global:AddedPathes += $key

Это должно быть единственное место, которое вам нужно $Global:, так как оно его модифицирует.

1 голос
/ 01 июля 2011

Поскольку эта функция находится в вашем профиле, я думаю, что глобальная переменная области видимости, вероятно, является лучшим решением.Тем не менее, я просто хотел сообщить вам, что есть другой способ.

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

Вы должны создать массив $AddedPaths типа [ref], а затем передать его в качестве параметра вашемуфункция (теперь с переменной ссылочного типа):

function AddPath($keys, [ref]$ActivePaths)
{
    if ($keys.Count -eq 0) { return }

    foreach ($key in $keys)
    {
        if ($AddablePaths.Contains($key))
        {
            if (!($ActivePaths.Value -contains $key))
            {
                $env:Path += $AddablePaths[$key]
                $ActivePaths.Value += $key
            }
        }
        else
        {
            Write-Host "Invalid path option. Options are:"
            foreach ($key in $AddablePaths.keys) {
                Write "    $key"
            }
        }
    }
}

> [ref]$AddedPaths = @()
> AddPath -keys ("ruby","git","notepad++") -ActivePaths $AddedPaths

> $AddedPaths

Value
-----
{ruby, git, notepad++}

Для получения дополнительной справки по ссылочным переменным:

> help about_ref
1 голос
/ 01 июля 2011

Если вы сделаете его хеш-таблицей вместо массива, вам вообще не придется его охватывать, пока вы не будете повторно использовать то же имя переменной в последующих дочерних областях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...