I'm reading a book "Make your own python text adventure" and decided to
give it a try with perl6. So this code works as expected.

class Bag {
    has %.items;

    method show {
        say "ropa ", %!items<ropa>.amount
            if %!items<ropa>:exists;
        say "femur ", %!items<femur>.amount
            if %!items<femur>:exists;
        say "fósforos ", %!items<fósforos>.amount
            if %!items<fósforos>:exists;
    }
}

I'm using a class called bag as my inventory and trying to keep track of
items in a hash, so the key is just a name and the value is an object and
just found that a pattern when I try to list the elements on the screen...

dd %!items
Hash %!items = {:femur(Items::Femur.new(amount => 1)),
:fósforos(Items::Matches.new(amount => 3)), :ropa(Items::Cloth.new(amount
=> 4))}

Items has data and the show method does what I expect, then I change the
code, so I try to add a private method that handdle the pattern and change
the show method to use the private one.

class Bag {
    has %.items;

    method !show-item ($msg, $item, $attr) {
        # dd $msg; dd $item; dd $attr; # all Str
        say "$msg ", %items{$item}.$attr
            if %!items{$item}:exists;
    }

    method show {
         self!show-item('Ropa', 'ropa', 'amount');
         ...
     }
}

Now I get an error, the line corresponds to the private method
No such method 'CALL-ME' for invocant of type 'Str'

Try a few variants like return instead of say or things like
    say "$msg", "%!items{$item}.$attr"; # output: Ropa
Items::Cloth<94810994868552>.amount
    say "$msg", $!items{$item}.{$attr}; # output: Type Items::Cloth does
not support associative indexing.
    say "$msg", %!items{$item}."{$attr}"; # ouput: gives a compile error

The output I'm expecting is: Ropa 4
Ropa is the $msg, and 4 corresponds to the value in the attribute amount.

Is there a way to refactor my code? Thanks in advance.

Reply via email to