Ohhh I see the parens are significant. Now this works :)

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

    method show {
        for <ropa fósforos femur> {
            self!show-item(.values.tc, .values, 'amount');
        }
        self!show-item('Vida útil de la antorcha', 'antorcha', 'duration');
    }

2017-12-30 5:54 GMT-03:00 Siavash <siavash.askari.n...@gmail.com>:

>
> What you want is `%items{$item}."$attr"()`.
>
> But if all you want is removing the show's repetition, maybe there are
> other ways, for example:
>
> for %!items<ropa femur fósforos>:kv {
>     say $^key.tc, ' ', $^value.amount;
> }
>
> or if you want all items:
>
> for %!items {
>     say .key.tc, ' ', .value.amount;
> }
>
> On 2017-12-30 05:13:43 GMT, clasclin . wrote:
> > 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