{"id":3873,"date":"2013-04-05T11:59:00","date_gmt":"2013-04-05T11:59:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/04\/05\/closures-in-powershell\/"},"modified":"2013-04-05T11:59:00","modified_gmt":"2013-04-05T11:59:00","slug":"closures-in-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/closures-in-powershell\/","title":{"rendered":"Closures in PowerShell"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary<\/strong><span style=\"font-size: 12px\">: Bruce Payette talks about Windows PowerShell closures and how to call the <strong>G<\/strong><\/span><strong>etNewClosure<\/strong><span style=\"font-size: 12px\"> method.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. This week we will not have our usual <strong>PowerTip<\/strong>. Instead we have excerpts from seven books from Manning Press. In addition, each blog will have a special code for 50% off the book being excerpted that day. Remember that the code is valid only for the day the excerpt is posted. The coupon code is also valid for a second book from the Manning collection.<\/p>\n<p class=\"Body\" align=\"left\">This excerpt is from <a href=\"http:\/\/www.manning.com\/payette2\/\" target=\"_blank\">Windows PowerShell in Action<\/a><br \/>&nbsp; By <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/bruce+payette\/\" target=\"_blank\">Bruce Payette<\/a><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2086.hsg-4-5-13-1.png\"><img decoding=\"async\" style=\"border: 0px currentColor\" title=\"Photo of book cover\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2086.hsg-4-5-13-1.png\" alt=\"Photo of book cover\" \/><\/a><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">Windows PowerShell uses dynamic modules to create dynamic closures. A closure in computer science terms (at least as defined in Wikipedia) is &ldquo;a function that is evaluated in an environment containing one or more bound variables.&rdquo; A bound variable is, for our purposes, a variable that exists and has a value. The environment in our case is the dynamic module. Finally, the function is simply a script block. In effect, a closure is the inverse of an object. An object is data with methods (functions) attached to that data. A closure is a function with data attached to that method.<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">The best way to understand what all this means is to look at an example. You&rsquo;ll use closures to create a set of counter functions. The advantage closures give you over plain functions is that you can change what increment to use after the counter function has been defined. Here&rsquo;s the basic function:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">function New-Counter ($increment=1)<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">{<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">&nbsp;&nbsp;&nbsp; $count=0;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">&nbsp;&nbsp;&nbsp; {<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $script:count += $increment<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $count<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">&nbsp;&nbsp;&nbsp; }.GetNewClosure()<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">}<\/span><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">There&rsquo;s nothing you haven&rsquo;t seen so far&mdash;you create a variable and then a script block that increments that variable&mdash;except for returning the result of the call to the <strong style=\"font-size: 12px\">Get-NewClosure()<\/strong> method. Let&rsquo;s try this function to see what it does. First, create a counter:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (1) &gt; $c1 = New-Counter<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (2) &gt; $c1.GetType().FullName<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">System.Management.Automation.ScriptBlock&nbsp;<\/span><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">Looking at the type of the object returned, you see that it&rsquo;s a script block, so you use the <strong>&amp;<\/strong> operator to invoke it:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (3) &gt; &amp; $c1<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">1<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (4) &gt; &amp; $c1<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">2<\/span><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">The script block works as you&rsquo;d expect a counter to work. Each invocation returns the next number in the sequence. Now, create a second counter, but this time set the increment to <strong style=\"font-size: 12px\">2<\/strong>:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (5) &gt; $c2 = New-Counter 2<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">Invoke the second counter scriptblock:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (6) &gt; &amp; $c2<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">2<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (7) &gt; &amp; $c2<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">4<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (8) &gt; &amp; $c2<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">6<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">It counts up by 2. But what about the first counter?&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (9) &gt; &amp; $c1<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">3<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (10) &gt; &amp; $c1<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">4<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">The first counter continues to increment by 1, unaffected by the second counter. So the key thing to notice is that each counter instance has its own copies of the <strong style=\"font-size: 12px\">$count<\/strong> and <strong style=\"font-size: 12px\">$increment<\/strong> variables. When a new closure is created, a new dynamic module is created, and then all the variables in the caller&rsquo;s scope are copied into this new module.<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">Here are more examples of working with closures to give you an idea of how flexible the mechanism is. First, you&rsquo;ll create a new closure by using a <strong>param<\/strong> block to set the bound variable <strong>$x<\/strong>. This is essentially the same as the previous example, except that you&rsquo;re using a script block to establish the environment for the closure instead of a named function:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (11) &gt; $c = &amp; {param ($x) {$x+$x}.GetNewClosure()} 3.1415<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">Now evaluate the newly created closed script block:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (12) &gt; &amp; $c<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">6.283<\/span><\/p>\n<p><span style=\"font-size: small\">This evaluation returns the value of the parameter added to itself. Because closures are implemented by using dynamic modules, you can use mechanisms to manipulate the state of a closure. You can do this by accessing the module object attached to the script block. You&rsquo;ll use this object to reset the module variable <strong style=\"font-size: 12px\">$x<\/strong> by evaluating <strong style=\"font-size: 12px\">Set-Variable<\/strong> (<strong style=\"font-size: 12px\">sv<\/strong>) in the closure&rsquo;s module context:<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (13) &gt; &amp; $c.Module Set-Variable x &#8220;Abc&#8221;<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">Now evaluate the script block to verify that it&rsquo;s been changed:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (14) &gt; &amp; $c<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">AbcAbc<\/span><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">Next, create another script block closed over the same module as the first one. You can do this by using the <strong>NewBoundScriptBlock()<\/strong> method on the module to create a new script block that is attached to the module associated with the original script block:<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (15) &gt; $c2 = $c.Module.NewBoundScriptBlock({&#8220;x ia $x&#8221;})<\/span><\/p>\n<p><span style=\"font-size: small\">Execute the new script block to verify that it&rsquo;s using the same <strong style=\"font-size: 12px\">$x<\/strong>:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (16) &gt; &amp; $c2<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">x ia Abc<\/span><\/p>\n<p><span style=\"font-size: small\">Now use <strong style=\"font-size: 12px\">$c2.module<\/strong> to update the shared variable:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (17) &gt; &amp; $c2.module sv x 123<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (18) &gt; &amp; $c2<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">x ia 123<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">And verify that it&rsquo;s also changed for the original closed script block:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (19) &gt; &amp; $c<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">246<\/span><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">Finally, create a named function from the script block by using the function provider:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (20) &gt; $function:myfunc = $c<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">And verify that calling the function by name works:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (21) &gt; myfunc<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">246&nbsp;<\/span><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">Set the closed variable yet again, but use <strong>$c2<\/strong> to access the module this time:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (22) &gt; &amp; $c2.Module sv x 3<\/span><\/p>\n<p class=\"Body1\" align=\"left\"><span style=\"font-size: small\">Verify that it&rsquo;s changed when you call the named function:&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">PS (23) &gt; myfunc<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><span style=\"font-size: small\">6<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">These examples should give you an idea about how all of these pieces&mdash;script blocks, modules, closures, and functions&mdash;are related. This is how modules work. When a module is loaded, the exported functions are closures bound to the module object that was created. These closures are assigned to the names for the functions to import. A fairly small set of types and concepts allow you to achieve advanced programming scenarios.<\/span><\/p>\n<p class=\"Body\" align=\"left\"><span style=\"font-size: small\">~Bruce<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-size: small\"><strong>Here is the code for the discount offer today at <\/strong><a href=\"http:\/\/www.manning.com\/\" target=\"_blank\">www.manning.com<\/a>: <strong>scriptw5<\/strong><\/span><br \/><span style=\"font-size: small\"> Valid for 50% off <a href=\"http:\/\/www.manning.com\/payette2\/\" target=\"_blank\">PowerShell in Action<\/a> and <a href=\"http:\/\/www.manning.com\/wilen\/\" target=\"_blank\">SharePoint Web Parts in Action<\/a><\/span><br \/><span style=\"font-size: small\"> Offer valid from April 5, 2013 12:01 AM until April 6, midnight (EST)<\/span><\/p>\n<p><span style=\"font-size: small\">I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/span><\/p>\n<p><span style=\"font-size: small\"><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Bruce Payette talks about Windows PowerShell closures and how to call the GetNewClosure method. Microsoft Scripting Guy, Ed Wilson, is here. This week we will not have our usual PowerTip. Instead we have excerpts from seven books from Manning Press. In addition, each blog will have a special code for 50% off the book [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[266,56,52,3,4,45],"class_list":["post-3873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-bruce-payette","tag-guest-blogger","tag-modules","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Bruce Payette talks about Windows PowerShell closures and how to call the GetNewClosure method. Microsoft Scripting Guy, Ed Wilson, is here. This week we will not have our usual PowerTip. Instead we have excerpts from seven books from Manning Press. In addition, each blog will have a special code for 50% off the book [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=3873"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3873\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=3873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}