{"id":191,"date":"2013-03-17T11:01:07","date_gmt":"2013-03-17T18:01:07","guid":{"rendered":"http:\/\/www.jsnover.com\/blog\/?p=191"},"modified":"2013-09-22T17:58:46","modified_gmt":"2013-09-23T00:58:46","slug":"variable-scopes-and-private","status":"publish","type":"post","link":"https:\/\/www.jsnover.com\/blog\/2013\/03\/17\/variable-scopes-and-private\/","title":{"rendered":"Variable Scopes and $PRIVATE:"},"content":{"rendered":"<p>In my previous post <a href=\"https:\/\/www.jsnover.com\/blog\/2013\/03\/16\/evolution-of-a-script-timing-operations\/\" target=\"_blank\">Evolution of a Script, Timing Operations<\/a>, I used\u00a0the technique of putting &#8220;__&#8221; in front of variable names to avoid namespace collision.\u00a0 Niklas Bergius left a comment saying, &#8220;Instead of using __ prefixes, wouldn\u2019t $private: work?&#8221;\u00a0\u00a0 Great question &#8211; let&#8217;s explore.<!--more--><\/p>\n<p>The first thing I want everyone to get in focus is that there are lots of ways to accomplish something in PowerShell.\u00a0 That means that you shouldn&#8217;t freak out of you see someone using a technique you don&#8217;t use.\u00a0 The culture of PowerShell is one of exploration and fun.\u00a0 When you see something new, go explore and find out it&#8217;s strengths and weaknesses for yourself.\u00a0 I&#8217;ve always believed that the best way to learn a system is to use it &#8211; explore and have some fun.\u00a0 While PowerShell is a power tool for admins, we put in a number of features that make it easy (and often safe) to explore (e.g. -Whatif).<\/p>\n<p>So let&#8217;s explore $PRIVATE:.<\/p>\n<p>What is the first thing we do when exploring something? We type HELP.\u00a0 In this case, we say HELP PRIVATE (I didn&#8217;t provide the &#8216;$&#8217; otherwise it would try to evaluate it as a variable).\u00a0 This provides a list of potential help subjects including <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/hh847849.aspx\" target=\"_blank\">ABOUT_SCOPES<\/a>.\u00a0 $PRIVATE: is a variable SCOPE &#8211; you can tell that by the &#8220;:&#8221;.<\/p>\n<p>So now we want to read the help and explore what it tells us.\u00a0 The way I like to do this is to use ISE and pipe the help to the clipboard (help About_scopes | clip ) and then paste it into a new editor windows (CTRL-N and then CTRL-V).\u00a0 Now I can read the help and have the interactive shell to explore.\u00a0 You should spend some time here &#8211; there is a LOT to learn about Scopes.\u00a0 PowerShell&#8217;s implementation of variables is very rich and different from other languages.<\/p>\n<p>Side note: PowerShell separates syntax from implementation.\u00a0 Variables are just places you store and retrieve data.\u00a0 Traditionally this is a piece of volatile RAM but in PowerShell it can be anywhere.\u00a0 For example:\u00a0 ${C:\\Temp\\Test.txt} = &#8220;This is a test&#8221;\u00a0 stores the string into a file using variable syntax.\u00a0 This is a trick I learned implementing<a href=\"http:\/\/en.wikipedia.org\/wiki\/GT.M\" target=\"_blank\"> GT.M MUMPS <\/a>systems (which were a combined language\/database system) in the 1980s.<\/p>\n<p>The help explains the concept of a scope (a\u00a0mechanism which\u00a0determines how a element [variable, alias, drive, function, etc.] will be made available [or not] to other\u00a0elements of the program)\u00a0and\u00a0explains the different types of scopes: Global, Local, Script, Private, and Numbered.\u00a0 The explanation of Private scopes says:<\/p>\n<p><em>Items in private scope cannot be seen outside of the current scope. You can use private scope to create a private version of an item with the same name in another scope.<\/em><\/p>\n<p>So let&#8217;s start exploring:<br \/>\nLet&#8217;s start with the following as a baseline to remind everyone how PowerShell variables work and the power of dynamic scoping:<br \/>\n<!-- Stylesheet link --><\/p>\n<div class=\"dp-highlighter\" id=\"hlDiv\">\n<div class=\"bar\"><\/div>\n<ol class=\"dp-rb\">\n<li class=\"alt\"><span><span class=\"comment\">#start\u00a0with\u00a0a\u00a0clean\u00a0slate<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span><span class=\"builtin\">Remove-Variable<\/span><span>\u00a0-Name\u00a0x\u00a0\u00a0\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span><span class=\"variable\">$x<\/span><span>\u00a0=\u00a0<\/span><span class=\"string\">&#8220;1&#8221;<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span><span class=\"string\">&#8220;x\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$x<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span><span class=\"keyword\">function<\/span><span>\u00a0test\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>{\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>\u00a0\u00a0\u00a0\u00a0<span class=\"string\">&#8220;In\u00a0test,\u00a0x\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$x<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>}\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>test\u00a0\u00a0<\/span><\/li>\n<\/ol>\n<\/div>\n<p>Running it produces the following output:<br \/>\nx = 1<br \/>\nIn test, x = 1<\/p>\n<p>What that means is that when we tried to access the variable X in the function test, it was not available so PowerShell looked into the parent&#8217;s scope, found the variable there and used it. Now let&#8217;s put $X into a PRIVATE scope and see how things change.<br \/>\n<!-- Stylesheet link --> \t<link href=\"http:\/\/www.thecomplex.plus.com\/styles\/SyntaxHighlighter.css\" rel=\"stylesheet\" type=\"text\/css\" \/><!-- Code --><\/p>\n<div class=\"dp-highlighter\" id=\"hlDiv\">\n<div class=\"bar\"><\/div>\n<ol class=\"dp-rb\">\n<li class=\"alt\"><span><span class=\"comment\">#start\u00a0with\u00a0a\u00a0clean\u00a0slate<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span><span class=\"builtin\">Remove-Variable<\/span><span>\u00a0-Name\u00a0x\u00a0\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span><span class=\"variable\">$private<\/span><span class=\"symbol\">\ud83d\ude21<\/span><span>\u00a0=\u00a0<\/span><span class=\"string\">&#8220;1&#8221;<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span><span class=\"string\">&#8220;x\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$x<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span><span class=\"keyword\">function<\/span><span>\u00a0test\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>{\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>\u00a0\u00a0\u00a0\u00a0<span class=\"string\">&#8220;In\u00a0test,\u00a0x\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$x<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>}\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>test\u00a0\u00a0<\/span><\/li>\n<\/ol>\n<\/div>\n<p>(Apologizes if that code shows an emoticon &#8211; I&#8217;m using a Syntax Highlighter which doesn&#8217;t work properly &#8211; any recommendations?)<\/p>\n<p>This produces the following result:<br \/>\nx = 1<br \/>\nIn test, x =<\/p>\n<p>So what that tells us is that by using $Private, the variable is hidden from other parts of\u00a0the program.\u00a0\u00a0Niklas&#8217;\u00a0comment showed a clear understanding of scope and variable handling because\u00a0if PowerShell doesn&#8217;t find the variable in the parent,\u00a0it\u00a0continues up the stack looking for the variable until it finds it or fails.\u00a0\u00a0The problem I had\u00a0with my script was that I wanted to use a variable name in one routine and have child routines be able to use that variable but bind it to\u00a0it&#8217;s grandparents value.\u00a0 Let&#8217;s go through that slowly.<\/p>\n<p>I was trying to write a function Measure-Time which took a variable which\u00a0I wanted to call\u00a0$ScriptBlock which I would then execute by calling &amp;$ScriptBlock.\u00a0 That\u00a0worked fine EXCEPT when the\u00a0ScriptBlock\u00a0refers to\u00a0a variable named $ScriptBlock (and why wouldn&#8217;t it &#8211; If I find it useful, others will as well).\u00a0 The problem is that that\u00a0then\u00a0evaluates to itself and bad things ensue.\u00a0 So what we want to do is to somehow use the variablename\u00a0ScriptBlock in a way that when ONLY my routine sees it.\u00a0 When\u00a0my routine calls a function that walks up the stack looking for a variable\u00a0called ScriptBlock &#8211; I want it to pass right over me and look for it in my parent\/grandparent\/etc.\u00a0\u00a0That is\u00a0exactly what $PRIVATE: does.<\/p>\n<p>If none of that makes any sense &#8211; don&#8217;t worry &#8211; lets explore\u00a0a few things and I think you&#8217;ll get it via experimentation.\u00a0 So here is the experiment (I&#8217;m going to switch variable names from X to ScriptBlock so it matches the text above):<\/p>\n<div class=\"dp-highlighter\" id=\"hlDiv\">\n<div class=\"bar\"><\/div>\n<ol class=\"dp-rb\">\n<li class=\"alt\"><span><span class=\"comment\">#start\u00a0with\u00a0a\u00a0clean\u00a0slate<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span><span class=\"builtin\">Remove-Variable<\/span><span>\u00a0-Name\u00a0ScriptBlock\u00a0-ErrorAction\u00a0Ignore\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span><span class=\"variable\">$ScriptBlock<\/span><span>\u00a0=\u00a0<\/span><span class=\"string\">&#8220;top&#8221;<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span><span class=\"string\">&#8220;ScriptBlock\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$ScriptBlock<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span><span class=\"keyword\">function<\/span><span>\u00a0child\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>{\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>\u00a0\u00a0\u00a0\u00a0<span class=\"string\">&#8220;In\u00a0child,\u00a0\u00a0ScriptBlock\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$ScriptBlock<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>}\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span><span class=\"keyword\">function<\/span><span>\u00a0middle\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>{\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>\u00a0\u00a0\u00a0\u00a0<span class=\"variable\">$ScriptBlock<\/span><span>\u00a0=\u00a0<\/span><span class=\"string\">&#8220;middle&#8221;<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>\u00a0\u00a0\u00a0\u00a0<span class=\"string\">&#8220;In\u00a0middle,\u00a0ScriptBlock\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$ScriptBlock<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span>\u00a0\u00a0\u00a0\u00a0child\u00a0\u00a0<\/span><\/li>\n<li><span>}\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>middle\u00a0\u00a0\u00a0<\/span><\/li>\n<\/ol>\n<\/div>\n<p>You run that and get:<\/p>\n<p>ScriptBlock = top<br \/>\nIn middle, ScriptBlock = middle<br \/>\nIn child,\u00a0\u00a0 \u00a0ScriptBlock = middle<\/p>\n<p>When CHILD runs, it tries to access $ScriptBlock and can&#8217;t find it so it goes to the parent MIDDLE, finds it and uses it.\u00a0 Now let&#8217;s modify the MIDDLE routine and declare the ScriptBlock variable to be PRIVATE.\u00a0 What we are trying to do is to hide it from everyone else so that when CHILD looks for it, it skips MIDDLE and finds it at the top scope.\u00a0 We only change 1 line in MIDDLE:<\/p>\n<div class=\"dp-highlighter\" id=\"hlDiv\">\n<div class=\"bar\"><\/div>\n<ol class=\"dp-rb\">\n<li class=\"alt\"><span><span class=\"keyword\">function<\/span><span>\u00a0middle\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>{\u00a0\u00a0<\/span><\/li>\n<li class=\"alt\"><span>\u00a0\u00a0\u00a0\u00a0<span class=\"variable\">$Private<\/span><span>:ScriptBlock\u00a0=\u00a0<\/span><span class=\"string\">&#8220;middle&#8221;<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li><span>\u00a0\u00a0\u00a0\u00a0<span class=\"string\">&#8220;In\u00a0middle,\u00a0ScriptBlock\u00a0=\u00a0&#8220;<\/span><span>\u00a0+\u00a0<\/span><span class=\"variable\">$ScriptBlock<\/span><span>\u00a0\u00a0<\/span><\/span><\/li>\n<li class=\"alt\"><span>\u00a0\u00a0\u00a0\u00a0child\u00a0\u00a0<\/span><\/li>\n<li><span>}\u00a0\u00a0<\/span><\/li>\n<\/ol>\n<\/div>\n<p>You run that and now get:<\/p>\n<p>ScriptBlock = top<br \/>\nIn middle, ScriptBlock = middle<br \/>\nIn child,\u00a0\u00a0 \u00a0ScriptBlock = top<\/p>\n<p>Success!<\/p>\n<p>So there are 3 things I want\u00a0you to get out of this blog:<\/p>\n<ol>\n<li>PowerShell has rich semantics so explore SCOPES to understand them.<\/li>\n<li>There are usually multiple ways to solve a problem in PowerShell each with a different set of pros and cons.<\/li>\n<li>Explore and Share.\u00a0 I shared my work and Niklas reminded me of a better way to solve the problem.\u00a0 If I didn&#8217;t share, I wouldn&#8217;t have benefitted from his insight.\u00a0 Sometimes beginners are embarrassed to share their work because they are afraid of\u00a0looking like a beginner\u00a0&#8211; DON&#8217;T LET THIS BE YOU.\u00a0 \u00a0The PowerShell community has a TON of super smart people that are both very helpful and very kind.\u00a0\u00a0Share your work and if there is a better way of doing things, they&#8217;ll let you know that without being a jerk about it.\u00a0 (I hope that is true and someone recommends a new PowerShell syntax highlighter for HTML \ud83d\ude42<\/li>\n<li>Things don&#8217;t have to be perfect &#8211; they have to be useful.\u00a0 (joke intended but it is a serious point)\u00a0 I could have gone back and done a bunch of work to clean up my examples to get rid of the emoticon but you can cut-n-paste the example and it is going to work fine and if I cleaned it up &#8211; I would never get a recommendation for a better syntax highlighter.<\/li>\n<\/ol>\n<p>Explore, explore, explore!<br \/>\nCheers!<br \/>\nJeffrey<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous post Evolution of a Script, Timing Operations, I used\u00a0the technique of putting &#8220;__&#8221; in front of variable names to avoid namespace collision.\u00a0 Niklas Bergius left a comment saying, &#8220;Instead of using __ prefixes, wouldn\u2019t $private: work?&#8221;\u00a0\u00a0 Great &hellip; <a href=\"https:\/\/www.jsnover.com\/blog\/2013\/03\/17\/variable-scopes-and-private\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-191","post","type-post","status-publish","format-standard","hentry","category-powershell"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/posts\/191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/comments?post=191"}],"version-history":[{"count":9,"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/posts\/191\/revisions"}],"predecessor-version":[{"id":225,"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/posts\/191\/revisions\/225"}],"wp:attachment":[{"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/media?parent=191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/categories?post=191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jsnover.com\/blog\/wp-json\/wp\/v2\/tags?post=191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}