2011-07-03 4 views
5

나는 거기에 '빈 슬롯'배열을 만들 수 있습니다'빈 슬롯'을 사용하여 익명 배열 ([])을 만드는 방법은 무엇입니까?

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

또는

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 

는 참고 :이 undef을 할당과 동일하지 않습니다.

그러나 어떻게 익명 배열에 []을 사용한다고 지정합니까?

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

을 그리고 난 단지 할당 된 값 얻을 수 있기 때문에이 역시 실패 :

이 작동하지 않습니다

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

보너스 질문 : 내가 '빈 배열 슬롯'을 확인 할 수있는 방법을 내 펄 스크립트에?

배경 : 테스트 스크립트에서 배열 내용을 정확하게 비교할 수 있기를 바랍니다. 예를 들어, '할당되지 않음'과 'undef 값으로 할당 됨'을 구별하고 싶습니다.

통찰력을 주셔서 감사합니다.

+1

당신은 사용하여 배열에 직접 할당을 수행하는 방법 의미는 '[]'익명의 배열에 대해,'exists'로 테스트했을 때 false를 반환하는 배열 안에 값이 있습니까? – TLP

+0

예. 게으르다면, 한 문장으로 이것을 지정할 수 있으면 좋을 것입니다. 그렇지 않으면 여러 문에서 'undef'를 사용하거나 실행해야합니다. – hexcoder

답변

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. 

우리는 익명의 배열 인 @{$aref}에 5 개의 스폿을 미리 할당했습니다. 최고 색인은 4입니다. 우리는 최고 색인이 우리가 그것을 창조 한 동일한 방법 인 무슨을 찾아 낼 수있다; $#{$aref}의 값을 테스트하여 우리는 존재를 테스트 할 수 있습니다. 04 사이의 모든 항목을 만들었습니다. 그러나 Perl은 특별히 할당 된 배열 요소 (심지어는 undef 일 수도 있음)에 대해서만 "존재"한다고보고합니다. 따라서 $aref->[2]이 존재한다고보고되었지만 정의되지 않았습니다. 그냥 재미로, ''$aref->[3]으로 지정하여 한 번 정의 된 테스트 보고서를 확인하십시오.그러나 비록 배열이 미리 확장되어 있다고해도 초기화 될 요소와 undef의 요소와 배열 미리 확장을 통해 이라는 요소가 'exists'을 사용하여 차이점을 테스트 할 수 있습니다.

문서화 된 동작이 exists이라고 말할 수는 없습니다. 언젠가는 변하지 않을 것이라고 보장 할 수는 없습니다. 그러나 그것은 5.8, 5.10, 5.12 및 5.14에서 작동합니다.

그래서, 여기에 정의 된, 그리고 된 초기화 된 요소를 찾을 수있는 간단한 방법을 찾고은 예입니다 :

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

고마워요! 내 두 번째 질문에 대한 위대한 대답! 그동안 나는'$ aref -> [2] 삭제;가 해시 엔트리처럼 '초기화되지 않음'으로 변경되었음을 알게되었습니다. – hexcoder

+0

도움이 되었기 때문에 기쁩니다. 이 퍼즐을 통해 일하는 것은 항상 재미 있습니다. – DavidO

-1

XS 코드에서만 이러한 종류의 작업을 수행 할 수 있습니다 (예 : Devel::Peek 참조). 전부는 아니지만 일부는 *::Util 패키지에 의해 노출됩니다. (I 패키지를 추적/디버깅 작업을했습니다, 그래서 사람이 필요 것보다 이것에 대해 더 알고 ....)

+0

포인터를 가져 주셔서 감사합니다. 나는 모양을 가질 것이다. 너무 나쁘다. Perl의 직접적인 방법은 없다. (그리고 나는 할 수있는 방법이 하나 이상 있다고 생각했다. ;-). – hexcoder

+0

* :: Util에서 유용한 것을 찾을 수 없습니다. 나는 List :: * Util * 또는 Array :: Utils에서 무언가를 기대했다. 당신은 더 구체적 일 수 있습니까? – hexcoder

3

해야한다고 :

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

동의합니다. 비슷하게'$ a = []; $ a -> [2] = 0;'역시해야합니다. 하지만 한 가지 진술로 가능합니까? 아마도 모듈을 지원하지 않았을 것입니다. – hexcoder

1

배경 :에서 내 테스트 스크립트 나는 배열 내용을 정확하게 비교할 수 있기를 바란다. 예를 들어, '할당되지 않음'과 'undef 값으로 할당 됨'을 구별하고 싶습니다.

색인이 끝까지지나 갔는지 확인할 수 있습니다. 그 너머에는 할 수있는 것이별로 없습니다. undef $x->[9999] 0 9998의 요소 중 어느 것도 존재하지 않으므로 $x->[9999] = undef; 동등

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

지문 10000 펄 마법 undef에 개재 된 모든 요소를 ​​할당한다.

+0

감사. 나는'perl이 마술처럼 모든 매개체를 undef에 할당 할 것 '에 동의하지 않는다. 내 첫 번째 디버깅 출력에서 ​​볼 수 있듯이 구멍은 '빈 슬롯'으로 표시됩니다. 그들이 __assigned__ 'undef'였다면 디버거는 여기에 'undef'를 표시합니다. 나는 그것을 시도했지만 질문에 이것을 보여주지 않았다. – hexcoder

+0

@hexcoder : 값이 정의되어 있지 않지만 값으로 undef가 없기 때문입니다. 이상한 뉘앙스. – DavidO

+0

@DavidO : 네. 디버거에는'x @ x'와'x \ @ x' 사이에 차이가 있습니다. 첫 번째는 'undef', 두 번째 '빈 슬롯'이 표시됩니다. 그리고'p @ x'는 초기화되지 않은 값에 대한 경고를줍니다. – hexcoder

관련 문제