Indirectly Invoking Methods Via Variablenames

Indirectly Invoking Methods Via Variablenames

  • Comments 3

PSMDTAG:FAQ: Can I specify a methodname using a variable? e.g. $x.$y()

PSMDTAG:FAQ: Why do I get METHOD metadata when I specify a method without providing parentheses?

One of the great things about Windows PowerShell is that it is a latebound language which allows you to do all sorts of incredibly powerful operations.  Consider the following code which defines a function to display the properties of an object.  The names of the properties come from a file passed into the function:

PS> function test ($obj, $file) {
>> foreach ($prop in cat $file) {"{0,-12} : {1}" -f $prop, $obj.$prop}
>> }
>>

PS> cat properties.txt
Name
ID

PS> test (get-process notepad) properties.txt
Name         : notepad
ID           : 456

PS> cat properties2.txt
Name
WS
NPM
Handles

PS> test (get-process notepad) properties2.txt
Name         : notepad
WS           : 7483392
NPM          : 4520
Handles      : 50

This works because you can specify $Obj.$Prop  where $prop contains the name of the property you want to see.

So how about Methods?  Lets see how that works:

PS> $s="This is a TEST"
PS> $method="ToUpper"
PS> $s.$method()
Unexpected token '(' in expression or statement.
At line:1 char:12
+ $s.$method() <<<<

It turns out the the parser does not handle this situation. 

But now try this:

PS> $s="This is a TEST"
PS> $s.ToUpper()
THIS IS A TEST
PS> $s.ToUpper

MemberType          : Method
OverloadDefinitions : {System.String ToUpper(), System.String ToUpper(Cultu
                      reInfo culture)}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : System.String ToUpper(), System.String ToUpper(Cultur
                      eInfo culture)
Name                : ToUpper
IsInstance          : True

What is happening is that if you specify a METHOD with parens, we call it.  If you specify a method without parens, we return the metadata for that method.  This can be a tad non-plussing at first but it turns out to be very useful at times.  In particular, it allows you to do this:

PS> $s="This is a TEST"
PS> $s.ToUpper.Invoke()
THIS IS A TEST
PS> foreach ($method in "ToUpper","ToLower","GetType") {$s.$method.Invoke()}

THIS IS A TEST
this is a test

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Enjoy!

 

Jeffrey Snover [MSFT]
Windows PowerShell/Aspen Architect
Visit the Windows PowerShell Team blog at:   
http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

PSMDTAG:INTERNAL: Indirectly invoking methods via variable Names

PSMDTAG:LANGUAGE: Parser does not accept directly support variable substitution for method names

Leave a Comment
  • Please add 5 and 4 and type the answer here:
  • Post
  • This is awesome, thanks Jeffrey.

    Typing methods without parenthesis returns metadata. How can we access those metadata for properties?

    What I am thinking of is a way to handle a list of members without knowing in advance whether they are properties or methods, and invoke them appropriately depending on their type. If in a script I have $obj.$member and $member is a property it will work, but if $member is a method it won't work and I will have to use $obj.$member.invoke() instead. I want to know the member type so I will use it with the appropriate syntax.

    Thanks,
    Jacques
  • I think this does what you want:
    PS> cat t1.ps1
    $s="STRing"
    foreach ($x in "toupper","length","tolower")
    {
       switch ((get-member -in $s $x).MemberType)
       {
       "method"   {$s.$x.Invoke()}
       "property" {$s.$x}
       }
    }
    PS> .\t1.ps1
    STRING
    6
    string

    Jeffrey Snover [MSFT]
    Windows PowerShell/Aspen Architect
    Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
    Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
  • What if the method or property name contains

Page 1 of 1 (3 items)