Можно ли создать мою собственную «автоматическую переменную»? - PullRequest
6 голосов
/ 17 ноября 2010

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

$myvar = `write-host foo`;

Тогда каждый раз, когда я ссылаюсь на $ myvar, будет выводиться foo:

dir $myvar

Directory of foo:

Дело в том, что часть write-host foo будет выполняться заново каждый раз, когда я ссылаюсь на $ myvar

Ответы [ 3 ]

5 голосов
/ 17 ноября 2010

Это возможно в управляемом коде (C # / VB), создав собственный производный класс PSVariable, но не напрямую в чистом скрипте, извините.Я говорю «чистый скрипт», потому что в powershell v2 вы можете встроить C # с помощью add-type.Тем не менее, вы можете взломать его в сценарии, полагаясь на неявные вызовы ToString, но это не будет надежным в каждой ситуации.Пример:

# empty custom object
$o = new-object psobject

# override ToString with a PSScriptMethod member
$o.psobject.members.add((new-object `
     System.Management.Automation.PSScriptMethod "ToString", {
         "ticks: $([datetime]::now.ticks)" }))

ps> $o
ticks: 634256043148813794

ps> $o
ticks: 634256043165574752

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

function Ticks { [datetime]::now.ticks }

# use as a parameter - note the use of ( and )
ps> write-host (ticks)
634256043148813794

# use in a string - note the use of $( and )
ps> write-host "ticks $(ticks)"
ticks 634256043165574752

Надеюсь, это поможет

-Oisin

2 голосов
/ 19 ноября 2010

Не так сложно завершить то, что упоминает @ x0n. Мы можем встроить часть C # в наш код и получить настоящую автоматическую переменную:

# define a class of my variable, override the Value property
Add-Type @'
using System;
using System.Management.Automation;
public class MyVariable : PSVariable
{
    public MyVariable(string name) : base(name) {}
    public override object Value
    {
        get { return DateTime.Now.Ticks; }
        set { }
    }
}
'@

# install the variable
$ExecutionContext.SessionState.PSVariable.Set((New-Object MyVariable Ticks))

# test
$Ticks
sleep 1
$Ticks
sleep 1
$Ticks

О PSVariable:

http://msdn.microsoft.com/en-us/library/system.management.automation.psvariable

2 голосов
/ 19 ноября 2010

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

$MySecretOldPromptStorage = ${Function:Prompt}
function prompt { $o = $([datetime]::now.ticks); &$MySecretOldPromptStorage }

Ofконечно, это приводит к тому, что он запускается каждый раз вместо запроса по требованию

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