Hello!

Both `print` and `say` convert their argument to a string, but they do so by calling different methods on the argument. `print` calls the method `.Str`, while `say` calls the method `.gist`. On custom classes (like your PartitionClass), calling `.Str` will only return the object’s identifier by default, but calling `.gist` (or `.raku`) will return code you can run to re-create the object. So to get the same output with `print` like you did with `say`, only without the newline, you can do `print $Partition.gist` or `print $Partition.raku`. (`.gist` might not show the entire code if the text gets too long, so you might prefer to use `.raku`.)

Calling `.kv` doesn’t work, because objects (/unlike/ maps / tables) aren’t transparent structures that you can see the insides of. From the perspective of OOP, objects are opaque, and the only proper way to look inside is by calling their methods. So if you want to be able to see all of the object’s attributes, you should *give the class a method* that will return all of the object’s attributes in some form. You could override the `.Str` or `.gist` methods if you simply want to print the attributes in a nice form, or you could override the `.kv` method if you might want to do something else with them. Here’s an example:

   [0] > class PartitionClass{
       has Str $.DeviceID          is rw;
       has Str $.VolumeName        is rw;
       has Str $.ProviderName      is rw;
       has Str $.UNC_BackupPath    is rw;
       has Int $.DriveType         is rw;
       has Str $.DriveTypeStr      is rw;
       has Int $.FreeSpace         is rw;
       has Int $.Size              is rw;
       has Int $.PercentUsed       is rw;
       has Int $.PercentRemaining  is rw;

       #| Return a list of pair objects: (Attribute name => Attribute
   value)
       method pairs(--> Iterable) {
           :$.DeviceID, :$.VolumeName, :$.ProviderName,
           :$.UNC_BackupPath, :$.DriveType, :$.DriveTypeStr,
           :$.FreeSpace, :$.Size, :$.PercentUsed, :$.PercentRemaining;
       }

       #| Return a sequence of attribute names and values interleaved.
       method kv(--> Iterable) {
           $.pairs.map({ .kv }).flat;
       }

       #| Return a string presenting all attributes on a single line.
       method Str(--> Str) {
           $.pairs.map({ .key ~ “: ” ~ .value }).join(“, ”) ~ “.”;
       }
   }
   (PartitionClass)

   [1] > my $Partition = PartitionClass.new(
       DeviceID         => "",
       VolumeName       => "",
       ProviderName     => "",
       UNC_BackupPath   => "",
       DriveType        => 0,
       DriveTypeStr     => "Unknown",
       FreeSpace        => 0,
       Size             => 0,
       PercentUsed      => 0,
       PercentRemaining => 100
   );
   PartitionClass.new(DeviceID => "", VolumeName => "", ProviderName =>
   "", UNC_BackupPath => "", DriveType => 0, DriveTypeStr => "Unknown",
   FreeSpace => 0, Size =>
   0, PercentUsed => 0, PercentRemaining => 100)

   [2] > for $Partition.kv -> $i, $j { print "i <$i>   j <$j>\n" }
   i <DeviceID>   j <>
   i <VolumeName>   j <>
   i <ProviderName>   j <>
   i <UNC_BackupPath>   j <>
   i <DriveType>   j <0>
   i <DriveTypeStr>   j <Unknown>
   i <FreeSpace>   j <0>
   i <Size>   j <0>
   i <PercentUsed>   j <0>
   i <PercentRemaining>   j <100>

   [2] > print $Partition ~ "\n";
   DeviceID: , VolumeName: , ProviderName: , UNC_BackupPath: ,
   DriveType: 0, DriveTypeStr: Unknown, FreeSpace: 0, Size: 0,
   PercentUsed: 0, PercentRemaining: 100.

   [2] > say $Partition;
   PartitionClass.new(DeviceID => "", VolumeName => "", ProviderName =>
   "", UNC_BackupPath => "", DriveType => 0, DriveTypeStr => "Unknown",
   FreeSpace => 0, Size =>
   0, PercentUsed => 0, PercentRemaining => 100)

Of course, both the code and the formatting of the output could be improved. :-)

You could also ask Raku to list all of the object’s attributes and then find each of their values for your object. This pretty much violates the principles of OOP, so it might not be something you want your programs to rely on, but if you just need to inspect an object’s internal state for your personal use, it’s probably fine! An example:

   [2] > for $Partition.^attributes { say “{.name}: {.get_value:
   $Partition}” }
   $!DeviceID:
   $!VolumeName:
   $!ProviderName:
   $!UNC_BackupPath:
   $!DriveType: 0
   $!DriveTypeStr: Unknown
   $!FreeSpace: 0
   $!Size: 0
   $!PercentUsed: 0
   $!PercentRemaining: 100

If there are better ways, I’m afraid I don’t know of them. Hope this helps, though! ^ ^
// Tirifto

On 11. 04. 25 8:19, ToddAndMargo via perl6-users wrote:
Hi All,

I am not having any luck printing the values of a OOP
structure, except for printing them one at a time.  I
can get it to messily print with `say`, but I want to
do it with `print` so I can control the line feeds,
comments, etc..

What am I doing wrong?

Many thanks,
-T


[0] > class PartitionClass{
    has Str $.DeviceID          is rw;
    has Str $.VolumeName        is rw;
    has Str $.ProviderName      is rw;
    has Str $.UNC_BackupPath    is rw;
    has Int $.DriveType         is rw;
    has Str $.DriveTypeStr      is rw;
    has Int $.FreeSpace         is rw;
    has Int $.Size              is rw;
    has Int $.PercentUsed       is rw;
    has Int $.PercentRemaining  is rw;
}
(PartitionClass)


[1] > my $Partition = PartitionClass.new(
    DeviceID         => "",
    VolumeName       => "",
    ProviderName     => "",
    UNC_BackupPath   => "",
    DriveType        => 0,
    DriveTypeStr     => "Unknown",
    FreeSpace        => 0,
    Size             => 0,
    PercentUsed      => 0,
    PercentRemaining => 100
);
PartitionClass.new(DeviceID => "", VolumeName => "", ProviderName => "", UNC_BackupPath => "", DriveType => 0, DriveTypeStr => "Unknown", FreeSpace => 0, Size => 0, PercentUsed => 0, PercentRemaining => 100)


[2] > for $Partition.kv -> $i, $j { print "i <$i>   j <$j>\n" }
i <0>   j <PartitionClass<4875316684000>>


[2] > print $Partition ~ "\n";
PartitionClass<4875316684000>


[2] > say $Partition;
PartitionClass.new(DeviceID => "", VolumeName => "", ProviderName => "", UNC_BackupPath => "", DriveType => 0, DriveTypeStr => "Unknown", FreeSpace => 0, Size => 0, PercentUsed => 0, PercentRemaining => 100)

Reply via email to