Powershell objects: referencing Self
Asked Answered
V

1

6

I can create an object with four properties like this

$pocketKnife = New-Object PSObject -property @{
    Color = 'Black'
    Weight = '55'
    Manufacturer = 'Buck'
    Blades = '1'
}

And is works basically as expected. However, I can't seem to grok how to add a method that references the object's own properties. I can add this

$pocketKnife | Add-Member ScriptMethod GetColor {
    Write-Host "Color = $($pocketKnife.Color)" 
}

and I can then call $pocketKnife.GetColor() and it works as expected. But I have to hard wire the object reference into the method, and I am actually referencing the object variable defined outside the object itself. What I want to do is

$pocketKnife | Add-Member ScriptMethod GetColor {
    Write-Host "Color = $($Self.Color)" 
}

Ultimately I want to create a Logger object, that will initialize itself and establish an appropriate log file name in a property, and has a Log method that takes a string argument, and when called it logs to the log file in the property. And I get the sense that maybe this is more than PowerShell is really intended to do with regards to being object oriented. Like I should really be limiting my concept of (custom) objects to Structures for data, not classes and instances? FWIW, I am new enough to OOP that I don't know what I don't know. What I do know is that right now I am using a global variable for the log file path, and init and log functions that reference it, and I am looking for the best way to eliminate the global variable, and also use PS to it's potential, and learn some programming concepts while I am at it. And all my Google Fu ends up with more info about object properties and nothing about methods beyond simple examples that echo some text to prove you're in the method. So, any advice is greatly appreciated, even if it is just "Ain't nothin' up that tree"

Thanks!

Veneaux answered 14/2, 2015 at 14:30 Comment(0)
M
12

PowerShell and C# are very similar. C# uses this to the reference the current instance/itself, while PowerShell uses $this

$This

In a script block that defines a script property or script method, the $This variable refers to the object that is being extended.

Source: about_Automatic_Variables

Sample:

$pocketKnife2 = New-Object PSObject -property @{
    Color = 'Black'
    Weight = '55'
    Manufacturer = 'Buck'
    Blades = '1'
}

$pocketKnife2 | Add-Member ScriptMethod GetColor {
    Write-Host "Color = $($this.Color)" 
}

$pocketKnife2.GetColor()
Color = Black

$pocketKnife2.Color = 'Red'

$pocketKnife2.GetColor()
Color = Red
Martimartial answered 14/2, 2015 at 14:42 Comment(5)
Aha! Thanks for that. I guess my Obj-C/Swift orientation showed there. ;) Unless maybe C uses Self as well. Anyway, that has me back on track for my weekend. On a related note, am I correct in understanding that in Powershell you basically build your object and define it's Init method, then call the Init method? Rather than there being standard methods that get called at certain times, like Init and Getters and Setters? Also, as I have my program structured now all the Log functions are in a different module, which means my new Log object is going to need to be a global variable, yes?Veneaux
I'm not a developer, so even though I understand the words you use, I'm not experienced enough with programming to fully understand your question. :-) What you need to understand is that PowerShell is not a programming language, but a scripting language. It built upon .NET Framework which means it can use 90+% of classes etc. from managed and unmanaged assemblies, but it's not a replacement for C, C# etc. If you need to define classes or use advanced programming features, then you should write an c# assembly, and use that in PS.Martimartial
In Powershell the way I use logging is a simple function that runs Out-File -Append etc. to save the message to a file, with ex. a global-scope variable specifying the path (which would be generated in the script or the first time you run the function). And yes, to use objects created in another script you should save the variable in the global-scope, like $global:MyGlobalvar = ...Martimartial
You might want to consider creating a custom class for you objects, rather than constructing them on the fly #18705658Refusal
mjolinor & Frode. F, I'll be looking at the custom class option, but given that I don't know C# I may just have to punt in the short term. :( I may just leave it to my Swift class to really get my head around OOP.Veneaux

© 2022 - 2024 — McMap. All rights reserved.