web-dev-qa-db-ja.com

一部のユーザーがPerlでクラス名を引用するのはなぜですか?

Type::Tiny を見ると、Type::Tiny->newの呼び出しのクラス名が公式ドキュメントで引用されていることがわかります。

my $NUM = "Type::Tiny"->new(
   name       => "Number",
   constraint => sub { looks_like_number($_) },
   message    => sub { "$_ ain't a number" },
);

どうしてこれなの?これは単なるスタイルですか?このプラクティスにはパフォーマンス上の影響がありますか?

12
Evan Carroll

ベアワード(文字列として扱われる)を使用するのではなく、クラス名を明示的に引用することは、構文のあいまいさを回避する3つの方法の1つです。 perlobjドキュメントクラスメソッドの呼び出し セクションで説明します。

Perlでは、パッケージ名とサブルーチン名にベアワードを使用できるため、ベアワードの意味が誤って解釈されることがあります。たとえば、構造Class->new()'Class'->new()またはClass()->new()のいずれかとして解釈できます。英語では、2番目の解釈は「Class()という名前のサブルーチンを呼び出し、次にnew()の戻り値のメソッドとしてClass()を呼び出す」と解釈します。現在の名前空間にClass()という名前のサブルーチンがある場合、Perlは常にClass->new()を2番目の代替として解釈します。つまり、new()の呼び出しによって返されたオブジェクトに対するClass()の呼び出しです。

以下のデモで、この奇妙なケースの動作をご覧ください。

#! /usr/bin/env Perl

use strict;
use warnings;

sub Type::Tiny { print "Returning Bogus\n" ; return "Bogus" }

sub Type::Tiny::new { print "Type::Tiny::new\n" }

sub Bogus::new { print "Bogus::new\n" }

my $class = "Type::Tiny";

Type::Tiny->new;
Type::Tiny::->new;
"Type::Tiny"->new;
$class->new;

その出力は

Bogus 
 Bogus :: new 
 Type :: Tiny :: new 
 Type :: Tiny :: new 
 Type :: Tiny :: newを返す

前述のドキュメントセクションの残りの部分では、予期しない動作や不注意によるエラーから保護する方法を示します。

Perlに最初の解釈(i.e。"Class"という名前のクラスのメソッド呼び出しとして)を使用するように強制するには、2つの方法があります。最初に、::をクラス名に追加できます。

Class::->new()

Perlは常にこれをメソッド呼び出しとして解釈します。

または、クラス名を引用することもできます。

'Class'->new()

もちろん、クラス名がスカラー内にある場合、Perlは正しいことも行います。

my $class = 'Class';
$class->new();

あなたの質問に適用すると、以下の呼び出しはすべて同等です。

Type::Tiny::->new( … );

"Type::Tiny"->new( … );

my $class = "Type::Tiny";
$class->new( … );

最後に::を追加すると、役立つ警告が生成されるという利点があります。誤って入力したとしましょう

Type::Tinny::->new;

それが生み出す

ベアワード「Type :: Tinny ::」は、。/ try行15に存在しないパッケージを参照しています。
パッケージ「Type :: Tinny」を介してオブジェクトメソッド「new」が見つかりません(「Type :: Tinny "?)./try行15。
0
Greg Bacon