in reply to how to let sub return hash of 2 sub?

That line will work if you return a list of objects.

Say you want to create an object for each element of a hash, where name is the key of the element, and val is the value of the element.

sub parameter { ... return map { NameValTuple->new( name => $_, val => $rv{$_} } keys(% +rv); }
If you instead returned a list of hashes, it would look like
print $_->{name}, ': ', $_->{val}, "\n" for $objA->parameter( 'a.x' );

To return a list of hashes, you'd use

sub parameter { ... return map { +{ name => $_, val => $rv{$_} } } keys(%rv); }

(The "+" might not be needed. You can remove it if you don't get an error without it.)

Replies are listed 'Best First'.
Re^2: how to let sub return hash of 2 sub?
by toohoo (Beadle) on May 27, 2015 at 15:12 UTC

    Thanks at first, dear Ikegami.

    I see that I have to describe a little bit more, what I'm trying to do. But bag you pardon, please don't laugh too much about me, it's my fault.

    I have written now a short file of code, which should describe nearly, what I want to do.

    ___ testpar.pl ___

    #!/usr/bin/perl use objectA; my %myhash = ( 'a.x' => 1, 'b.y' => 2, 'c.x' => 3, ); my $objA = objectA->new(); $objA->map_query( \%myhash ); print $_->name, ': ', $_->val, "\n" for $objA->parameter( 'a.x' ); print $_->name, ': ', $_->val, "\n" for $objA->parameter( 'b.y' ); return;

    ___ objectA.pm ___

    package objectA; sub new { my $class = shift; my $self = {}; bless $self, $class; return $self; } sub map_query { my $self = shift; my $hash = shift; map { $self->{ values }->{ $_ } = $$hash{ $_ }; } keys %{ $hash }; } sub parameter { my $self = shift; my $para = shift; my $param = $para =~ m/^([^\.]*\.)(.*?)$/i ? $2 : $para; # return { sub name{ $param; }, sub value{ $self->{ values }->{ $pa +ra } || ''; } }; my $name = \&parameter_name( $param ); my $val = \&parameter_value( $self->{ values }->{ $para } ); return { $name, $val }; } sub parameter_name { my $param = shift; return $param; } sub parameter_value { my $parval = shift; return $parval || ''; } 1;
      Since my solution works for a zero or more objects, it also works for a single object.
      sub parameter { ... return NameValTuple->new( name => $name, val => $val ); }

      It's still simpler to return a hash since you don't have to create a new class.

      sub parameter { ... return map { +{ name => $_, val => $rv{$_} } } keys(%rv); }

      But you'd have to change

      print $_->name, ': ', $_->val, "\n" for $objA->parameter( 'a.x' );
      to
      print $_->{name}, ': ', $_->{val}, "\n" for $objA->parameter( 'a.x' );

        Hello wise Monks,
        first thanks to all.

        The question emerges, what my point is exactly. I will try to name it. The really fix point is the request of code, which is given to me:

        print $_->name, ': ', $_->val, "\n" for $objA->parameter( 'a.x' );

        This is fix, it is not allowed to me to change this. I myself now should find a solution, that fullfills this request.

        I guess, that parts of some of you might have put together to work.

        If I try the last of Ikegami, I have first to build an extra package NameValTuple to be able to call a new on it. May be this is the nearest solution. I will try this. I only tought there is a "short" construct, which can solve this request.

        Thanks again and best regards, Thomas

      In that case, return a list (or array reference) instead of a rather useless hash reference (as $name is converted into a string which then cannot be used as a sub reference) ...

      # In testpar.pl ... ... print join ': ' , map $_->() , $objA->parameter( 'a.x' ); ... # In A ... package A; ... sub parameter { ... return ( \&parameter_name( $param ) , \&parameter_value( $self->{ values }->{ $para } ) ) ; } ...