2010-02-24 14 views
5

$ i = 1; ($ i < 3) { yazdırma < < "EOT"; def px $ i = yeni E (kullanıcı) (px $ i.hasErrors()) { println "$ {px $ i.name}/$ {px $ i.empr.to} Tamam" }Perl dizesinde kod benzeri şeylerden nasıl kurtulabilirim?

Can't call method "px" without a package or object reference at borrar.pl line 3.

nasıl olursa "kaçış" olabilir:

EOT 

    $i++; 
} 

hata üretir?

Teşekkürler.

+0

Bunun ne olduğunu bilmiyorum, ama kesinlikle Perl değil. – friedo

+0

Baskı/EOT içerisindeki kod kesinlikle değil, ancak işin aslı, baskıya/EOT'un içine yazılacak olana ihtiyacım var; Aslında "if" bloğunu kaldırırsam, mükemmel çalışır. – xain

+0

Doh - Eşyaların büyük bir heredokta olduğu gerçeğini kaçırdım. – friedo

cevap

6

Bu kodun başarması gerektiğini söylemek zor, ama belki de println deyimindeki dış dolar işaretlerinin son çıktıda korunmasını istiyorsunuz? O değişiklikle

println "\${px$i.name}/\${px$i.empr.to} OK" 

, görüyorum hatasız çıkışı:

def px1 = new E(user) 
if (!px1.hasErrors()) { 
     println "${px1.name}/${px1.empr.to} OK" 
} 

def px2 = new E(user) 
if (!px2.hasErrors()) { 
     println "${px2.name}/${px2.empr.to} OK" 
} 
+0

Kod, bir cvs yükleyen ve verilerinden mükemmel sınıflar oluşturan daha büyük bir komut dosyasının parçasıdır.Soru şu ki, perl derleyicisi baskı/EOT içindeki bloğu derlemeyi ve bunu nasıl yapmamayı anlatıyor. (BTW, öneri için teşekkürler ama işe yaramadı) – xain

+0

@ xain: Tam olarak ne demek istiyorsun? "işe yaramadı"? Almayı beklediğiniz kesin çıktıyı gösterin. Sean'ın çıkışından nasıl farklıdır? – toolic

+0

Sean, benim hatam. İyi çalıştı. Teşekkürler! – xain

1

Bu sorunu çözmek gerekir. Görüldüğü gibi

println "${"px$i.name"}/${"px$i.empr.to"} OK" 
println "px$i.name"/px$i.empr.to OK" 
1

, dize $px parçası değerlendirilir oluyor. Sadece ondan kaçmak gerekir:

$i=1; 
while($i<3) { 
    print << "EOT"; 
    def px$i = new E(user) 
    if (!px$i.hasErrors()) { 
      println "\${px$i.name}/\${px$i.empr.to} OK" 
    } 

EOT 

    $i++; 
} 

"ayrıştırma Kanlı ayrıntıları yapılarını aktardığı" altında perldoc perlop en kaçan dize hakkında daha fazlasını okuyun.

4

Komut satırı seçeneği -MO=Deparse, Perl'in basitleştirdikten sonra kodunuzu nasıl yorumladığını gösterir (örneğin, heredoc'u qq {} bloklarına dönüştürme). Örneğin.

$ perl -MO=Deparse test.pl 
$i = 1; 
while ($i < 3) { 
    print qq[ def px$i = new E(user) \n if (!px$i.hasErrors()) {\n   println "${$i->px . 'name';}/${$i->px . 'empr' . 'to';} OK"\n }\n\n]; 
    ++$i; 
} 

ilgili parçasıdır:

println "${$i->px . 'name';}/${$i->px . 'empr' . 'to';} 

Perl ${$i->px . 'name'} için ${px$i.name} dönüştüğü! Perlde

, ${...} blok içinde ne olursa olsun değerlendirmek ve bir sayısal geri çevirmek için daha sonra KQUEUE, bir symbolic reference (yani, bir değişken adı) veya skalar referans olarak ele alınır. Böylece Perl, bu blokların içinde ne varsa onu yürütmeye çalışır, onların içeriğini Perl kodu olarak ele alır. Bunun nedeni, heredoc, "EOT"'un çift tırnaklı bir dizgiye benzemesi ve dolar işaretlerini enterpolasyonudur.

Çözüm: dolar işaretlerinden kaçının ($ ->\$) veya tekdüzenler yerine tek tırnak ve birleştirme kullanın.

1
my $format = << 'EOT'; 
def px%d = new E(user) 
    if (!px%d.hasErrors()) { 
      println "${px%d.name}/${px%d.empr.to} OK" 
    } 
EOT 

for my $i (1 .. 3) { 
    printf $format, ($i) x 4; 
} 
+1

(+1) birden fazla çeşitte heredog var tek tırnaklı enterpolasyonlu değildir. başka bir tip backticks, ör. Dizeyi kabuk yoluyla yürütecek olan EOT. – harschware

İlgili konular