none
$_ in quotes RRS feed

  • Question

  • If I run a script

    $files = get-childitem C:\testfiles

    $files  | % { "$_" }

    it returns the Name property. As it happens this suits me, but I cannot find any documentation on why it does so. Any know why ?.

    Sunday, May 27, 2018 6:12 PM

Answers

  • Because you are implicitly asking for the conversion of a FileInfo object to a String. It is the same as doing it explicitly:

    $f | % { $_.tostring() }

    • Marked as answer by jksg Monday, May 28, 2018 4:56 PM
    Sunday, May 27, 2018 7:33 PM

All replies

  • Quoting a file object returns the name.

    PS D:\scripts>> $x = Get-Item test.txt
    PS D:\scripts>> $x
    
    
        Directory: D:\scripts
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        2/22/2018  12:07 PM             12 test.txt
    
    
    PS D:\scripts>> "$x"
    D:\scripts\test.txt
    PS D:\scripts>>

    One reason to not use quotes except when you know they are required.


    \_(ツ)_/

    Sunday, May 27, 2018 6:32 PM
    Moderator
  • Yes, looks like that's just how it is.
    Sunday, May 27, 2018 7:11 PM
  • Because you are implicitly asking for the conversion of a FileInfo object to a String. It is the same as doing it explicitly:

    $f | % { $_.tostring() }

    • Marked as answer by jksg Monday, May 28, 2018 4:56 PM
    Sunday, May 27, 2018 7:33 PM
  • or ths:

    $files | % {[string]$_ }

    or this:

    $files | % {$_.Fullname }

    or this

    $files | % {'' + $_ }

    or this

    $files | % {$_ -eq 'c:\file.txt'}

    And dozens of other ways an object can become a string.


    \_(ツ)_/

    Sunday, May 27, 2018 7:47 PM
    Moderator
  • Reason why it does this has already been explained. But if you want to use other properties of the $_ object, you can "escape" the variable:

    $files | % { Write-Host "File: $($_.FullName)" }



    Floris van der Ploeg - www.florisvanderploeg.com

    If my post was helpfull, remember to click the "Propose as answer" button.

    Monday, May 28, 2018 9:05 AM
  • Reason why it does this has already been explained. But if you want to use other properties of the $_ object, you can "escape" the variable:

    $files | % { Write-Host "File: $($_.FullName)" }



    Floris van der Ploeg - www.florisvanderploeg.com

    If my post was helpfull, remember to click the "Propose as answer" button.

    Correct but it is not called "escape" the construct is called a subexpression evaluation.  "()" denote a subexpression.  The subexpression evaluator is this "$()".

    Check "help" for more info.


    \_(ツ)_/

    Monday, May 28, 2018 1:15 PM
    Moderator
  • For whatever the type is, a .ToString() method is defined for it in .net.

    PS /Users/js> echo hi > file

    PS /Users/js> $a = ls file

    PS /Users/js> $a.gettype()

    IsPublic IsSerial Name                                     BaseType

    -------- -------- ----                                     --------

    True     False    FileInfo                                 System.IO.FileSystemInfo

    PS /Users/js> $a.tostring()

    /Users/js/file

    PS /Users/js> "$a"

    /Users/js/file



    • Edited by JS2010 Monday, May 28, 2018 2:14 PM
    Monday, May 28, 2018 2:13 PM
  • All types do not define a "ToString" method.  Only some types can be converted.

    \_(ツ)_/

    Monday, May 28, 2018 2:16 PM
    Moderator
  • Can you give a counterexample?  There may be some inheritance involved, but any type I think can of has a tostring() you can call.  Granted, with [pscustomobject], it comes out blank.

    Here's a funny example where powershell turns an object from the pipe into a string because it's so desperate for the byvalue name parameter.

    [pscustomobject]@{totalcount=1} | get-command
                                                                                          
    get-command : The term '@{totalcount=1}' is not recognized as the name of a cmdlet, function, script file, or operable program.
    Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:35
    + [pscustomobject]@{totalcount=1} | get-command
    +                                   ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{totalcount=1}:String) [Get-Command], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand








    • Edited by JS2010 Monday, May 28, 2018 3:16 PM
    Monday, May 28, 2018 3:02 PM
  • ToString() is implemented as a victual method that each type can implement or not.

    The base method is empty.

    In object-oriented programming, in languages such as C++, and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method for which dynamic dispatch is facilitated. This concept is an important part of the (runtime) polymorphism portion of object-oriented programming (OOP).

    See: Virtual function - Wikipedia


    \_(ツ)_/

    Monday, May 28, 2018 3:38 PM
    Moderator
  • Glad we agree.
    Monday, May 28, 2018 4:48 PM
  • Glad we agree.

    Agree on what?

    "ToString" is not implemented on many types and many types will only return the type.


    \_(ツ)_/

    Monday, May 28, 2018 4:51 PM
    Moderator
  • Thanks everyone, I have marked the first explicit mention of tostring as the answer. I have one further question. What determines the Tostring returns the Name property rather than say Fullnsme ?
    Monday, May 28, 2018 4:58 PM
  • For each type you have to look it up in the documentation.

    For a FileInfo object:

    https://msdn.microsoft.com/en-us/library/system.io.fileinfo.tostring(v=vs.110).aspx

    The code is internal to each type.

    For a Process object see: https://msdn.microsoft.com/en-us/library/1khx1h1e(v=vs.110).aspx


    \_(ツ)_/

    Monday, May 28, 2018 5:10 PM
    Moderator
  • Thanks.
    Monday, May 28, 2018 5:17 PM
  • This is why it is critical in PowerShell to learn "object" technology.  In Windows almost everything is an object.  In Net all things net are objects created from "types" of "classes".  Proficiency in PowerShell assumes a good working knowledge of objects and object systems.

    One place to start is here: https://en.wikipedia.org/wiki/Object-oriented_programming

    also:

    https://en.wikipedia.org/wiki/Class_(computer_programming)

    https://en.wikipedia.org/wiki/Object_(computer_science)

    Extra credit and a free donut: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/classes


    \_(ツ)_/

    Monday, May 28, 2018 5:28 PM
    Moderator