ChristopherDBerry
ChristopherDBerry

Reputation: 1772

Perl's map function with OO perl

Within an Perl object's method I would like to call another method on a list of variables. Using map like so does not work:

($open, $high, $low, $close) 
    = map( $self->adjust_for_factor, ($open, $high, $low, $close) );

....

sub adjust_for_factor {
    my $self = shift;
    my $price = shift;

    return $price *  $self->get_factor ;
}

This works, however its ugly and doesn't scale. I'm sure it must be possible to use map here:

($open, $high, $low, $close) 
= (  $self->adjust_for_factor($open)
, $self->adjust_for_factor($high)
, $self->adjust_for_factor($low)
, $self->adjust_for_factor($close) );

I guess it's an issue of referencing self in the correct way. I'm having trouble conceptualizing how it all fits together.

Thanks to all who take the time to consider/ leave feedback.

Upvotes: 2

Views: 275

Answers (3)

ikegami
ikegami

Reputation: 386216

($open, $high, $low, $close) =
    map $self->adjust_for_factor, $open, $high, $low, $close;

should be

($open, $high, $low, $close) =
    map $self->adjust_for_factor($_), $open, $high, $low, $close;

which can be shortened to

$_ = $self->adjust_for_factor($_)
    for $open, $high, $low, $close;

Upvotes: 3

DVK
DVK

Reputation: 129473

You forgot to pass a parameter to your object's method (hat tip tchrist), here's a working example:

$ cat l1.pl
use strict;
package p;

sub new { return bless({factor => $_[1]}, $_[0]); }
sub get_factor { return $_[0]->{factor}; }
sub adjust_for_factor {
    my ($self, $price) = @_;
    return $price * $self->get_factor;
}

package main;

my $obj = p->new(3); # Don't use "self" for object name outside object's class!
my @res = map ($obj->adjust_for_factor($_), qw(1 2 3));
print join(", ", @res) . "\n";

$ ./l1.pl
3, 6, 9

Upvotes: 4

Eugene Yarmash
Eugene Yarmash

Reputation: 149933

As @tchrist said, you forgot to pass $_ to your method. The correct way would be

($open, $high, $low, $close)    
    = map $self->adjust_for_factor($_), $open, $high, $low, $close;

You can also modify the method so that it can accept a list:

sub adjust_for_factor {
    my ($self, @prices) = @_;

    return map $_ * $self->get_factor, @prices;
}

($open, $high, $low, $close)      
     = $self->adjust_for_factor($open, $high, $low, $close);

Upvotes: 7

Related Questions