-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);
   }
}

Can anyone explain this subroutine what is being done in each line ? and is hash used in this or not? what is my $rec= {};? what happens by using push?

Kamlesh Sam
  • 13
  • 1
  • 3
  • https://perldoc.perl.org/perlreftut.html & https://perldoc.perl.org/functions/push.html – mpapec Sep 12 '17 at 06:05
  • But this sub appears to me almost useless; $rec goes out of scope at end of block and the sub returns the value returned by push() . – ulix Sep 12 '17 at 08:08
  • @ulix: The fact that `$rec` goes out of scope at the end of the subroutine isn't a problem - as a reference to it is stored in `@gCol`. The problem is that `@gCol` goes out of scope as well at exactly the same time :-) – Dave Cross Sep 12 '17 at 12:21

3 Answers3

1
{ LIST }

is basically equivalent to

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

It creates a hash, then assigns the scalars produced by LIST (if present) to the hash, and then creates a reference to the hash. The whole evaluates to that reference.


The sub could just as easily have been written as follows:

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;
   }
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

You ask for an explanation of what is happening on every line and I don't think you've got that yet.

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.
}

To summarise, your code does a lot of work, but all that work is wasted as the variables it uses are all thrown away as the subroutine ends. So the net effect of calling this subroutine is absolutely nothing.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • if subroutine limit the scope of variables ..then what is the advantage of using subroutines? – Kamlesh Sam Sep 14 '17 at 06:52
  • It isn't the use of subroutines that limits the scope of variables, it is the use of `my` within the subroutine. But that's a good idea. Subroutines should not use variables from outside the subroutine. All data that the subroutine needs should be passed into it as a parameter and any data that the subroutine creates that needs to be shared outside of the subroutine should be returned through a `return()` statement. – Dave Cross Sep 14 '17 at 08:33
0

$rec= {} this is called as anonymous hash reference. And name , type , length are keys BATID,VARCHAR2,14 are values for those keys.

And $rec->{ref_col} this key's value is anonymous array.

mkHun
  • 5,891
  • 8
  • 38
  • 85