3

こんにちは私はperlを学んでいます、そして私はここにいくつかの仮定を投稿します。ですから、どこかで間違っている場合は、遠慮なくコメントして訂正してください。

  1. ハッシュの作成は(他のいくつかの方法の中で)次の方法で行われます。

    %numbers = qw(one 1 two 2);
    
  2. アレイの作成は次のように行われます。

    @array = qw(one two);
    
  3. 上記の構造は「非匿名」タイプを表しています。非匿名型と匿名型の主な違いは、名前付き型には参照できる名前があることです。匿名型を作成する場合は、配列内()の角括弧、またはハッシュ内の中括弧の括弧を変更する必要があります。言い換えれば、ハッシュのハッシュは他のハッシュへの参照のハッシュです。したがって、クラシックハッシュではなく、ネストされたハッシュで使用する必要があります。[]{}{}()

    %HoH = (
        flintstones => {
            husband   => "fred",
            pal       => "barney",
        },
        jetsons => {
            husband   => "george",
            wife      => "jane",
            "his boy" => "elroy",  # quotes needed on key.
        },
        simpsons => {
            husband   => "homer",
            wife      => "marge",
            kid       => "bart",
        },
    );
    
  4. 同じ状況が多次元配列にも当てはまります。多次元配列は別の配列への参照を含む配列であるため、代わりに[]を使用する必要があります()。

    @array_of_arrays =  ( [ "one", "two", "three" ],
                          [  4,   5,  6,  7  ],
                          [ "alpha", "beta" ]
                        );
    
  5. 各家族(フリントストーン、ジェットソン、シンプソン)を含む「匿名でない」ハッシュがある場合、作成にどの構造を使用する必要があり%HOHますか?

    $HOH{flinstones} = {%flinstones};
    

    また

    $HOH{flinstones} = \%flinstones;
    

    私はそれ\%flinstonesが単にへの参照を割り当てていると仮定しています$HOH{flinstones}、これはそれが単にそれへの参照を含んでいるので私がすることは何でも%flinstones影響を与えることを意味し$HOH{flinstones}ます。一方{%flinstones}、「非匿名」ハッシュを「匿名」ハッシュに再キャストするようなものです。これには%flinstones、後で変更または削除することもできる効果があり、$HOH{flinstones}匿名ハッシュへの参照があるため、影響はありません。

  6. ループ内の変数はどうなりますか?ループ内で発行されると、古いものを上書きするmy $variable;か、新しいものを作成するか、同じ変数であるか、またはここで何が起こりますか?

    for($i=0;$i<4;$i++){
      my $variable=$i;
      print $variable
    }
    
4

3 に答える 3

3

質問5は質問1だと思いますが、どちらも使えます。最初の方法は次のことを理解する必要があります。

$HOH{flinstones} = {%flinstones}

ハッシュの浅いコピーを作成するだけ%flinstonesで、キーと値のリストに展開されます。一方

$HOH{flinstones} = \%flinstones

両方のハッシュがメモリ内の同じ場所を指すように、ハッシュを参照として渡します。

質問6に関しては、字句スコープの変数はどうなりますか?見てみましょうperldoc -f my

A "my" declares the listed variables to be local (lexically) to
the enclosing block, file, or "eval".

forループはブロックです。つまり、forループ内で宣言された変数はすべて、myそのループに対してローカルであり、そのループの各反復に対してローカルです。つまり、次のようなことをすると、次のようになります。

for my $number (0 .. 3) {
    print "Number is $_. Last number was $last\n";
    my $last = $_;                       # WRONG!
}   # $last goes out of scope here!

Use of uninitialized valueそれはあなたにたくさんの警告を与えるでしょう。スコープを拡張する必要があります。

my $last = "N/A";  # default value
for my $number (0 .. 3) {
    print "Number is $_. Last number was $last\n";
    $last = $_;
}

さて、これがあなたの側で意図的であったかどうかはわかりませんが、これらの質問の両方を1つに組み合わせることができます。

my %HOH;
{ # begin a block to reduce scope of variables
    my %flinstones = (
        husband   => "fred",
        pal       => "barney",
    );
    $HOH{flinstones} = \%flinstones;
} 
... # %flinstones hash is now out of scope, stored only in %HOH
于 2013-03-12T15:26:59.443 に答える
1

私はそれらを「リテラルハッシュ」、「リテラル配列」と呼んでいますが、それぞれ独自のものです。

Perlでは(sの場合を除いて)、ほとんど同じことを知っている必要がtieあります[...]\@xそしてそれ{...}もそう\%hです。これらは両方とも、配列とハッシュへの参照を「構築」します。

質問5では、どちらもあなたが望むことをします。しかし、それをより効率的に行うことができます。2番目の例では、すでに定義されているハッシュへの参照を別のハッシュの値として格納します。最初の例、

$HOH{flinstones} = {%flinstones}

リストコンテキストごとに、アドレスを返すハッシュを作成し、リストに展開します。 したがって、に格納されている別のハッシュに%flintstones正確にコピーされたハッシュを格納します。の変更がこのコピーに影響を与えないことは正しいです。%flintstones%HOH%flintstones

ここにあなたへのちょっとしたアドバイスがあります。インストール、Smart::Comments(SC)、いくつかのテストスクリプトを作成し、STDERRを介して変数の内部をダンプします。あなたは、あなたが見たいと思っているすべての内部を見て、どれだけ多くを学ぶことができるかに驚くでしょう。

SCでの私の経験からのいくつかの教訓は次のとおりです。

  • $Data::Dumper::Maxdepthオブジェクトをダンプする場合は、正の整数値に設定します。Win32::OLE同じOLEオブジェクトの各参照は、トラバースすると異なるPerlオブジェクトのように見える場合があるためです。

  • $_単独でダンプしないでください。何らかの理由で、SCのコードがそれを変更する可能性があります。したがって、常に次のようなことを行います。

    my $a = $_;
    ### $_ : $a
    
  • IOハンドルはダンプしないので、試さないでください。デフォルトの文字列化を使用します。

最後に、を使用してダンプ%flintstonesしなかった場合%HOH、参照が同じであるかどうかを、単純な変数ダンプを介して知る方法がありません。ただし、$Data::Dumper::Maxdepth完全なダンプを取得しないように設定できることを忘れないでください。したがって、2つの参照を部分的にダンプし、参照の単純な汎用Perl文字列化を使用することで、2つの参照が同じであるかどうかをテストできます。

### %flintstones : '' . \%flintstones 
local $Data::Dumper::Maxdepth = 1;
### %HOH

ケースが何であるかを自分で確認することは、Stackoverflowで多くの質問をするよりも早くPerlを学ぶのに役立ちます。

于 2013-03-12T15:20:25.737 に答える
1

構築は値の{ LIST }リストを取得し、それらから匿名ハッシュを構築し(同じリストをで名前付きハッシュに割り当てたかのように%hash = (LIST))、そのハッシュへの参照を返します。

Perlの「匿名ハッシュ」について特別なことは何もありません。それらは他のハッシュと同じように通常のハッシュです。それらを「匿名」にする唯一のことは、それらが(現在)名前を持っていないことです。したがって、参照を使用してそれらを参照することしかできません。

変数名にバインドされることは、ハッシュの固有のプロパティではありません。名前付きハッシュが匿名になる可能性があります(たとえば、名前がスコープ外になった場合)、または匿名ハッシュが名前を取得する可能性もあります。このようなシンボルテーブルの操作

my $hashref = {foo => 'bar'};
our %hash;             # required by "use strict"
*hash = $hashref;
print "$hash{foo}\n";  # prints "bar"

行の後*hash = $hashref、グローバル変数は、以前に名前があったかどうかに関係なく%hash、参照が指すハッシュの新しい名前になります。$hashrefこのメカニズムでは、同じハッシュに複数の名前を付けることもできます。実際、ハッシュ(または他の種類の変数)を独自の名前空間から自分の名前空間にエクスポートできるPerlモジュールは、基本的にこれを内部で実行します。

もちろん、上記のすべては配列にも当てはまります(実際、スカラーにも当てはまります)。


最後の質問に関してはmy、実際には、毎回同じ変数を再利用するのではなく、実行されるたびに新しい字句スコープの変数を作成します。これは実際にはサンプルコードに違いはありませんが、違いが生じる1つの状況は変数がスコープ外になる前に変数への参照を保存した場合です。たとえば、以下は、タブ区切りのデータを配列に解析するためのかなり一般的な方法です。

my @table;
while (my $line = <>) {
    chomp $line;
    my @row = split /\t/, $line;
    # maybe do some manipulation or checks on @row here...
    push @table, \@row;
}

@tableこれをテストすると、同じ配列を指す多くの参照ではなく、このコードが実際に行ごとに異なる(現在は匿名の)配列への参照で満たされていることがわかります。

于 2013-03-12T17:52:10.637 に答える