home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / lang / perl / 7663 < prev    next >
Encoding:
Internet Message Format  |  1993-01-04  |  5.8 KB

  1. Path: sparky!uunet!gatech!destroyer!caen!nic.umass.edu!dime!graceland!srivasta
  2. From: srivasta@pilgrim.umass.edu (Manoj Srivastava)
  3. Newsgroups: comp.lang.perl
  4. Subject: [Question] Indirection
  5. Keywords: glob,pointer.star value
  6. Message-ID: <58235@dime.cs.umass.edu>
  7. Date: 4 Jan 93 19:05:42 GMT
  8. Sender: news@dime.cs.umass.edu
  9. Reply-To: srivasta@pilgrim.umass.edu
  10. Organization: University of Massachusetts at Amherst
  11. Lines: 154
  12.  
  13.  
  14. Hi,
  15.  
  16.     I have  a  question  about the  best  way  to  do address  the
  17. following problem. I am parsing a set of object  specifications, where
  18. an object could have a number of tuples of the  form (attribute value)
  19. which I'd like  to place in  an associative  array, and it also has  a
  20. list of other objects, which I place in an simple array.
  21.  
  22.     The  actual  parsing  is  done by  an  automatically generated
  23. subroutine,  &yyparse, which modifies the global entities  %Attribute,
  24. and  @Object  list.  I'd like  the outer level routine,  parse_obj (),
  25. (which is recursively called  on  object list) to place  these  into a
  26. form which can beaccessed by the name of the object.
  27.  
  28.     The way I see it, I have two options, firstly (Shamelessly
  29.  copied from Tom Christiansen's article of 24 Jul 91 01:56:10 GMT Re:
  30.  possibly novice associative array query) of using an associative
  31.  array of uniquely named packages, keyed by object name, and use eval
  32.  to create the package. (I think I understand how this works, I'm
  33.  appending the code from Tom's posting at the end of this article; I'm
  34.  still hazy about what those type globs are doing). The second option
  35.  is to set up uniquely named arrays and use type globbing; like so:
  36.  
  37. sub parse_obj {
  38.     local ($obj_name) = @_;
  39.  
  40.     ...
  41.     undef %Attribute;
  42.     undef @Object;
  43.     &yyparse;
  44.     local ($code)=<<EOF;
  45.     foreach \$key (keys \%Attribute){
  46.         \$$obj_name{\$key} = \$Attribute{\$key};
  47.     }
  48.     foreach \$key (\@Object){
  49.         push (\@$obj_name, \$key);
  50.     }
  51.     \$Global_attrs{\$$obj_name} = *$obj_name;
  52. EOF
  53.     eval $code;
  54.     ...
  55. }
  56.  
  57.     And now I can set a pointer to reference the objects, as
  58.  
  59.     *ptr =  $Global_attrs{$obj_name};
  60.     print "@ptr";
  61.         ....
  62.  
  63.     Is there any other way to do this?  (Hah! this is perl.  there
  64. _has  _ to be one).
  65.  
  66. Also, I'd appreciate an explanation of the lines like *'Current_Folder
  67. = *Current_Folder; in  the  code snippet below, like  *'Current_Folder
  68. referes to the current package,  right?  and what  would happen if the
  69. refered value  changes?  (I'm sorry,  but  to me these look  like  C's
  70. pointers, and if the referenced values change,  the  effect is noticed
  71. by any alias reference).
  72.  
  73. In other words, if I type glob *new = *old, and then change $old, will
  74. $new  change? If  this  is so,  then any solution to my  problem would
  75. require a copying step,  since  yyparse keeps modifying %Attribute and
  76. and @Object.
  77.  
  78.     manoj
  79.  
  80. Quote feom tchrist@convex.COM (Tom Christiansen)'s article dated
  81.  24 Jul 91 01:56:10 GMT with 
  82. Subject: Re: possibly novice associative array query
  83.  
  84. Tom> Let me discuss in brief two other strategems for magaging complex
  85. Tom> data structures in perl.
  86.  
  87. Tom> The first is employed by the &activate_folder routine in plum.
  88. Tom> Basically,  I want to keep around an associative array of active
  89. Tom> folders (actually, active folder sequences).  Each active folder
  90. Tom> has a bunch of properties of varying associated with it, such as
  91. Tom> its cache's last mtime, all the line from scan, the mappings
  92. Tom> between message ids to scan line indices, etc.
  93.  
  94. Tom> In C, the natural thing to do would be to use an array of
  95. Tom> structures.  In perl, we must be sneakier than that.  What I've
  96. Tom> done is selected an associative array called %Active_Folders; the
  97. Tom> keys are the folder names, and the values are not pointers to
  98. Tom> individual variables, but rather the names of UNIQUELY NAMED
  99. Tom> PACKAGES in which all variables associated with the folder.  When
  100. Tom> I activate one, I set the current pointers equal to the hidden
  101. Tom> ones, and then normal variable references continue to work.
  102. Tom> Since only one folder can be considered active (viewed) at any
  103. Tom> given moment,  this works well.
  104.  
  105. Tom> Here's the trimmed-down routine:
  106.  
  107. Tom>     $gensym = 'a';
  108.  
  109. Tom>     sub gensym { 'gensym_' . $gensym++; }
  110.  
  111. Tom>     sub activate_folder {
  112. Tom>         local($folder) = @_;
  113.  
  114. Tom>         &assert('$folder',$folder);
  115.  
  116. Tom>         $Last_Seq = $Current_Seq;
  117.  
  118. Tom>         $Active_Folders{$folder} = &gensym
  119. Tom>             unless defined $Active_Folders{$folder};
  120.  
  121. Tom>         local($package) = $Active_Folders{$folder};
  122.  
  123. Tom>         # warning: it is important that any of these aggregate vars
  124. Tom>         # get clearedinstead of undeffed.  otherwise you may get
  125. Tom>           # a coredump.
  126.  
  127. Tom>         local($code)=<<"EOF";
  128. Tom>             {
  129. Tom>                 package $package;
  130. Tom>                 *'Current_Folder    = *Current_Folder;
  131. Tom>                 *'Current_Seq       = *Current_Seq;
  132. Tom>                 *'Current_Line      = *Current_Line;
  133. Tom>                 *'Top_Line          = *Top_Line;
  134. Tom>                 *'Scan_Lines        = *Scan_Lines;
  135. Tom>                 *'Scan_IDs          = *Scan_IDs;
  136. Tom>                 *'Incomplete_Read   = *Incomplete_Read;
  137. Tom>                 *'Folder_Cache_Time = *Folder_Cache_Time;
  138. Tom>                 *'Last_Typed        = *Last_Typed;
  139. Tom>                 *'Deleted           = *Deleted;
  140. Tom>             }
  141. Tom>     EOF
  142. Tom>         eval $code;
  143. Tom>         $Current_Seq = $folder;
  144.  
  145. Tom>         &panic("bad eval: $@\n$code\n") if $@;
  146. Tom>     }
  147.  
  148. Tom> The typed variables I use are:
  149.  
  150. Tom>      $Current_Folder
  151. Tom>      $Current_Seq
  152. Tom>      $Current_Line
  153. Tom>      $Top_Line
  154. Tom>      @Scan_Lines
  155. Tom>      %Scan_IDs
  156. Tom>      $Incomplete_Read
  157. Tom>      $Folder_Cache_Time
  158. Tom>      $Last_Typed
  159. Tom>      %Deleted
  160. Tom>      $Deleted
  161.  
  162. Tom> In certain ways, the pseudo-anonymous packages provided by &gensym
  163. Tom> are the key to this entire scheme.
  164.  
  165.  
  166.     
  167.