1

オンラインのチュートリアルを使用して、Perl を始めたばかりです (約 15 分前)。いくつかの Perl 機能をテストするための小さなサブルーチンを作成しましたが、sub' 呼び出しに渡されたパラメーターが配列かスカラーかを実行時に判断できるかどうかを知りたいです。私が書いたサブを例として使用しましょう:

#!/usr/bin/perl

sub somme_prod {
    if (scalar(@_) > 1) {
        $facteur = shift(@_);
        foreach my $nb (@_) {
            $resultat += $nb
        }
        return ($resultat * $facteur);
    }
    else {
        return "ERREUR";
    }
}

print somme_prod(2, 2, 3, 7);

これは基本的な和積サブルーチンで、まさにその名前が示すとおりです。さて、このサブルーチンを変更して、このように配列とスカラーを混在させることは可能でしょうか?

somme_prod(2, (2,3), 7);
somme_prod(2, (2,3,7));
#...

また、ここで示した Perl コーディングのスタイルに関するコメントは歓迎です。私はアマチュア C++ コーディングのバックグラウンドがあるので、Perl について考えていないかもしれません。

編集:申し訳ありません。投稿後に実際に試してみたところ、Perl が私のサブルーチンを希望どおりに処理しているようです。さて、私の質問は「Perl はこれを処理する方法をどのように知っているか」ということになると思います。

より Perl っぽいバージョンのコードを編集しました。

4

3 に答える 3

2

Perl はリストと配列を異なる方法で扱います。What is the difference between a list and an array?

Perl は常にネストされたリスト (およびリスト内の配列) を平坦化します。

my @data1 = (2, (2, 3), 7);

また

my @data2 = (2, 3);
my @data1 = (2, @data2, 7);

と同等です

my @data1 = (2, 2, 3, 7);

Kevin が言うように、ネストされた配列が必要な場合は、サブリストが表示される場所に配列参照を配置する必要があります。参照はスカラーであるため、展開されません。

サブルーチンは問題ありませんが、事実上の標準を使用すると、他の人があなたのプログラムに従うのに役立ちます。まず、undefエラーが発生した場合にサブルーチンが返されるという慣習があるため、次のように記述できます。

sous_routine($p1, $p2) or die "Erreur";

この場合、ゼロが有効な結果である可能性がこれを台無しにしますが、それでも規則に従うことが最善です。returnパラメータのないプレーンはエラーを示します

unlessand ifas ステートメント修飾子を少し整理して使用すると、次のようになります。

sub somme_prod {
  return unless @_ > 1;
  my $facteur = shift;
  my $somme = 0;
  $somme += $_ for @_;
  return $somme * $facteur;
}

print somme_prod(2, 2, 3, 7);
于 2012-08-12T22:10:07.257 に答える
2

はい; Perl では、配列 (またはハッシュなど) への参照を作成して、複数の値を 1 つのパラメーターに詰め込むことができます。

例えば:

somme_prod(2, [2, 3], 7);

...次のように解決されます。

sub somme_prod {
  foreach my $arg (@_) {
    if (ref($arg) eq 'ARRAY') {
      my @values = @$arg; # dereference, e.g. [2, 3] -> (2, 3)
      . . .
    } else {
      # single value, e.g. "2" or "7"
    }
  }
}

このページを読んで、参照perldoc perlrefに関するすべてを学ぶことができます。

于 2012-08-12T20:50:22.080 に答える
0

Perl を 15 分間知っていましたか? 今のところ参照を忘れてください。

基本的に、サブルーチンに渡されるものはすべて配列です。実際、それは という配列に格納されてい@_ます。

# /usr/bin/env perl

use strict;   #ALWAYS USE!
use warnings; #ALWAYS USE!

my @array = qw(member1 member2 member3 member4);

foo(@array, 'scalar', 'scalar', 'scalar');

sub foo {

print "My input is " . join (":", @_) . "\n";

これは印刷されます:

my input is member1:member2:member3:member4:scalar:scalar:scalar

配列からのエントリとスカラーからのエントリを区別する方法はありません。サブルーチンに関する限り、それらはすべて array のメンバーです@_


ちなみに、Perl には というコマンドが付属していperldocます。誰かが を参照するように言った場合、コマンド ラインに入力してドキュメントを表示perlrefできます。コマンドで見つかったのと同じ情報が含まれてperldoc perlrefいるサイトに移動することもできます。http://perldoc.perl.orgperldoc


さて、参考文献について....

Perl 配列のデータ要素またはハッシュの値には、単一の値のみを含めることができます。それは文字列かもしれないし、実数かもしれないし、整数かもしれないし、別の Perl データ構造への参照かもしれない。そこにすべての楽しみとお金があります。

たとえば、foo上記の同じサブルーチンで次の情報を取得できます。

foo(\@array, 'scalar', 'scalar', 'scalar'); #Note the backslash!

この場合、@arrayintoの値を渡していませんfoo。代わりに、配列への参照が の最初のデータ要素として渡され@_ます。を印刷しようとすると、データ要素が配列であり、メモリ内のどこにある$_[0]かを示すようなものが表示されます。ARRAY:6E43832

これで、関数を使用してref、データの一部が参照であるかどうか、およびその参照のタイプを確認できます。

 sub foo {
     foreach my $item (@_) {

        if (ref $item eq 'ARRAY') {
           print "This element is a reference to an array\n";
        }
        elsif (ref $item eq 'HASH') {
           print "This element is a reference to a hash\n";
        }
        elsif (ref $item) {   #Mysterious Moe Reference
            print "This element is a reference to a " . lc (ref $item) . "\n";
        }
        else {
            print "This element is a scalar and it's value is '$item'\n";
        }
    }
}

もちろん、配列への参照は、配列などへの参照を含むハッシュへの参照を含む配列である可能性があります。データ構造全体を出力する Perl に付属のモジュール(それに関する情報を表示するためにData::Dumper使用できます) が呼び出されます。perldoc

これがオブジェクト指向の Perl のしくみなので、Perl データの一部に埋め込まれた他の Perl データ構造への参照を持つことは非常に一般的です。

今は、基本的な Perl とその仕組みに慣れるだけです。次に、Perldoc にあるPerl リファレンスに関するさまざまなチュートリアルを参照してください。

于 2012-08-12T23:46:14.950 に答える