如何在Perl中的getter方法中返回两个值?

XXI*_*XIV 2 perl

use strict;
use warnings;

package LineSegment;

sub new
{       
        my $class = shift; 
        my ($ax, $ay, $bx, $by) = @_;
        my $self = {"ax"=>$ax,
                    "ay"=>$ay,
                    "bx"=>$bx,
                    "by"=>$by,
                   }; 
        bless ($self, $class);
        return $self;
}
sub getA{
        #Issue on get A
        my $self = shift;
        return ($self->{ax}, $self->{ay});
}
sub getB{
        #Issue on get B
        my $self = @_;
        return ($self->{bx}, $self->{by});
}
sub setA{
        #Can print correct value. Is the return statement where it goes wrong?
        my($self, $ax, $ay) = @_;
        $self->{ax} = $ax if defined($ax);
        $self->{ay} = $ay if defined($ay);
        print "Setting ax: $self->{ax}\n";
        print "Setting ay: $self->{ay}\n";

        return ($self->{ax}, $self->{ay});
}
sub setB{
         #Can print correct value. Is the return statement where it goes wrong?
        my($self, $bx, $by) = @_;
        $self->{bx} = $bx if defined($bx);
        $self->{by} = $by if defined($by);
        return $self->{bx}, $self->{by};
}
1;
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个名为LineSegment的类.ax和ay是一个点,因此是bx和by.我不能让getA或getB返回我想要的东西.它们只返回第二个值,对于getA和getB,它们都是ay.我希望它返回两个值(ax,ay)或(bx,by).我怎么做到这一点?在我的setA和setB方法中,将打印值.但是,我可以在setA和setB中将它们返回错误吗?或者我的问题在于我的getter方法?

这是我的主要内容:

print "Starting Line Segment\n";
use LineSegment;
$line = new LineSegment(10,20,30,40);
$line->setA(15,10);
$a = $line->getA();
print "Point A is: $a\n";
Run Code Online (Sandbox Code Playgroud)

这是我的Point类:

use strict;
use warnings;

#class name 
package Point;

#constructor
sub new
{
        my $class = shift;
        my($x, $y) = @_;
        my $self = {"x"=>$x,
                    "y"=>$y,
                   };
        bless ($self, $class);
        return $self;
}

sub getX{
        my($self) = @_;
        return $self->{x};
}
sub setX{
        my ($self, $x) = @_;
        $self->{x} = $x if defined($x);
        return $self->{x};
}
sub setY{
        my ($self, $y) = @_;
        $self->{y} = $y if defined($y);
        return $self->{y};
}
sub random{
        my $self = shift;
        my $range = 50;
        $self->{x} = int(rand($range));
        $self->{y} = int(rand($range));

        return ($self->{x}, $self->{y});
}
1;
Run Code Online (Sandbox Code Playgroud)

更新主要:

use strict;
use warnings;

    use Point;
    use LineSegment;

    my $line = LineSegment->new(Point->new()->random, Point->new()->random);
    my $pointA = $line->getA;
    my $pointB = $line->getB;
    printf "Point = (%d,%d)\n", $pointA->getX, $pointA->getY;
Run Code Online (Sandbox Code Playgroud)

Bor*_*din 6

正如Tanktalus指出的那样,您将返回两个值的列表,并期望能够将其视为单个Point对象.标量上下文中的列表计算到列表的最后一个元素,因此您只获得Y坐标

我在下面写了一些功能代码.可能让您感到困惑的一件事是哈希切片语法与之@{$self}{qw/ _x _y /} = @_相同

$self->{_x} = $_[0];
$self->{_y} = $_[1];
Run Code Online (Sandbox Code Playgroud)

你应该记住use strict,并use warnings在每一个Perl的源文件的顶部.你也应该避免使用它$a,$b因为它们在Perl内部使用.无论如何,更长,更具描述性的标识符更好

如果我改变你Point.pm的构造函数接受参数(我也修复了你的random方法)就像这样

Point.pm

use strict;
use warnings 'all';

package Point;

sub new {
    my $class = shift;

    my $self = { };
    @{$self}{qw/ _x _y /} = @_ if @_;

    bless $self, $class;
}

sub getX{
    my $self = shift;

    return $self->{_x};
}

sub getY{
    my $self = shift;

    return $self->{_y};
}

sub setX {
    my $self = shift;

    $self->{_x} = $_[0] if @_;

    return $self->{_x};
}

sub setY {
    my $self = shift;

    $self->{_y} = $_[0] if @_;

    return $self->{_y};
}

use constant RANGE => 50;

sub random {
    my $self = shift;

    $self->{_x} = int rand RANGE;
    $self->{_y} = int rand RANGE;

    return $self;
}

1;
Run Code Online (Sandbox Code Playgroud)

并写LineSegment.pm这样的

LineSegment.pm

use strict;
use warnings 'all';

package LineSegment;

sub new {
    my $class = shift;

    my $self = { };
    @{$self}{qw/ _pA _pB /} = @_ if @_;

    bless $self, $class;
}

sub getA {
    my $self = shift;

    return $self->{_pA};
}

sub getB {
    my $self = shift;

    return $self->{_pB};
}

sub setA {
    my $self = shift;

    $self->{_pA} = $_[0] if @_;

    return $self->{_pA};
}

sub setB {
    my $self = shift;

    $self->{_pB} = $_[0] if @_;

    return $self->{_pB};
}

1;
Run Code Online (Sandbox Code Playgroud)

那么我可以编写一个程序来完成我认为你想要的东西

main.pl

use strict;
use warnings 'all';

use Point;
use LineSegment;

my $line = new LineSegment(
    Point->new(10, 20),
    Point->new(30, 40),
);

$line->setA( Point->new(15, 10) );

my $point = $line->getA;

printf "Point = (%d,%d)\n",
    $point->getX,
    $point->getY;
Run Code Online (Sandbox Code Playgroud)

产量

Point = (15,10)
Run Code Online (Sandbox Code Playgroud)