2011-07-03 35 views
5

İçinde 'boş yuvalara' ile bir dizi oluşturabilirsiniz:'Boş yuvalarla' anonim dizi ([]) nasıl oluşturulur?

$ perl -wde 1 
... 
    DB<1> $x[2] = 0 
    DB<2> x \@x 
0 ARRAY(0x103d5768) 
    0 empty slot 
    1 empty slot 
    2 0 

veya

DB<3> $#y = 4 
    DB<4> x \@y 
0 ARRAY(0x103d5718) 
    0 empty slot 
    1 empty slot 
    2 empty slot 
    3 empty slot 
    4 empty slot 

Lütfen dikkat: Bu undef atama gibi aynı değildir.

Ama bunu [ ve ] kullanarak anonim bir dizi için nasıl belirtebilirim?

DB<5> x [,,0] 
syntax error at (eval 27)[/usr/local/lib/perl5/5.10.0/perl5db.pl:638] line 2, near "[," 

Ve sadece atanmış değeri elde beri bu da başarısız:

Bu işe yaramaz

DB<6> x []->[2] = 0 
0 0 

Bonus soru: Ben bir 'boş dizi yuvası' için nasıl kontrol edebileceklerini Perl betiğimde mi?

Amaç: benim test komut dosyaları ben tam dizi içeriğini karşılaştırabilir olmak istiyorum. Örneğin 'atanmamış' ve 'undef değeriyle atanan' arasında ayrım yapmak istiyorum.

Her türlü anlayış için teşekkürler.

+1

kullanarak, bir diziye doğrudan atama nasıl demek '[]' anonim dizi için, var olanla test edildiğinde false döndüren dizinin içinde değerlere sahip midir? – TLP

+0

Evet. Tembel olmak, bunu tek bir ifadede belirtmek güzel olurdu. Aksi halde 'undef' kullanmam veya birden fazla ifadede yapmam gerek. – hexcoder

cevap

5
use feature qw/ say /; 
use strict; 
use warnings; 

my $aref; 

$#{$aref} = 4; 
$aref->[2] = undef; 
$aref->[3] = ''; 

foreach my $idx (0 .. $#{$aref}) { 
    say "Testing $idx."; 
    say "\t$idx exists." if exists $aref->[$idx]; 
    say "\t$idx defined." if defined $aref->[$idx]; 
} 

OUTPUT: 
Testing 0. 
Testing 1. 
Testing 2. 
    2 exists. 
Testing 3. 
    3 exists. 
    3 defined. 
Testing 4. 

Biz anonim dizi @{$aref} beş noktalar-tahsis önceden. Üst dizin 'dur. En iyi endeksin, yarattığımızla aynı şekilde olduğunu bulabiliriz; $#{$aref} değerini test ederek. Varlığı test edebiliriz. 0 ve 4 arasındaki herşeyi biliyoruz. Ancak Perl, yalnızca kendilerine atanmış bir şeyleri olan dizi öğeleri için "var olur" raporlar (undef olsa bile). Bu nedenle, $aref->[2]'un var olduğu bildirilmiştir, ancak tanımlanmamıştır. Sadece eğlence için, bir kez tanımlanmış bir test raporunu görmek için '''u $aref->[3]'a atadık.Ancak kısa öykü, dizinin önceden uzatılmış olmasına rağmen, undef ile başlatılan bir öğe arasındaki farkı ve dizi ön uzantısı üzerinden 'exists' kullanarak bir elemanın undef arasındaki farkı test edebiliriz.

Bunun exists davranışını belgelenir diyemeyiz. Yani birgün değişmeyeceğine dair bir garanti yok. Ama 5.8, 5.10, 5.12 ve 5.14 üzerinde çalışıyor.

Yani, burada, tanımlandı ve değillerdi hangi başlatıldı hangi elemanlara bulmak için basit bir yol, arayan bir örnek:

use feature qw/ say /; 
use strict; 
use warnings; 

my $aref; 

$#{$aref} = 4; 
$aref->[2] = undef; 
$aref->[3] = ''; 

my @initialized = grep { exists $aref->[$_] } 0 .. $#{$aref}; 
my @defined = grep { defined $aref->[$_] } 0 .. $#{$aref}; 
my @uninitialized = grep { not exists $aref->[$_] } 0 .. $#{$aref}; 
my @init_undef = grep { exists $aref->[$_] and not defined $aref->[$_] } 0 .. $#{$aref}; 
say "Top index is $#{$aref}."; 
say "These elements are initialized: @initialized."; 
say "These elements are not initialized: @uninitialized."; 
say "These elements were initialized with 'undef': @init_undef."; 
say "These elements are defined: @defined." 
+0

Çok teşekkürler! Benim ikinci soru için büyük cevap! Bu arada, $ aref -> [2] 'i sildiğini,' hash girdileri için yaptığı gibi 'başlatılmamış' olarak değiştirdiğini öğrendim. – hexcoder

+0

Yardımcı olduğunu düşündüğünüz için teşekkür ederiz. Bu bulmacalarla çalışmak her zaman eğlenceli. – DavidO

-1

Yalnızca XS kodundan bu tür şeyleri yapabilir (örneğin Devel::Peek için bakınız). Bazıları, ancak hepsi değil, *::Util paketleri tarafından ortaya çıkar. (Ben paketi izleme/a ayıklama çalışıyoruz, o yüzden kimsenin gerek gerekenden daha bu konuda daha fazla bilgi ....)

+0

İşaretçiler için teşekkürler. Bir göz atarım. Çok kötü, doğrudan Perl yolu yoktur (ve bunu yapmak için birden fazla yol olduğunu düşündüm ;-); – hexcoder

+0

Kullanışlı bir şey bulamadım * :: Util. List :: * Util * veya Array :: Utils'de bir şey olmasını ümit ettim ama hiçbir şey. Daha spesifik olabilir misin? – hexcoder

3

yapmalıdır Yani:

$a=[]; 
$#$a=4; 
+0

Aynı fikirdeyim, aynı şekilde $ a = []; $ a -> [2] = 0; 'da yapmalı. Ama bir ifadede mümkün mü? Muhtemelen bir modülden destek almadan olmaz. – hexcoder

1

Arka Plan: Benim içinde test scriptleri Dizi içeriğini tam olarak karşılaştırmak istiyorum. Örneğin 'atanmamış' ve 'undef değeriyle atanan' arasında ayrım yapmak istiyorum. indeks sonunda geçmiş ise

kontrol edebilirsiniz. Bunun ötesinde yapabileceğiniz fazla bir şey yok. undef $x->[9999] 0 9998 için elementlerin hiçbiri mevcut Çünkü $x->[9999] = undef; eşdeğerdir

$x = []; 
undef $x->[9999]; 
print scalar @$x; 

baskılar 10000, perl sihirli undef üzere müdahale tüm öğeleri atar.

+0

Teşekkürler. Ben kabul etmiyorum; perl, tüm müdahaleci unsurları sihirli olarak atayacaktır. İlk hata ayıklama çıkış deliklerimde gördüğünüz gibi 'boş yuva' olarak görünüyor. Onlar __assigned__ 'undef' olsaydı, debugger burada 'undef' gösterirdi. Bunu denedim, ancak bunu soruda göstermedim. – hexcoder

+0

@hexcoder: Değerleri tanımlanmamış olsa da, değer olarak undef değeri yoktur. Garip nüans. – DavidO

+0

@DavidO: Yep. Hata ayıklayıcıda 'x @ x' ve' x \ @ x' arasında bir fark vardır. İlk, 'undef', ikinci 'boş yuva' gösterecektir. Ve 'p', başlatılmamış değerler için uyarılar verecektir. – hexcoder

İlgili konular