How do I create new variables with indexed names in Perl? - perl

hi i've read some related question non seems tohelp me.
this is a code that will explain what i want.
for ($i=0;$i<5;$i++) {
my $new$i=$i;
print "\$new$i is $new$i";
}
expecting variables to be named $new0,$new1,$new2,$new3,$new4,$new5.
and to have the abillty to use them in a loop like the print command is trying to do.
Thanks

You want to use a hash or array instead. It allows a collection of data to remain together and will result in less pain down the line.
my %hash;
for my $i (0..4) {
$hash{$i} = $i;
print "\$hash{$i} is $hash{$i}\n";
}

Can you describe why exactly you need to do this.
Mark Jason Dominus has written why doing this is not such a good idea in Why it's stupid to "use a variable as a variable name"
part 1, part 2 and part 3.
If you think your need is an exception to cases described there, do let us know how and somebody here might help.

You are asking a common question. The answer in 99.9% of cases is DON'T DO THAT.
The question is so common that it is in perlfaq7: How can I use a variable as a variable name?.
See "How do I use symbolic references in Perl?" for lots of discussion of the issues with symbolic references.

use a hash instead.
my %h=();
$new="test";
for ($i=0;$i<5;$i++) {
$h{"$new$i"}=$i;
}
while( my( $key, $value ) = each( %h ) ) {
print "$key,$value\n";
}

if you want to create variables like $newN you can use eval:
eval("\$new$i=$i");
(using hash probably would be better)

Related

Perl: How to get keys on key "keys on reference is experimental"

I am looking for a solution to Perl's warning
"keys on reference is experimental at"
I get this from code like this:
foreach my $f (keys($normal{$nuc}{$e})) {#x, y, and z
I found something similar on StackOverflow here:
Perl throws "keys on reference is experimental"
but I don't see how I can apply it in my situation.
How can I get the keys to multiple keyed hashes without throwing this error?
keys %{$normal{$nuc}{$e}}
E.g. dereference it first.
If you had a reference to start off with, you don't need {} E.g.:
my $ref = $normal{$nuc}{$e};
print keys %$ref;
The problem is that $normal{$nuc}{$e} is a hash reference, and keys will officially only accept a hash. The solution is simple—you must dereference the reference—and you can get around this by writing
for my $f ( keys %{ $normal{$nuc}{$e} } ) { ... }
but it may be wiser to extract the hash reference into an intermediate variable. This will make your code much clearer, like so
my $hr = $normal{$nuc}{$e};
for my $f ( keys %$hr ) { ... }
I would encourage you to write more meaningful variable names. $f and $e may tell you a lot while you're writing it, but it is sure to cause others problems, and it may even come back to hit you a year or two down the line
Likewise, I am sure that there is a better identifier than $hr, but I don't know the meaning of the various levels of your data structure so I couldn't do any better. Please call it something that's relevant to the data that it points to
keys $hash_ref
is the reason for the warning keys on references is experimental
Solution:
keys %{ $hash_ref }
Reference:
https://www.perl.com/pub/2005/07/14/bestpractices.html/

smart match operator for hash of hash

I want to match keys of a hash of hash with regexp .
$line=" Cluster(A,B):A(T) M(S)";
$reg="Cluster";
my ( $cluster, $characters ) = split (/:/,$line);
$HoH{$cluster}={split /[( )]+/,$characters } ;
foreach $value(keys %HoH){
foreach $characters (keys %{$HoH{$cluster}}){
print "$value:$characters\n" if /$reg/ ~~ %HoH;
}
}
now Output is :
Cluster(A,B):A
Cluster(A,B):M
This code is works fine with this sample data,but not with real data!! my data is more complicated but the structure is the same I was wondering if there is some other ways to do this
Perhaps you want just
print "something\n" if exists $HoH{regexp}
or maybe
print "something\n" if grep /regexp/, keys %HoH
but if neither of these are correct then you need to explain better what you need, and give some examples
This is under documented, and I don't grok exactly what the issue is, but the smart match operator works better with references to arrays and hashes. So you may have better luck with
/$reg/ ~~ \%Hoh
SmartMatch is currently complicated, unwieldy and surprising. Don't use it, at least not now. There's talk by the main developers of perl to either greatly simplify it or remove it completely. Either way it won't do what you're asking it to do in the future, so don't rely on it doing that now.
Being more explicit about what you want is better anyway.
Most likely, your bug is here:
foreach $characters (keys %{$HoH{$cluster}}) {
which should read
foreach $characters (keys %{$HoH{$value}}) {
. Probably.

How do I print a hash name in Perl?

Kind of a simple question, but it has me stumped and google just lead me astray. All I want to do is print out the name of a hash. For example:
&my_sub(\%hash_named_bill);
&my_sub(\%hash_named_frank);
sub my_sub{
my $passed_in_hash = shift;
# do great stuff with the hash here
print "You just did great stuff with: ". (insert hash name here);
}
The part I don't know is how to get the stuff in the parenthesis(insert...). For a nested hash you can just use the "keys" tag to get the hash names (if you want to call them that). I can't figure out how to get the entire hash name though, it seems like it really is just another key.
As #hackattack said in the comment, the technical answer to your questions can be found in an answer to Get variable name as string in Perl
However, you should consider whether you are doing the right thing?
If you somehow need to know the name of the hash, you most likely would solve the problem better if you stash those multiple hashes into a hash-of-hashes with names being the keys (which you should be familiar with as you alluded to the approach in your question).
$hash_named_bill{name} = "bill";
$hash_named_frank{name} = "frank";
&my_sub(\%hash_named_bill);
&my_sub(\%hash_named_frank);
sub my_sub{
my $passed_in_hash = shift;
# do great stuff with the hash here
print "You just did great stuff with: ". $passed_in_hash->{name};
}
You can use a name to refer to a hash, but hashes themselves don't have names. For example, consider the following:
*foo = {};
*bar = \%foo;
$foo{x} = 3;
$bar{y} = 4;
Keeping in mind the hash contains (x=>3, y=>4): Is the hash nameless? named 'foo'? named 'bar'? All of the above? None of the above?
The best you can do is approximate an answer using PadWalker. I recommend against using it or similar (i.e. anything that finds a name) in production!
A hash is just a piece of memory, to which a name (or more than one) can be associated.
If you want to print the name of the variable, that's not very straightforward (see haccattack comment), and doesn't smell very well (are you sure you really need that?)
You can also (if this fits your scenario) consider "soft (or symbolic) references" :
%hash1 = ( x => 101, y => 501);
%hash2 = ( x => 102, y => 502);
my_sub("hash1");
#my_sub(\%hash1); # won't work
my_sub("hash2");
sub my_sub {
my $hashname = shift;
print "hash name: $hashname\n";
print $hashname->{x} . "\n";
}
Here you are passing to the function the name of the variable, instead of a (hard) reference to it. Notice that, in Perl, this feels equivalent at the time of dereferencing it (try uncommenting my_sub(\%hash1);), though it's quite a different thing.

Accessing arrays within arrays

I have two bits of code that produce different output, and I am having great difficulty understanding why.
Code snippet 1:
my #args = $bighash{'arguments'}{'allocations'};
print "$args[0][1]";
Code snippet 2:
my #args = $bighash{'arguments'}{'allocations'}[0];
print "$args[1]";
In the first case, it is printing the value I expect. In the second case, it's not printing anything at all. Can anyone explain this?
The values stored in your hash are array references. You can work with the reference directly:
my $args = $bighash{'arguments'}{'allocations'};
print $$args[1]; # or $args->[1]
Or you can unpack the array into a new one:
my #args = #{ $bighash{'arguments'}{'allocations'} };
print $args[1];
More detail on the perlref and perldsc man pages.
Eric Strom's answer basically set's you right... but I'm surprised nobody has suggested using Data::Dumper to examine the data-structures you are working with. You can really see the difference between what you've done and Eric's correction. This might help set things straight for you.
Re: use warnings... you must get a warning when you try to print the non-existent element of the newly created array? I once got told never to ask anything online until I've used strict and warnings. That's maybe a bit extreme, but -w and Data::Dumper definitely help me :-)
In the code snippet 2, youre effectively taking the first element in your bighash ([0] is the first element) and putting that as the only element in an array. Then you ask for the second element, which does not exist.
If you remember to 'use warnings', this should yield one, since you're assigning a scalar as an array. I have not tested this myself, though.

Questions every good Perl developer should be able to answer [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Inspired by the original thread and the up and coming clones, here's one for the Perl community.
What are questions a good Perl programmer should be able to respond to?
Why is use strict helpful?
My bellweather question is What's the difference between a list and an array?.
I also tend to like asking people to show me as many ways as they can to define a scope. There's one that people almost always forget, and another that most people think provides a scope but doesn't.
What is the difference between
if ($foo) { ... }
and
if (defined $foo) { ... }
and when should you use one over the other?
Questions
What is a reference?
How does Perl implement object orientation?
How does Perl's object orientation differ from other languages like C# and Java?
Traditional object orientation in core Perl has largely been superseded by what?
Why?
What is the difference between a package and a module?
What features were implemented in 5.10?
What is a Schwartzian transform?
Explain the difference between these lines of code and the values of the variables.
my $a = (4, 5, 6);
my #a = (4, 5, 6);
my $b = 4, 5, 6;
my $c = #a;
What are some of Perl's greatest strengths?
What are some of Perl's greatest weaknesses?
Name several hallmarks of the "modern Perl" movement.
What does the binding operator do?
What does the flip-flop operator do?
What is the difference between for and foreach?
What makes Perl difficult to parse?
What are prototypes?
What is AUTOLOAD?
What is the Perl motto?
Why is this a problem?
What does use strict; do? Why is it useful?
What does the following block of code do?
print (3 + 4) * 2;
Tests
Implement grep using map.
Implement and use a dispatch table.
Given a block of text, replace a word in that block with the return value of a function that takes that word as an argument.
Implement a module, including documentation compatible with perldoc.
Slurp a file.
Draw a table that illustrates Perl's concept of truthiness.
What is the difference between my and our?
What is the difference between my and local?
For the above, when is it appropriate to use one over the other?
What are list context and scalar context?
What is the difference between my $x = ... and my($x) = ...?
What does my($x,undef,$z) = ... do?
Why is my(#a,#b) = (#list1, #list2) likely a bug?
How can a user-defined sub know whether it was called in list or scalar context? Give an example of when it makes sense for the same sub to return different values in one context or the other.
What is the difference between /a(.*)b/ and /a(.*?)b/?
What's wrong with this code?
my #array = qw/a b c d e f g h/;
for ( #array ) {
my $val = shift #array;
print $val, "\n";
}
my $a = 1;
if($a) {
my $a = 2;
}
print $a;
What is the value of $a at the end?
What's wrong with using a variable as a variable name?
Study guide: Part 1, Part 2, and Part 3.
I think brian d foy's approach is an ingenious tactic to test knowledge, understanding, and partiality about the language and the programming craft in general: What are five things you hate about your favorite language?. If they can't name 5 they probably aren't great with the language, or are totally inept at other approaches.
He applies this to people trying to a push a language: I would extend that and say it is just as applicable here. I would expect every good Perl programmer to be able to name five things they don't like. And, I would expect those five things to have some degree of merit.
Write code that builds a moderately complex data structure, say an array of hashes of arrays. How would you access a particular leaf? How would you traverse the entire structure?
For each of the following problems, how would you solve it using hashes?
Compute set relationships, e.g., union, intersection, mutual exclusion.
Find unique elements of a list.
Write a dispatch table.
My favourite question. What is following code missing:
open(my $fh, "<", "file.txt");
while (<$fh>) {
print $_;
}
close($fh);
This question should open discussion about error handling in perl. It also can be adopted to other languages too.
Some months ago, chromatic—author of Modern Perl—wrote a similar nice article “How to Identify a Good Perl Programmer,” which contains a list of questions that every good Perl programmer should be able to answer effectively.
Some of those nice questions are given below:
What’s the difference between accessing an array element with $items[$index] and #items[$index]?
What’s the difference between == and eq?
How do you load and import symbols from a Perl 5 module?
What is the difference, on the caller side, between return; and return undef;?
What is the difference between reading a file with for and with while?
For complete details read How to Identify a Good Perl Programmer.
How is $foo->{bar}[$baz]($quux) evaluated?
What is a lexical closure? When are closures useful? (Please, no counter-creators!)
What is the difference between list context and scalar context. How do you access each? Is there such a thing as Hash context? Maybe a little bit?
How to swap the values of two variables without using a temporary variable?
What does this one-liner print and why :
perl -pe '}{$_ = $.' file
answer: number of lines in the file, similar to wc -l.
What's wrong with this code :
my $i;
print ++$i + ++$i;
answer: modifying a variable twice in the same statement leads to undefined behaviour.
Simple one: will the if block run :
my #arr = undef;
if (#arr) { ... }
answer: yes
How would you code a reverse() perl builtin yourself ? You can use other perl functions.
answer: many ways. A short one: sub my_reverse {sort {1} #_})
I would also probably dig on regex, as I expect every good Perl programmer to master regex (but not just that). Some possible questions:
what are lookahead and lookbehind assertion /modifierq?
how do you check that two individual parts of a regex are identical ?
what means greedy ?
what are Posix character classes ?
what does \b match ?
what is the use of \c modifier ?
how do you precompile a regex ?
What is the correct way to initialize a empty string?
my $str = q{};
or
my $str = "";
or
my $str = '';