locked_user sundialsvc4 has asked for the wisdom of the Perl Monks concerning the following question:

Trying to follow the example in Moose::Meta::Attribute::Native::Trait::Hash, specifically the example at the middle of the page under kv, with this code:   (Perl 5.10.0 on OS/X)

package foo; use Moose; has "k"=>( traits=>["Hash"], is=>"rw", isa=>"HashRef[Str]", default=>sub{{}} ); my $f=foo->new(); print $f->k->kv;
... gives ...

Can't call method "kv" on unblessed reference

Incidentally, I find that ref($f) eq 'foo' and that ref($f->k) eq 'HASH'.   So it is, indeed, “an unblessed reference.”

So, I guess I just really don't understand how these Trait thingies are supposed to work ...   (A quick cover-your-asterisk check confirms that including or omitting handles as per the Synopsis makes no difference, as expected.)

I honestly think that I am writing the test exactly a shown in the page and it’s not working.   I pray for Enlightenment.

Update:   I now took the exact text of the example on the page and got the same result:

package Stuff; use Moose; has 'options' => ( traits => ['Hash'], is => 'ro', isa => 'HashRef[Str]', default => sub { {} }, handles => { set_option => 'set', get_option => 'get', has_no_options => 'is_empty', num_options => 'count', delete_option => 'delete', option_pairs => 'kv', }, ); my $object=Stuff->new(); for my $pair ( $object->options->kv ) { print "$pair->[0] = $pair->[1]\n"; }

Replies are listed 'Best First'.
Re: (Moose/Hash): Can't call method "kv" on unblessed reference
by chromatic (Archbishop) on Nov 16, 2011 at 23:45 UTC

    The example in the documentation should probably read:

    for my $pair ( $object->option_pairs ) { print "$pair->[0] = $pair->[1]\n"; }

    Is that clearer?


    Improve your skills with Modern Perl: the free book.

Re: (Moose/Hash): Can't call method "kv" on unblessed reference
by ikegami (Patriarch) on Nov 17, 2011 at 00:18 UTC

    You're trying to call kv on the hash ref returned by $object->k. Not gonna happen. Unblessed hash refs don't have methods.

    You mean to call a method you created for $object that's not even named kv.

    $object->option_pairs

    PS — All your links are broken.

      Links removed.   Thanks.
Re: (Moose/Hash): Can't call method "kv" on unblessed reference
by locked_user sundialsvc4 (Abbot) on Nov 17, 2011 at 00:12 UTC

    Okay, I figured it out by carefully examining the source-code of the native_traits/trait_hash.t test of this module.

    The example should read:   (with the strikeout omitted ...)
    for my $pair ( $object->options->kv ) {

    Or, more appropriately to a real-world situation (as you did suggest):

    for my $pair ( $object->options->option_pairs ) {

    The accessor makes it possible to iterate through the values of, say, the options property of the object, by repeated calls to this method of the object ... it is not a method of the property itself.   (AFAIK, Moose has no such concept.)

    The use of handles is, of course, the Right Goodness™ because, if (as you well might) you have more than one such property, you’ll need to define distinct accessor-names corresponding to each one and for that you of course must use handles.   (That’s of course what it is for.)

Re: (Moose/Hash): Can't call method "kv" on unblessed reference
by locked_user sundialsvc4 (Abbot) on Nov 16, 2011 at 23:50 UTC

    Unfortunately... no dice.   Using the copied example-code, as shown above with the change you suggested:

    Can't call method "option_pairs" on unblessed reference at foo.pl line 19.

    I’m afraid that this does not look to be “just an obvious tpyo.”   Something about this doesn’t work, and I sincerely don’t know why.

    The perldoc makes no mention of, say, Perl-version dependencies, and I see no bug-reports that seem to be relevant.

    For completeness, the code being discussed now reads:

    package Stuff; use Moose; has 'options' => ( traits => ['Hash'], is => 'ro', isa => 'HashRef[Str]', default => sub { {} }, handles => { set_option => 'set', get_option => 'get', has_no_options => 'is_empty', num_options => 'count', delete_option => 'delete', option_pairs => 'kv', }, ); my $object=Stuff->new(); for my $pair ( $object->options->option_pairs ) { print "$pair->[0] = $pair->[1]\n"; }