2017-09-12 10 views
-5
sub bat 
{ 
    my ($abc) = @_; 
    my @gCol ; 
    { 
     my $rec = {}; 
     $rec->{name}  = "BATID"; 
     $rec->{type}  = "VARCHAR2"; 
     $rec->{length}  = "14"; 
     $rec->{scale}  = "0"; 
     $rec->{label}  = "Id"; 
     $rec->{ref_comment} = "Shows bat type"; 
     $rec->{ref_link} ="$APPL_HOME/bat.cgioptions=Status&options=mfgDate&options=Details&options=RefreshAuto"; 
     $rec->{ref_col}  = [ ("BAT_ID") ]; 
     $rec->{nullable} = "Y"; 
     $rec->{pk}   = "N"; 
     $rec->{print}  = undef; 
     $rec->{visible}  = "Yes"; 
     push (@gCol, $rec); 
    } 
} 

이 서브 루틴을 각 행에서 설명 할 수 있습니까? 이것에 사용되는 해시인가 아닌가? 내 $ rec = {};는 무엇입니까? 푸시를 사용하면 어떻게됩니까?perl의 서브 루틴에 대한 이해

+0

https://perldoc.perl.org/perlreftut.html & https://perldoc.perl.org/functions/push.html –

+0

그러나이 하위 항목은 거의 쓸모없는 것처럼 보입니다. $ rec는 블록 끝에서 범위를 벗어나고 sub는 push()가 반환 한 값을 반환합니다. – ulix

+0

@ulix :'$ rec'가 서브 루틴의 끝에서 범위를 벗어나는 것은 문제가 아닙니다. 참조가'@gCol'에 저장되어 있기 때문에 문제가되지 않습니다. 문제는'@ gCol'도 정확히 같은 시간에 범위를 벗어납니다. –

답변

1

당신은 모든 라인에 무슨 일이 일어나고 있는지에 대한 설명을 요청하고 난 당신이 아직있어 생각하지 않습니다.

sub bat 
{ 
    # Take the first parameter passed to the subroutine and store 
    # it in a variable called $abc. 
    # This value is then ignored for the rest of the subroutine, so 
    # this line of code is pointless. 
    my ($abc) = @_; 

    # Declare an array variable called @gCol. 
    my @gCol ; 

    # Start a new block of code. 
    { 

     # Declare a scalar variable called $rec. 
     # Initialise it with a reference to an empty, anonymous hash 
     my $rec = {}; 

     # The next dozen lines are pretty much all the same. 
     # Each of them inserts a key/value pair into the $rec hash. 
     $rec->{name}  = "BATID"; 
     $rec->{type}  = "VARCHAR2"; 
     $rec->{length}  = "14"; 
     $rec->{scale}  = "0"; 
     $rec->{label}  = "Id"; 
     $rec->{ref_comment} = "Shows bat type"; 
     # This line is slightly interesting as it uses the value 
     # of a global variable called $APPL_HOME. 
     # Using global variables inside a subroutine is a really 
     # bad idea as it limits the portability of the subroutine. 
     $rec->{ref_link} ="$APPL_HOME/bat.cgioptions=Status&options=mfgDate&options=Details&options=RefreshAuto"; 
     # This line is also interesting as instead of setting the 
     # value to a scalar value, it sets it to a reference to an 
     # anonymouse array. 
     $rec->{ref_col}  = [ ("BAT_ID") ]; 
     $rec->{nullable} = "Y"; 
     $rec->{pk}   = "N"; 
     $rec->{print}  = undef; 
     $rec->{visible}  = "Yes"; 

     # Having set up a hash with twelve key/value pairs, you 
     # then push the hash reference onto the (currently empty) 
     # array, @gCol. 
     push (@gCol, $rec); 

     # The next line marks the end of the block of code. 
     # Because the $rec variable was declared inside this block, 
     # It will now go out of scope and ceases to exist. 
     # However, because the reference is still stored in @gCol, 
     # the memory will not be recovered, so your hash still exists. 
    } 

    # This line marks the end of the subroutine. This is also the 
    # end of scope for any variables declared within the subroutine. 
    # That includes the @gCol array which ceases to exist at this 
    # point. Unfortunately, this means that our carefully constructed 
    # hash also ceases to exist at this point and all our work 
    # is wasted. 
} 

는 코드가 많은 작업을 수행, 요약하면,하지만, 모든 작업은 서브 루틴이 종료 모든 멀리 던져 사용하는 변수로 낭비된다. 따라서이 서브 루틴을 호출하는 순수 효과는 전혀 없습니다.

+0

서브 루틴을 사용하면 어떤 이점이 있습니까? –

+0

변수 범위를 제한하는 서브 루틴을 사용하는 것이 아니라 서브 루틴 내에서 'my'를 사용하는 것입니다. 그러나 그것은 좋은 생각입니다. 서브 루틴은 서브 루틴 외부의 변수를 사용하지 않아야합니다. 서브 루틴이 필요로하는 모든 데이터는 매개 변수로 전달되어야하며 서브 루틴 외부에서 공유되어야하는 데이터는'return()'문을 통해 리턴되어야합니다. –

1
{ LIST } 

다음 해시 LIST 의해 생성 된 스칼라 (존재하는 경우)에 할당하고, 해시에 대한 참조를 생성

do { my %anon = LIST; \%anon } 

이것은 해시를 생성 기본적으로 동일하다. 전체가 그 참조를 평가합니다. 당신은 중괄호로 표시 블록을 3 행의 서브 루틴에서

sub bat 
{ 
    my ($abc) = @_; 
    my @gCol; 
    { 
     my %rec; 
     $rec{name}  = "BATID"; 
     $rec{type}  = "VARCHAR2"; 
     $rec{length}  = "14"; 
     $rec{scale}  = "0"; 
     $rec{label}  = "Id"; 
     $rec{ref_comment} = "Shows bat type"; 
     $rec{ref_link} ="$APPL_HOME/bat.cgioptions=Status&options=mfgDate&options=Details&options=RefreshAuto"; 
     $rec{ref_col}  = [ ("BAT_ID") ]; 
     $rec{nullable} = "Y"; 
     $rec{pk}   = "N"; 
     $rec{print}  = undef; 
     $rec{visible}  = "Yes"; 
     push @gCol, \%rec; 
    } 
} 
+0

@gcol을 푸시는 것은 무엇이겠습니까? \ % rec 행이 사용됩니까? –

+0

'push '는 하나 이상의 요소를 배열에 추가합니다. 나는 당신의 [연구] 부족으로 짜증났다. (http://perldoc.perl.org/functions/push.html). 서브 루틴이 변수의 범위를 제한한다면 – ikegami

-1

다음과 같이


서브는 그냥 간단하게 쓸 수 있었다. 블록에는 자체 범위가 있습니다. @gCol 배열은 블록의 동일한 범위에서 선언됩니다. 그럼 내 $ rec = {}; 연관 배열 (해시라고도 함)을 선언하고 그 다음은 해시에 대한 키 값 쌍의 정의입니다. @gCol은 $ rec로 % rec의 스칼라 값에 (push) 추가됩니다.

More on hashes in scalar context: