Neden bazı kullanıcılar Perl'de sınıf isimleri veriyor?


12

Baktığımda, çağrıdaki Type::Tinysınıf adının Type::Tiny->newresmi belgelerde alıntılandığını görüyorum ,

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

Bu neden? Bu sadece bir tarz mı? Bu uygulama için performans sonuçları var mı?

Yanıtlar:


7

Daha basit bir örnek alın

package Foo { sub new { die 7  } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();

Yukarıdaki örnekte, sabit Foo"Bar" ile çözer, böylece bu nedenle bu çağrılar "Bar"->newdeğil "Foo"->new. Altyordamın çözülmesini nasıl durdurursunuz? Alıntı yapabilirsin.

"Foo"->new();

Performans imalarına gelince, işler bir bareword yerine bir dize kullanılarak daha da kötüleşmez. Tarafından oluşturulan opree O=Deparseaynı olduğunu doğruladım . Genel bir kural olarak, doğruluğa değer veriyorsanız, Sınıf Adlarını alıntılamak daha iyi gibi görünüyor.

Bu Programlama Perlinde (ne yazık ki dolaylı yöntem çağırma bağlamında ) belirtilmiştir.

... size iki şey doğruysa, neredeyse her zaman çıplak bir sınıf adıyla kaçabileceğinizi söyleyeceğiz. İlk olarak, sınıfla aynı adı taşıyan alt program yoktur. ( Start küçük harf gibi alt program adları newve ElvenRingstart büyük harf gibi sınıf adları gibi kuralları izlerseniz , bu hiçbir zaman sorun değildir). İkincisi, sınıf aşağıdakilerden biri ile yüklendi

use ElvenRing;
require ElvenRing;

Bu bildirimlerin her ikisi de, Perl'in bildiklerinin ElvenRing, geçerli pakette kendi alt programınızı bildirmiş olsanız bile new, sınıf adından önce olduğu gibi herhangi bir çıplak adı ElvenRingyöntem çağrısı olarak yorumlanmaya zorlayan bir modül adı olmasını sağlar new.

Ve bu mantıklı: Buradaki karışıklık ancak alt programlarınız (genellikle küçük harf) bir sınıfla (genellikle büyük harf) aynı ada sahipse gerçekleşebilir. Bu, yalnızca yukarıdaki adlandırma kuralını ihlal ederseniz gerçekleşebilir.

TLDR; Eğer onları biliyorsanız ve dağınıklığa karşı doğruluğa değer veriyorsanız muhtemelen sınıf adlarınızı alıntılamak iyi bir fikir olabilir.

Yan not: alternatif olarak, bir bareword'un bir işleve çözünürlüğünü ::, sonuna a , örneğin üstüne yapıştırılarak durdurabilirsiniz Foo::->new.


Reddit'teki Ginnz'e bunu işaret ettiği için ve yorum için Toby Inkster'a teşekkürler (ilk okumada bana mantıklı gelmedi).


2
Veya Foo::->newikegami'den öğrendiğim gibi.
mafya

@mob yea, Perl kitabında da (açıkça), oraya koyup koymamam gerektiğinden emin değil misiniz? lol.
Evan Carroll

@mob Bunu da dipnot olarak ekledim. Yine de hoşuma gittiğinden emin değilim.
Evan Carroll

1
Foo::Foomevcut bir paket değilse uyarması avantajına sahiptir
ikegami

1
Deneyin :: Tiny, Foo'dan daha iyi bir örnektir. Kodunuzu kullanarak Foo->paketinizde böyle bir altyordam olmadığını bilmeniz beklenebilir. Ancak Try :: Tiny ve diğer cpan / diğer harici kaynaklı modülleri kullanıyorsanız, bunlardan birinin bir Try paketi kullanıp kullanmadığını ve eğer öyleyse, içinde bir Tiny sub varsa kim söyleyebilir?
19:10, ysth

0

Bir bareword (dize olarak ele alınır) kullanmak yerine sınıf adını açıkça belirtmek, sözdizimsel belirsizliği önlemenin üç yolundan biridir. Çağırma Sınıf Yöntemler bölümünde perlobj belgelerine açıklar.

Perl, paket isimleri ve altyordam isimleri için barewordları kullanmanıza izin verdiği için, bazen bir bareword'un anlamını yanlış yorumlar. Örneğin, yapı Class->new()ya 'Class'->new()da olarak yorumlanabilir Class()->new(). İngilizce'de, bu ikinci yorum “adlı bir alt programı Class()çağır, sonra new()dönüş değerinde bir yöntem olarak çağır Class(). Class()Geçerli ad alanında bir alt yordam varsa , Perl her zaman Class->new()ikinci alternatif olarak yorumlanır : çağrıyla new()döndürülen nesneye yapılan çağrı Class().

Aşağıdaki demoda bu garip durumu iş başında görün.

#! /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;

Çıkışı

Geri dönen sahte
Sahte :: Yeni
Tip :: Minik :: Yeni
Tip :: Minik :: Yeni
Tip :: Minik :: Yeni

Yukarıda belirtilen dokümantasyon bölümünün geri kalanı, şaşırtıcı davranışlara veya yanlışlıkla yapılan hatalara karşı nasıl korunacağını gösterir.

Perl'i ilk yorumu ( yani , adlandırılan sınıfta bir yöntem çağrısı olarak "Class") iki şekilde kullanmaya zorlayabilirsiniz . İlk olarak, ::sınıf adına bir ekleyebilirsiniz :

Class::->new()

Perl bunu her zaman bir yöntem çağrısı olarak yorumlayacaktır.

Alternatif olarak, sınıf adını da verebilirsiniz:

'Class'->new()

Tabii ki, sınıf adı skalerdeyse Perl de doğru şeyi yapacaktır:

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

Sorunuza başvurduğunuzda, aşağıdaki aramaların tümü eşdeğerdir.

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

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

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

Ekleme ::ucuna yararlı bir uyarı üretme avantajına sahiptir. Yanlışlıkla yazdığınızı söyleyin

Type::Tinny::->new;

Üreten

Bareword "Type :: Tinny ::", ./try satır 15'teki mevcut olmayan paketi ifade eder.
"New" paketi üzerinden "Type :: Tinny" nesne yöntemini bulamıyor (belki "Type :: Tinny" dosyasını yüklemeyi unuttunuz?) ./Try line 15.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.