Powershell parameter namespace collision -
i'm powershell beginner, although not programming n00b. i'm trying create idisposable/raii-style failsafe pattern, sort of in:
http://www.sbrickey.com/tech/blog/post/idisposable_in_powershell
so have:
function global:failsafeguard { param ( [parameter(mandatory=$true)] [scriptblock] $execute, [parameter(mandatory=$true)] [scriptblock] $cleanup ) seek { &$execute } { &$cleanup } }
i'm trying utilize perform bunch of tasks in different directory, using push-location on way in , pop-location on way out. have:
function global:push-location-failsafe { param ( $location, [scriptblock] $execute ) failsafeguard { push-location $location; &$execute } { pop-location } }
i find $execute param in push-location-failsafe collides $execute param in failsafe function.
push-location-failsafe "c:\" {dir} look after '&' in pipeline element produced invalid object. must result in command name, script block or commandinfo object. @ c:\temp\b807445c-1738-49ff-8109-18db972ab9e4.ps1:line:20 char:10 + &$ <<<< execute
the reason think it's name-collision if rename $execute $execute2 in push-location-failsafe, works fine:
push-location-failsafe "c:\" {dir} directory: c:\ mode lastwritetime length name ---- ------------- ------ ---- d---- 2011-08-18 21:34 cygwin d---- 2011-08-17 01:46 dell [snip]
what's wrong in understanding of parameters?
your problem scriptblocks , how handle variables. variables within scriptblock doesn't expand until executed. because of hitting loop. allow me show you:
when phone call push-location-failsafe
method variable this:
[dbg]: ps c:\>> (get-variable execute).value dir
but phone call inner function failsafeguard
, $execute
variable changes this:
[dbg]: ps c:\>> (get-variable execute).value push-location $location; & $execute
now when you're try { }
block starts executing, begins expand variables. when expands $execute
this:
try { push-location $location; & $execute }
then expands $execute
again. seek block now:
try { push-location $location; & { push-location $location; & $execute } }
and got infinite loop caused recursion. prepare this, can expand $execute
variable within string, create scriptblock out of. this:
function global:push-location-failsafe { param ( $location, [scriptblock] $execute ) failsafeguard ([scriptblock]::create(" push-location $location; & $execute")) { pop-location } }
be aware particular solution have problem when $execute
includes variables inside. e.g.: $execute = { $h = dir }
because seek expand $h when creates scriptblock.
an easier , improve way solve utilize different variablenames there's no collision in first place :-)
powershell
No comments:
Post a Comment