in reply to Re^3: how to let sub return hash of 2 sub?
in thread how to let sub return hash of 2 sub?

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

Replies are listed 'Best First'.
Re^5: how to let sub return hash of 2 sub?
by ikegami (Patriarch) on May 28, 2015 at 14:00 UTC

    find a solution, that fullfills this request.

    For the third time, what you need is

    sub parameter { ... return NameValTuple->new( name => $name, val => $val ); }

    I have first to build an extra package NameValTuple

    Yes, yes you do. By definition, you can't have objects without a class.

      However, that class doesn't have to have a 'new' method; and I'd argue that it's really superfluous, if the class's use cases are no more complex than this.

      return bless { name => $name, val => $val }, 'NameValTuple';

      The one potential downside of this is that it "exposes" the representation of the underlying object (in this case, a hash). Having a 'new' method hides all that. I personally believe that, at least in a simple case like this, there's hardly anything to be gained from hiding it.

        You could inline new, but you still need name and val.

        I don't see the point of changing

        return NameValTuple->new( name => $name, val => $val ); { package NameValTuple; sub new { my $class = shift; bless({ @_ }, $class) } sub name { $_[0]->{name} } sub val { $_[0]->{val} } }
        to
        return bless { name => $name, val => $val }, 'NameValTuple'; { package NameValTuple; sub name { $_[0]->{name} } sub val { $_[0]->{val} } }

        It breaks encapsulation for no reason.

      Hello dear Ikegami, hello dear people,

      Dear Ikegami, bag your pardon, as I mitght possibly read wrong, you named different things. First time you wrote: Re: how to let sub return hash of 2 sub?

      objectA.pm

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

      But map if I'm thinking right returns an array, does'nt it? That is not 100% exactly what I need.

      Second time you wrote: Re^3: how to let sub return hash of 2 sub?

      sub parameter { ... return NameValTuple->new( name => $name, val => $val ); }

      .. which I am unsure what it does exactly. There are the 2 scalars $name and $val. But I think I need really two subs in the returned object.

      Now as I see, you write the same as second time. Okay so far.

      I have tried to guess, what you have meant to do. This is my solution with a little change at all.

      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; print "__ parameter para[$para] \n"; my $param = $para =~ m/^([^\.]*\.)(.*?)$/i ? $2 : $para; print "__ parameter param[$param] - val[$self->{ values }->{ $p +ara }]\n"; return NameValTuple->new( $param, $self->{ values }->{ $para } ); } package NameValTuple; sub new { my $class = shift; my $self = { _key => shift, _val => shift || '', }; bless $self, $class; print ">> NameValTuple new key[$self->{_key}] val[$self->{_val +}]\n"; return $self; } sub name { my $self = shift; return $self->{_key}; } sub val { my $self = shift; return $self->{_val}; } 1;

      As you might have seen allready, I do not simple want the key and the value but have to change the key in this way, that instead of the key I have to return the key without the leading word plus dot.

      This seams to work now, together with the former listed testpar.pl Re^2: how to let sub return hash of 2 sub?

      Thanks to you all, Have A Nice Day, Thomas

Re^5: how to let sub return hash of 2 sub?
by Anonymous Monk on May 28, 2015 at 14:12 UTC
    I only tought there is a "short" construct, which can solve this request.

    Moose and Moo were already suggested to you as examples of frameworks to make writing classes easier.

      I wasn't aware that they could create anonymous classes, and I'm not seeing the advantage of
      { package NameValTuple; use Moose; has name => ( is => 'rw' ); has val => ( is => 'rw' ); no Moose; __PACKAGE__->meta->make_immutable; }
      over
      { package NameValTuple; sub new { my $class = shift; bless({ @_ }, $class) } sub name { $_[0]->{name} } sub val { $_[0]->{val} } }

        Fair point; if the OP only needs to write a couple of classes by hand that's fine. If he ends up needing to write more classes than that, perhaps some with inheritance etc., learning and using one of the Perl OO frameworks should show its advantages pretty quickly.