1. ホーム
  2. スクリプト・コラム
  3. パール

Sigilsを使ったPerl5とPerl6の比較

2022-01-08 15:05:07

Perl 5とPerl 6の違いをSigls(変数名の先頭の記号)で見ていきます。

概要

まず、Perl 5とPerl 6のSigilsの概要から説明します:。

{を使用します。 ハッシュ  {を使用します。 サブルーチン  {を使用します。
シンボルマーク パール5 パール6
@   アレイ  位置づけ
%   アソシアティブ
呼び出し可能
スカラー  項目
タイプグロブ N

(配列と位置の比較)

perl5で配列を定義する場合、スカラー値の拡張可能なリストを作成し、それにシジルで名前を付けることができます。@:

# Perl 5
my @foo = (1,2,3);
push @foo, 42;
say for @foo; # 1␤2␤3␤42␤

perl 6 で配列を定義する場合、新しい列オブジェクトを作成し、それにバインドしてレキシカルパッドにその名前のエントリを入力します。このように

# Perl 6
my @foo = 1,2,3;
push @foo, 42;
.say for @foo; # 1␤2␤3␤42␤

は機能的にはPerl 5と同じですが、1行目がforになっています。

# Perl 6
my @foo := Array.new( 1,2,3 );

/{br

これは、新しいカラム・オブジェクトを語彙定義の名前にバインドする(割り当てるのではない)ものである。foo.this, this, that, that @perl 6 の印は、型制約を表しています。この印を使って何かを lexpad エントリーにバインドしたい場合、それは位置的な役割を果たすものでなければなりません。クラスが役割を果たすかどうかを判断するのは、SmartMatchを使えば難しいことではありません。

# Perl 6
say Array ~~ Positional; # True

Perl 6 のすべての配列は、Perl 5 の bound array で実装されていると考えてよいでしょう。そして、これは真実から遠いものではありません。詳細は省きますが、簡単な例でこの点を明らかにできるかもしれません。this, this, that, and the at-POS メソッドは位置の役割の実装である。このメソッドは、1つの要素にアクセスする必要があるたびに呼び出されます。だから、あなたが書くとき

say @a[42]



/{br

実行中です。

say @a.AT-POS(42)

もちろん、これだけでなく、もっと .

ポジション・ロールを実行するためにクラスをバインドしなければならない代わりに、特有な構文を使用することができます。つまり、書かなければならない代わりに

# Perl 6
my @a := YourClass.new( 1,2,3 );

/{br

書くことができます。

# Perl 6
my @a is YourClass = 1,2,3;

Perl 5 では、束縛された配列は「通常の」配列よりはるかに遅いです。Perl 6 では、配列は起動時に同様に遅くなります。幸いなことに、rakudo perl 6 はインライン化と "jiting" によってホットコードパスを最適化します。オペコードは可能な限り機械語コードを使用します。(これはオプティマイザの進歩のおかげで、より速く、より頻繁に、より良く実現されています)。

%(ハッシュ vs. 連想)

Perl 6 のハッシュの実装は配列に似ています。(Perl 5 の用語を使って)バインドハッシュと考えることもできます。ハッシュの実装には、配列の実装に使われるpositionの役割の代わりに、associativeの役割を使う必要があります。

ここでも、簡単な例が役に立つかもしれません。重要なアプローチは、バインディングロールを実装することである。このメソッドは、特定のキーの値にアクセスする必要があるときに呼び出されます。ですから、あなたが書くとき

say %h<foo>

実行中です。

say %h.AT-KEY("foo")



もちろん、他にもさまざまな方法を実装することができます。

サブルーチンと呼び出し可能の比較

Perl 5 では、呼び出し可能な実行コードの種類はサブルーチンだけです。

# Perl 5
sub frobnicate { shift ** 2 }

また、サブルーチンを引数として渡すには、そのサブルーチンへの参照を取得する必要があります。

# Perl 5
sub do_stuff_with {
 my $lambda = shift;
 &$lambda(shift);
}
say do_stuff_with( \&frobnicate, 42 ); # 1764

Perl 6 では、複数のタイプのオブジェクトが実行可能コードを含むことができます。これらのオブジェクトに共通するのは、交換可能なロールを消費することです。

Sgilは、%signalとbindingロール、@signalとlocationロールのように、実行可能なredememableロールにバインディングを強制します。Perl 5に非常に近い例を挙げます。

# Perl 6
my &foo = sub ($a,$b) { $a + $b }
say foo(42,666); # 708

なお、変数に&Sigilがあっても、その変数のコードを実行するために使う必要がないことは分かっているはずです。実際、最初から始めると、普通の人がサブ宣言するのと比べてほとんど違いがない。

# Perl 6
BEGIN my &foo = sub ($a,$b) { $a + $b } # same as sub foo()

Perl 5と異なり、Perl 6ではスタートブロックはブロックのない単一のステートメントにすることができるので、レキシカルスコープを外部と共有することができます。ただし、これについては今後の記事で詳しく説明します。

変数の使用は、何かがまだ知られていない場合でも、コンパイル時に実行可能であることを知るための方法です。

コードの一部を実行するように設定する方法は他にもあります。

# Perl 6
my &boo = -> $a, $b { $a + $b } # same, using a Block with a signature
my &goo = { $^a + $^b } # same, using auto-generated signature
my &woo = * + *; # same, using Whatever currying

また、シグネチャの内部で&を使い、着呼側がそこで何を実行させたいかを示すことも可能である。ここで、このセクションの最初の2つのコード例に戻る。

# Perl 5
sub frobnicate { shift ** 2 }
sub do_stuff_with {
 my $lambda = shift;
 &$lambda(shift);
}
say do_stuff_with( \&frobnicate, 42 ); # 1764

# Perl 6
sub frobnicate { $^a ** 2 }
sub do-stuff-with(&lambda, $param) { lambda($param) }
say do-stuff-with( &frobnicate, 42 ); # 1764

なお、Perl 6では、参照を受け取る必要はなく、単に&などのコードオブジェクトを引数として渡すことができます。

$(スカラー vs. アイテム)

シギルは@、%、&シギルと比べると、少し地味な存在です。型チェックをしないので、どんなオブジェクトの型にも束縛される。したがって、あなたが書くとき

# Perl 6
my $answer = 42;

このようなことが起こります。

# Perl 6
my $answer := Scalar.new(42);

非常に低いレベルは別として。だから一応言っておきますが、このコードはうまくいきません。スカラー変数を宣言するとこうなるのです。

Perl6では、$はその中に入っているものはすべて1つのアイテムとして扱われるべきものであるとも述べています。したがって、スカラーコンテナに列挙されたオブジェクトであっても、反復処理が必要な場合には単一のアイテムとして扱われます:。

# Perl 6
my @foo = 1,2,3;
my $bar = Array.new(1,2,3); # alternately: [1,2,3]
.say for @foo; # 1␤2␤3␤
.say for $bar; # [1 2 3]

後者の場合は1回の繰り返し、前者の場合は3回の繰り返しにしか適用されないことに注意してください。何かを反復するかどうかは、適切な紋章を前につけることで示すことができる。

# Perl 6
.say for $@foo; # [1 2 3] , consider the array as an item
.say for @$bar; # 1␤2␤3␤ , consider the scalar as a list

しかし、おそらくこれではノイズの中に入り込みすぎてしまうだろう。幸いなことに、より詳細な同等のものがあります。

# Perl 6
.say for @foo.item; # [1 2 3] , consider the array as an item
.say for $bar.list; # 1␤2␤3␤ , consider the scalar as a list

* (タイプグローブズ)

お気づきのように、Perl 6 には *sigil やタイプ・グロブという概念はありません。どのようなタイプのグロブか分からなくても、気にする必要はありません。Perl 5の複雑なシンボルテーブルを知らなくても、十分やっていけます(次の段落も読み飛ばしても大丈夫です)。

  • Perl 6では、sigilはシンボルテーブルに格納される名前の一部ですが、Perl 5では、名前はシグナルなしで格納されます。例えば、Perl 5では、$fooがプログラム内で参照された場合、コンパイラはfooを(sigilなしで)調べ、次に関連情報(これは配列です)を取得し、必要な$sigilインデックスを探します。Perl 6では、$fooが参照されると、コンパイラは$fooを調べ、そのキーに関連する情報を直接使用します。

Perl 6でパラメータを表すのに使われるSLurpyとPerl 5のType Gulb SIGLを混同しないでください、両者は何の関係もないのです。

シギレス変数

Perl 5 は符号なし変数をサポートしていません(左値のサブルーチンを除いてですが、これは実に不器用です)。

Perl 6 もシギレス変数を直接サポートしていませんが、プレフィックス・バックスラッシュ( \)を介した定義での名前をサポートしています。

# Perl 6
my \the-answer = 42;
say the-answer; # 42

代入の右辺は定数なので、これは本質的に定数を定義しているのと同じです:。

# Perl 5
use constant the_answer => 42;
say the_answer; # 42
# Perl 6
my constant the-answer = 42;
say the-answer; # 42

定義の右側が別のものであれば、もっと面白いのですが。まるでコンテナのようだ! これは、次のような構文のトリックを使って符号なし変数を使えるようにするものです。

# Perl 6
my \foo = $ = 41; # a sigilless scalar variable
my \bar = @ = 1,2,3,4,5; # a sigilless array
my \baz = % = a => 42, b => 666; # a sigilless hash

これは基本的に匿名のレキシカルエンティティ(スカラー、配列、ハッシュ)を作成し、通常のセマンティクスで初期化し、結果のオブジェクト(スカラーコンテナ配列オブジェクト、ハッシュオブジェクト)の名前をバインドするもので、Perl 6の他の通常の変数として使用できる。

# Perl 6
say ++foo; # 42
say bar[2]; # 3
bar[2] = 42;
say bar[2]; # 42
say baz<a b>; # (42 666)

もちろん、こうすることによって、特に補間におけるすべての利点を失うことになる。その場合、補間の際に必ず{ }を使用する必要があります。

# Perl 6
say "The answer is {the-answer}. "; # The answer is 42.

Perl 5 のほとんどのバージョンでは、これに相当するものはもっと問題です。

# Perl 5
say "The answer is @{[the_answer]}. "; # The answer is 42.

これらの変数をPerl5の概念で考えると、Perl6ではすべての変数が束縛された変数と考えることができます。このため、もともと少し遅いのです。しかし、いくつかのベンチマークでは、ランタイムの最適化とホットコードパスJIT化(点からマシンコードへ)により、Perl 5の変数よりも高速になりました。

Perl6では、特定のオブジェクトを生成する代わりに、その名前がバインドされているオブジェクトに適用される型制約を指示します。この点、$Sigilは型制約がないため、異なります。

接頭辞の@と$は、それぞれ実現と項目化を示しますが、.listと.itemを使用することで、実現と項目化の両方が可能になります。代わりにプロジェクトメソッドを使用します。

Perl6では、ちょっとした構文の工夫で、変数名にシグルがなくてもプログラミングが可能です。

まとめる

以上が本記事の内容の全てです、皆様の勉強やお仕事に本記事の内容が一定の参考学習価値を持つことを願っています、BinaryDevelopをよろしくお願いします。もっと詳しく知りたい方は、以下のリンク先をご確認ください。