1

I am declaring a variable like -

for($i = 0; $i <= 3; $i++)
{
    if(some condition) {
        my ${'file'.$i.'size'} = 0; }
}

I want my variable to be only declared if it matches the condition else not. I expected it to create 4 variables like file1size file2size etc. However I am getting error "Can't declare scalar dereference in my perl". Where am I going wrong ?

Cool Camel
  • 57
  • 6
  • 2
    What is this supposed to do that an array doesn’t do better?! – Biffen Nov 22 '22 at 13:30
  • Does this answer your question? [How can I use a variable as a variable name in Perl?](https://stackoverflow.com/questions/1549685/how-can-i-use-a-variable-as-a-variable-name-in-perl) – Biffen Nov 22 '22 at 13:32
  • The reason why I don't want an array is because there is a condition before declaring variables in my original code. I don't want file2size if suppose file doesn't exist [this is just an example of my actual code] – Cool Camel Nov 22 '22 at 13:32
  • I don’t understand what you’re trying to say. Could you [edit] the question to be closer to what you’re actually trying to do? Especially interesting is how you plan to _use_ those variables later on. – Biffen Nov 22 '22 at 13:34
  • Can you tell me alternative to achieve it ? I don't want to use array. @Biffen – Cool Camel Nov 22 '22 at 13:34
  • *"this is just an example of my actual code"* Please show actual code so we can better help you. – Håkon Hægland Nov 22 '22 at 13:35
  • I also don't understand why this doesn't work. If someone can explain it, that would be great. – Cool Camel Nov 22 '22 at 13:37
  • @CoolCamel It doesn’t work because Perl doesn’t work that way. Look at the answers to the question linked in my previous comment. – Biffen Nov 22 '22 at 13:39
  • 2
    @CoolCamel You could use a hash, e.g. `my %file_size; … $file_size{$i} = 0`. – Biffen Nov 22 '22 at 13:40
  • yeah it looks like I have no other option that to create a hash map – Cool Camel Nov 22 '22 at 13:41
  • @CoolCamel you could declare and define package variables (not lexical variables) like that `${'file'.$i.'size'} = 0`.. but without seeing more of your code I do not know whether it would be recommended or not – Håkon Hægland Nov 22 '22 at 13:42
  • @HåkonHægland when is it not recommended to use it ? Unfortunately, I cannot share the code. – Cool Camel Nov 22 '22 at 13:45
  • @CoolCamel generally global variables should be avoided – Håkon Hægland Nov 22 '22 at 13:45
  • If you don't already have a good understanding of how to use dynamic variable names, then you should never use them. And even if you knew how they work, it's extremely rare to have a good use-case. It's not like you have "no other option that to create a hash map": the best tool to solve your issue is to use a hashmap, and that's not a bad thing at all. If you think that this is a restriction, then your code is poorly designed. – Dada Nov 22 '22 at 13:49
  • Sure, thanks for the inputs @Biffen Hakon Dada. I think I'll go ahead with a hashmap then – Cool Camel Nov 22 '22 at 13:51
  • Perhaps the answer you want is [here](https://perldoc.perl.org/perlfaq7#How-can-I-use-a-variable-as-a-variable-name?) – TLP Nov 22 '22 at 16:14
  • Re "*yeah it looks like I have no other option that to create a hash map*", not at all. What you are currently building is actually akin to an array. – ikegami Nov 22 '22 at 17:39

1 Answers1

2

You can dynamically create package variables names (as opposed to lexical (my) variables), but it's a horrible idea. It's so bad that we use use strict; to tell Perl to forbid us from doing it.


You are effectively building an array.

my @file_sizes;
for my $i ( 0 .. 3 ) {
   if ( some condition ) {
      $file_sizes[ $i ] = 0;
   }
}

Whether this makes sense is another question.

Just like your original code, this creates "holes", by which I mean indexes with no value (undef for value). This, by itself, it not necessary wrong. But what's the point of an array that contains 0, undef, 0? or undef, 0, 0? (Even if the zeroes are other numbers.) Maybe you have parallel arrays. It might make sense in that case. But it's hard and annoying to work with parallel arrays, and that makes them error-prone.

So again, this code looks really fishy. But I have no information that I can use to improve it.

ikegami
  • 367,544
  • 15
  • 269
  • 518