Created
January 7, 2019 11:21
-
-
Save nohwnd/2b74daccdb8114c926bf6df4f73b3b74 to your computer and use it in GitHub Desktop.
Transparent wrapper using data object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I forgot about the
private:
scope of parameters. So this can all be avoided by doing this: