関数の引数のコンテキストはリスト

今日 DBIC を使ってて若干ハマったのでメモです。

sub list {
    shift->schema->resultset('User')->search({}, { 'order_by' => 'user_id' });
}

sub as_fdat {
    map +{ $_->get_columns }, $_[1]->all;
}

sub list_as_fdat {
    my $self = shift;
    [ $self->as_fdat( $self->list() ) ];
}

というようなメソッドを用意して、実行したら all なんてメソッド無いよと怒られました。

list_as_fdat() に my $rs = $self->list() を入れて中身を見てみても ResultSet オブジェクトが入ってます(当たり前)。

おそらく、as_fdat() を呼んでいるところで、リストリファレンスで囲んでいるので、リストコンテキストで list() が評価されているのだろうなと思って試したら、それもそうなのですが、それだけではなく、関数の引数もリストコンテキストで評価されていました。

正しくは、こう書く必要があります。

sub list_as_fdat {
    my $self = shift;
    [ $self->as_fdat( scalar $self->list() ) ];
}

以下のコードで試してみたところ、

sub sub1 {
    [ foo() ];
}

sub sub2 {
    foo();
}

sub sub3 {
    [ bar( foo() ) ];
}

sub sub4 {
    bar( foo() );
}

sub bar {
    map [ $_ ], @_;
}

sub foo {
    return wantarray ? qw(a r r a y) : "scalar";
}


my $r1 = sub1();
my $r2 = sub2();
my $r3 = sub3();
my $r4 = sub4();

print Dumper $r1;
print Dumper $r2;
print Dumper $r3;
print Dumper $r4;

実行結果はこうなりました。

$VAR1 = [
          'a',
          'r',
          'r',
          'a',
          'y'
        ];
$VAR1 = 'scalar';
$VAR1 = [
          [
            'a'
          ],
          [
            'r'
          ],
          [
            'r'
          ],
          [
            'a'
          ],
          [
            'y'
          ]
        ];
$VAR1 = 5;