Skip to content

Instantly share code, notes, and snippets.

@nohwnd
Created January 7, 2019 11:21
Show Gist options
  • Save nohwnd/2b74daccdb8114c926bf6df4f73b3b74 to your computer and use it in GitHub Desktop.
Save nohwnd/2b74daccdb8114c926bf6df4f73b3b74 to your computer and use it in GitHub Desktop.
Transparent wrapper using data object
# getting a piece of code from a user that we want to wrap,
# and execute, we often need to pass in additional parameters
# at least the script itself, and this poses a problem because
# the parameter name will conflict with the user script.
# (we want to add a wrapper for example to run two pieces of code
# in the same scope, without leaking variables into a parent scope)
# here for simplicity all the scriptblocks are running in the
# same session state, and we chose variable $A to pass the user
# provided scriptblock into our wrapper. This $A variable conflicts with
# a variable that the user defined and so it would be best if our wrapper
# used no variables and was completely transparent
Add-Type -TypeDefinition "
using System.Collections.Generic;
public class Container {
static Container () {
_data = new Dictionary<string,object>();
}
private static Dictionary<string,object> _data;
public static Dictionary<string,object> Data { get { return _data; } }
}"
# opaque wrapper, the result the content of $userCode -> '$A' instead of
# the correct value "abc" because we chose a conflicting variable name
$A = "abc"
$userCode = { $A }
& {
param ($A)
&$A
} $userCode
# transparent wrapper, the offending variable is removed and it's contents
# are stored in and retrieved from a container object
[Container]::Data.Clear()
& {
param ($A)
[Container]::Data.Add("A", $A)
Remove-Variable -Scope Local -Name A
&([Container]::Data.A)
} $userCode
@nohwnd
Copy link
Author

nohwnd commented Oct 3, 2019

I forgot about the private: scope of parameters. So this can all be avoided by doing this:

$A = "abc"
$userCode = { $A }

& { 
    param ($private:A) # <---
    & $A
    
} $userCode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment