Perl Language
変数
サーチ…
構文
- 私の#字句宣言
- #グローバル宣言
- $ foo#スカラー
- @foo#配列
- $#foo#配列最後のインデックス
- %foo#ハッシュ
- $ {$ foo}#スカラー・リファレンス
- @ {$ foo}#配列参照解除
- $#{$ foo}#Array-DeRef Last-Index
- %{$ foo}#ハッシュ逆参照
- $ foo [$ index]#配列のインデックスを取得する
- $ {$ foo} [$ index]#配列の参照を解除してインデックスを取得します。
- $ foo - > [$ index]#配列参照解除とインデックス取得(簡体字)
- $ foo {$ key}#キーのハッシュ値を取得する
- $ {$ foo} {$ key}#ハッシュを解除してキーの値を取得する
- $ foo - > {$ key}#ハッシュを参照解除してキーの値を取得する(簡体字)
- \ $ x#Scalarへの参照
- \ @x#配列への参照
- \%x#ハッシュへの参照
- = []#匿名配列への参照(インライン)
- = {}#匿名ハッシュへの参照(インライン)
スカラー
スカラーはPerlの最も基本的なデータ型です。彼らはsigil $
マークされ、3つのタイプのうちの1つの単一の値を保持します。
- 数 (
3
、42
、3.141
、等) - 文字列 (
'hi'
、'hi'
"abc"
'hi'
など) - 変数への参照 (他の例を参照)。
my $integer = 3; # number
my $string = "Hello World"; # string
my $reference = \$string; # reference to $string
Perlは 、特定のオペレータの期待に基づいて、オンザフライで数字と文字列を変換します。
my $number = '41'; # string '41'
my $meaning = $number + 1; # number 42
my $sadness = '20 apples'; # string '20 apples'
my $danger = $sadness * 2; # number '40', raises warning
文字列を数値に変換するとき、Perlは可能な限り文字列の先頭から多くの桁を取ります。したがって、最後の行では20 apples
が20
に変換されます。
スカラーの内容を文字列または数値として扱うかどうかに基づいて、異なる演算子を使用する必要があります。それらを混ぜないでください。
# String comparison # Number comparison
'Potato' eq 'Potato'; 42 == 42;
'Potato' ne 'Pomato'; 42 != 24;
'Camel' lt 'Potato'; 41 < 42;
'Zombie' gt 'Potato'; 43 > 42;
# String concatenation # Number summation
'Banana' . 'phone'; 23 + 19;
# String repetition # Number multiplication
'nan' x 3; 6 * 7;
数字に文字列演算を使用しようとしても警告は出ません。数値以外の文字列に対して数値演算を使用しようとすると、 'inf'
、 'nan'
、 '0 but true'
ような数字以外の文字列は数値として数えられることに注意してください。
配列
配列には順序付けられた値のシーケンスが格納されます。コンテンツをインデックスでアクセスしたり、繰り返したりできます。値は、入力した順序で保持されます。
my @numbers_to_ten = (1,2,3,4,5,6,7,8,9,10); # More conveniently: (1..10)
my @chars_of_hello = ('h','e','l','l','o');
my @word_list = ('Hello','World');
# Note the sigil: access an @array item with $array[index]
my $second_char_of_hello = $chars_of_hello[1]; # 'e'
# Use negative indices to count from the end (with -1 being last)
my $last_char_of_hello = $chars_of_hello[-1];
# Assign an array to a scalar to get the length of the array
my $length_of_array = @chars_of_hello; # 5
# You can use $# to get the last index of an array, and confuse Stack Overflow
my $last_index_of_array = $#chars_of_hello; # 4
# You can also access multiple elements of an array at the same time
# This is called "array slice"
# Since this returns multiple values, the sigil to use here on the RHS is @
my @some_chars_of_hello = @chars_of_hello[1..3]; # ('H', 'e', 'l')
my @out_of_order_chars = @chars_of_hello[1,4,2]; # ('e', 'o', 'l')
# In Python you can say array[1:-1] to get all elements but first and last
# Not so in Perl: (1..-1) is an empty list. Use $# instead
my @empty_list = @chars_of_hello[1..-1]; # ()
my @inner_chars_of_hello = @chars_of_hello[1..$#chars_of_hello-1]; # ('e','l','l')
# Access beyond the end of the array yields undef, not an error
my $undef = $chars_of_hello[6]; # undef
配列は変更可能です:
use utf8; # necessary because this snippet is utf-8
$chars_of_hello[1] = 'u'; # ('h','u','l','l','o')
push @chars_of_hello, ('!', '!'); # ('h','u','l','l','o','!','!')
pop @chars_of_hello; # ('h','u','l','l','o','!')
shift @chars_of_hello; # ('u','l','l','o','!')
unshift @chars_of_hello, ('¡', 'H'); # ('¡','H','u','l','l','o','!')
@chars_of_hello[2..5] = ('O','L','A'); # ('¡','H','O','L','A',undef,'!') whoops!
delete $chars_of_hello[-2]; # ('¡','H','O','L','A', '!')
# Setting elements beyond the end of an array does not result in an error
# The array is extended with undef's as necessary. This is "autovivification."
my @array; # ()
my @array[3] = 'x'; # (undef, undef, undef, 'x')
最後に、配列の内容をループすることができます:
use v5.10; # necessary for 'say'
for my $number (@numbers_to_ten) {
say $number ** 2;
}
ブール値として使用すると、配列が空でない場合はtrueになります。
ハッシュ
ハッシュはルックアップテーブルとして理解できます。それぞれのキーを指定することによって、その内容にアクセスすることができます。キーは文字列でなければなりません。そうでなければ、文字列に変換されます。
ハッシュを単純に既知の鍵にすると、それはあなたにその値を提供します。
# Elements are in (key, value, key, value) sequence
my %inhabitants_of = ("London", 8674000, "Paris", 2244000);
# You can save some typing and gain in clarity by using the "fat comma"
# syntactical sugar. It behaves like a comma and quotes what's on the left.
my %translations_of_hello = (spanish => 'Hola', german => 'Hallo', swedish => 'Hej');
次の例では、大括弧とsigilに注意してください。 $hash{key}
を使用して%hash
要素にアクセスし$hash{key}
これは、必要な値がスカラーであるためです。キーを引用するのは良い習慣だと考えている人もいれば、視覚的に騒々しいこのスタイルを見つけている人もいます。クォートは、 $hash{'some-key'}
ような式と間違える可能性のあるキーに対してのみ必要です
my $greeting = $translations_of_hello{'spanish'};
デフォルトではPerlは文字列としてベアワードを使用しようとしますが、 +
修飾子はPerlにキーを補間すべきではなく、実行結果をキーとして実行するように指示するためにも使用できます:
my %employee = ( name => 'John Doe', shift => 'night' );
# this example will print 'night'
print $employee{shift};
# but this one will execute [shift][1], extracting first element from @_,
# and use result as a key
print $employee{+shift};
配列と同様に、複数のハッシュ要素に同時にアクセスすることができます。これはハッシュスライスと呼ばれます 。結果の値はリストなので、 @
sigil:
my @words = @translations_of_hello{'spanish', 'german'}; # ('Hola', 'Hallo')
ハッシュのキーを反復処理するkeys
keys
ランダムな順序で項目を返します。あなたが望むなら、 sort
と組み合わせてください。
for my $lang (sort keys %translations_of_hello) {
say $translations_of_hello{$lang};
}
前の例のように実際にキーが必要ない場合、 values
はハッシュの値を直接返します。
for my $translation (values %translations_of_hello) {
say $translation;
}
each
whileループを使用して、ハッシュを反復処理することもできます。このようにして、キーと値の両方を同時に取得し、別々の値を参照する必要はありません。しかしながら、 each
が誤ったやり方で壊れるので 、その使用は推奨されません。
# DISCOURAGED
while (my ($lang, $translation) = each %translations_of_hello) {
say $translation;
}
設定されていない要素へのアクセスは、エラーではなくundefを返します。
my $italian = $translations_of_hello{'italian'}; # undef
map
とリストの平坦化を使用して配列からハッシュを作成することができます。これは、値が@elems
かどうかを素早く確認するなど、値のセットを作成する一般的な方法@elems
。この操作は通常、O(n)時間(つまり要素の数に比例する)が必要ですが、リストをハッシュにすることで一定時間(O(1))で実行できます。
@elems = qw(x y x z t);
my %set = map { $_ => 1 } @elems; # (x, 1, y, 1, t, 1)
my $y_membership = $set{'y'}; # 1
my $w_membership = $set{'w'}; # undef
これには何らかの説明が必要です。 @elems
の内容は@elems
に読み込まれ、 map
によって処理されmap
。 map
は入力リストの各値に対して呼び出されるコードブロックを受け取ります。要素の値は$_
で使用可能です。私たちのコードブロックは、各入力要素の2つのリスト要素を返します: $_
、入力要素、そして1
、ちょうどある値。リスト平坦化を説明すると、その結果はmap { $_ => 1 } @elems
はqw(xyxzt)
を(x => 1, y => 1, x => 1, z => 1, t => 1)
。
これらの要素がハッシュに割り当てられると、奇数要素はハッシュキーになり、要素もハッシュ値になります。リスト内でキーが複数回指定されてハッシュに割り当てられると、 最後の値が優先されます。これは効果的に重複を破棄します。
リストをハッシュに変換するより速い方法は、ハッシュスライスへの割り当てを使用します。 x
演算子を使用して単一要素のリスト(1)
に@elems
のサイズを@elems
ため、左側のスライスの各キーに1
値があります。
@elems = qw(x y x z t);
my %set;
@set{@elems} = (1) x @elems;
以下のハッシュのアプリケーションは、ハッシュとリストを名前のついた関数の引数を実装するために交換可能に使うこともできるという事実を利用しています。
sub hash_args {
my %args = @_;
my %defaults = (foo => 1, bar => 0);
my %overrides = (__unsafe => 0);
my %settings = (%defaults, %args, %overrides);
}
# This function can then be called like this:
hash_args(foo => 5, bar => 3); # (foo => 5, bar => 3, __unsafe ==> 0)
hash_args(); # (foo => 1, bar => 0, __unsafe ==> 0)
hash_args(__unsafe => 1) # (foo => 1, bar => 0, __unsafe ==> 0)
ブール値として使用すると、ハッシュ値は空でなければ真です。
スカラーリファレンス
参照は、他のデータを参照するスカラ変数( $
始まるもの)です。
my $value = "Hello";
my $reference = \$value;
print $value; # => Hello
print $reference; # => SCALAR(0x2683310)
参照先のデータを取得するには、参照先のデータを参照解除します。
say ${$reference}; # Explicit prefix syntax
say $$reference; # The braces can be left out (confusing)
新しいpostfixデリファレンス構文は、デフォルトでv5.24から利用可能です
use v5.24;
say $reference->$*; # New postfix notation
この「参照されていない値」は元の変数のように変更できます。
${$reference} =~ s/Hello/World/;
print ${$reference}; # => World
print $value; # => World
参照は常にtruthyある-それが参照値(等falsy場合でも0
または""
)。
Scalar Referenceが必要な場合は次のようになります。
文字列を関数に渡し、その文字列を戻り値なしに変更する必要があります。
Perlは、関数の中のある点で大きな文字列の内容を暗黙的にコピーすることを明示的に避けたいとします(特に、コピーオンライト文字列を持たない古いPerlに関連します)
コンテンツを伝える文字列から、特定の意味を持つ文字列のような値を明確にする場合は、次のようにします。
- ファイルの内容からファイル名を明確にする
- 返されたエラー文字列から返された内容を明確にする
軽量のインサイドアウトオブジェクトモデルを実装したい場合、呼び出しコードに渡されるオブジェクトにはユーザーが表示できるメタデータは含まれません。
our %objects; my $next_id = 0; sub new { my $object_id = $next_id++; $objects{ $object_id } = { ... }; # Assign data for object my $ref = \$object_id; return bless( $ref, "MyClass" ); }
配列参照
配列参照は、配列を参照するスカラ( $
)です。
my @array = ("Hello"); # Creating array, assigning value from a list
my $array_reference = \@array;
これらは、以下のようにより短く作成できます。
my $other_array_reference = ["Hello"];
アレイ参照を変更/使用するには、最初に参照解除する必要があります。
my @contents = @{ $array_reference }; # Prefix notation
my @contents = @$array_reference; # Braces can be left out
新しいpostfixデリファレンス構文は、デフォルトでv5.24から利用可能です
use v5.24;
my @contents = $array_reference->@*; # New postfix notation
arrayrefの内容にインデックスでアクセスするときには、 ->
構文的な砂糖を使うことができます。
my @array = qw(one two three); my $arrayref = [ qw(one two three) ]
my $one = $array[0]; my $one = $arrayref->[0];
配列とは異なり、arrayrefsはネストできます。
my @array = ( (1, 0), (0, 1) ) # ONE array of FOUR elements: (1, 0, 0, 1)
my @matrix = ( [1, 0], [0, 1] ) # an array of two arrayrefs
my $matrix = [ [0, 1], [1, 0] ] # an arrayref of arrayrefs
# There is no namespace conflict between scalars, arrays and hashes
# so @matrix and $matrix _both_ exist at this point and hold different values.
my @diagonal_1 = ($matrix[0]->[1], $matrix[1]->[0]) # uses @matrix
my @diagonal_2 = ($matrix->[0]->[1], $matrix->[1]->[0]) # uses $matrix
# Since chained []- and {}-access can only happen on references, you can
# omit some of those arrows.
my $corner_1 = $matrix[0][1]; # uses @matrix;
my $corner_2 = $matrix->[0][1]; # uses $matrix;
ブール値として使用すると、参照は常に真です。
ハッシュ参考文献
ハッシュ参照は、ハッシュのデータを含むメモリ位置へのポインタを含むスカラです。スカラーはハッシュ自体を直接指しているので、サブルーチンに渡されるとき、ハッシュに対する変更は通常のハッシュと同じようにサブルーチンに対してローカルではなく、グローバルになります。
まず、通常のハッシュをサブルーチンに渡してそこで変更するときに何が起こるかを調べてみましょう。
use strict;
use warnings;
use Data::Dumper;
sub modify
{
my %hash = @_;
$hash{new_value} = 2;
print Dumper("Within the subroutine");
print Dumper(\%hash);
return;
}
my %example_hash = (
old_value => 1,
);
modify(%example_hash);
print Dumper("After exiting the subroutine");
print Dumper(\%example_hash);
結果は:
$VAR1 = 'Within the subroutine';
$VAR1 = {
'new_value' => 2,
'old_value' => 1
};
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
'old_value' => 1
};
サブルーチンを終了すると、ハッシュは変更されないままであることに注意してください。ハッシュ自体ではなく、ハッシュのコピーを渡したので、それに対するすべての変更は、変更サブルーチンに対してローカルでした。
これと比較して、ハッシュリファレンスを渡すと、そのアドレスを元のハッシュに渡すので、サブルーチン内で行われた変更はすべて元のハッシュになります。
use strict;
use warnings;
use Data::Dumper;
sub modify
{
my $hashref = shift;
# De-reference the hash to add a new value
$hashref->{new_value} = 2;
print Dumper("Within the subroutine");
print Dumper($hashref);
return;
}
# Create a hashref
my $example_ref = {
old_value => 1,
};
# Pass a hashref to a subroutine
modify($example_ref);
print Dumper("After exiting the subroutine");
print Dumper($example_ref);
これにより、次の結果が得られます。
$VAR1 = 'Within the subroutine';
$VAR1 = {
'new_value' => 2,
'old_value' => 1
};
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
'new_value' => 2,
'old_value' => 1
};
タイプグロブ、型グロブのリファレンス、ファイルハンドルと定数
typeglob *foo
は、 $foo
、 @foo
$foo
、 $foo
、 &foo
などのグローバル変数の内容を参照します。ハッシュのようにアクセスしてシンボルテーブルを直接操作できます(悪い!)。
use v5.10; # necessary for say
our $foo = "foo";
our $bar;
say ref *foo{SCALAR}; # SCALAR
say ${ *foo{SCALAR} }; # bar
*bar = *foo;
say $bar; # bar
$bar = 'egg';
say $foo; # egg
typeglobは、ファイルを扱うときにより一般的に扱われます。 open
非グローバルファイルハンドルを作成するように求められたときに、例えば、型グロブへの参照を生成します。
use v5.10; # necessary for say
open(my $log, '> utf-8', '/tmp/log') or die $!; # open for writing with encoding
say $log 'Log opened';
# You can dereference this globref, but it's not very useful.
say ref $log; # GLOB
say (*{$log}->{IO} // 'undef'); # undef
close $log or die $!;
Typeglobsはグローバルな読み取り専用変数の作成にもuse constant
できますが、 use constant
は広く使用されています。
# Global constant creation
*TRUE = \('1');
our $TRUE;
say $TRUE; # 1
$TRUE = ''; # dies, "Modification of a read-only value attempted"
# use constant instead defines a parameterless function, therefore it's not global,
# can be used without sigils, can be imported, but does not interpolate easily.
use constant (FALSE => 0);
say FALSE; # 0
say &FALSE; # 0
say "${\FALSE}"; # 0 (ugh)
say *FALSE{CODE}; # CODE(0xMA1DBABE)
# Of course, neither is truly constant when you can manipulate the symbol table...
*TRUE = \('');
use constant (EVIL => 1);
*FALSE = *EVIL;
Sigils
Perlにはいくつかの記号があります:
$scalar = 1; # individual value
@array = ( 1, 2, 3, 4, 5 ); # sequence of values
%hash = ('it', 'ciao', 'en', 'hello', 'fr', 'salut'); # unordered key-value pairs
&function('arguments'); # subroutine
*typeglob; # symbol table entry
これらは見た目のように見えますが、そうではありません:
\@array; # \ returns the reference of what's on the right (so, a reference to @array)
$#array; # this is the index of the last element of @array
そんなに傾けるべきであれば、括弧の後に中括弧を使うことができます。場合によっては、これにより可読性が向上します。
say ${value} = 5;
さまざまな種類の変数を定義するために異なる記号を使用していますが、使用する記号に基づいて同じ変数にさまざまな方法でアクセスできます。
%hash; # we use % because we are looking at an entire hash
$hash{it}; # we want a single value, however, that's singular, so we use $
$array[0]; # likewise for an array. notice the change in brackets.
@array[0,3]; # we want multiple values of an array, so we instead use @
@hash{'it','en'}; # similarly for hashes (this gives the values: 'ciao', 'hello')
%hash{'it','fr'}; # we want an hash with just some of the keys, so we use %
# (this gives key-value pairs: 'it', 'ciao', 'fr', 'salut')
これは特に参考になります。参照される値を使用するには、一緒に記号を組み合わせることができます。
my @array = 1..5; # This is an array
my $reference_to_an_array = \@array; # A reference to an array is a singular value
push @array, 6; # push expects an array
push @$reference_to_an_array, 7; # the @ sigil means what's on the right is an array
# and what's on the right is $reference_to_an_array
# hence: first a @, then a $
おそらくこれについて考えてみると、それほど混乱のない方法です。前に見たように、中括弧を使用して、あるものの右側にあるものを囲むことができます。だから、 @{}
は配列参照をとり、参照配列を与えるものと考えることができます。
# pop does not like array references
pop $reference_to_an_array; # ERROR in Perl 5.20+
# but if we use @{}, then...
pop @{ $reference_to_an_array }; # this works!
わかるように、 @{}
実際に式を受け入れます:
my $values = undef;
say pop @{ $values }; # ERROR: can't use undef as an array reference
say pop @{ $values // [5] } # undef // [5] gives [5], so this prints 5
...と同じトリックも他のsigilsのために働く。
# This is not an example of good Perl. It is merely a demonstration of this language feature
my $hashref = undef;
for my $key ( %{ $hashref // {} } ) {
"This doesn't crash";
}
... sigilの "議論"が単純なら、中括弧を離れたままにすることができます。
say $$scalar_reference;
say pop @$array_reference;
for keys (%$hash_reference) { ... };
物事は過度に贅沢になることがあります。これはうまく動作しますが、Perlに責任を持って対応してください。
my %hash = (it => 'ciao', en => 'hi', fr => 'salut');
my $reference = \%hash;
my $reference_to_a_reference = \$reference;
my $italian = $hash{it}; # Direct access
my @greets = @$reference{'it', 'en'}; # Dereference, then access as array
my %subhash = %$$reference_to_a_reference{'en', 'fr'} # Dereference ×2 then access as hash
ほとんどの通常の使用では、サブルーチンを使わずにサブルーチン名を使うことができます。 (sigilのない変数は、通常、 "barewords"と呼ばれます。) &
sigilは、限られた数のケースでのみ有用です。
サブルーチンへの参照を作成する:
sub many_bars { 'bar' x $_[0] } my $reference = \&many_bars; say $reference->(3); # barbarbar
プロトタイプを無視して関数を呼び出す
gotoと組み合わせると、現在の呼び出しフレームが呼び出し元に置き換えられているやや奇妙な関数呼び出しです。 Linuxの
exec()
API呼び出しを考えてみましょう。