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

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 = '';

Related

Where can I find simple exercises to practice string manipulation in Perl?

Does anyone know where I can find a collection of very simple exercises on string manipulation in order to practice Perl language?
I'm learning Perl just to use the resources it has got of string manipulation.
Learning Perl book has lots of exercises as far as I recall.
Also, search StackOverflow on "perl" and ("regex" or "split") and try to answer any questions yourself and then go and understand other people's answers
Also, go through any string manipulation tasks on Rosetta Code and do them in Perl
You could do this simply with Test::More. Do your manipulations and then test your guess:
my $subs1 = substr( 'apple', 0, 1 );
is( $subs1, 'a' );
The underlying testing system will usually tell you what you guessed wrong. If you did this in REPL (since it's very linear), it could serve as a training exercise.
You can start with
my $s = 'PERL';
$s =~ s/PERL/Perl/;
or
$s = ucfirst lc $s;
perldoc -q string

Why does Perl::Critic dislike using shift to populate subroutine variables?

Lately, I've decided to start using Perl::Critic more often on my code. After programming in Perl for close to 7 years now, I've been settled in with most of the Perl best practices for a long while, but I know that there is always room for improvement. One thing that has been bugging me though is the fact that Perl::Critic doesn't like the way I unpack #_ for subroutines. As an example:
sub my_way_to_unpack {
my $variable1 = shift #_;
my $variable2 = shift #_;
my $result = $variable1 + $variable2;
return $result;
}
This is how I've always done it, and, as its been discussed on both PerlMonks and Stack Overflow, its not necessarily evil either.
Changing the code snippet above to...
sub perl_critics_way_to_unpack {
my ($variable1, $variable2) = #_;
my $result = $variable1 + $variable2;
return $result;
}
...works too, but I find it harder to read. I've also read Damian Conway's book Perl Best Practices and I don't really understand how my preferred approach to unpacking falls under his suggestion to avoid using #_ directly, as Perl::Critic implies. I've always been under the impression that Conway was talking about nastiness such as:
sub not_unpacking {
my $result = $_[0] + $_[1];
return $result;
}
The above example is bad and hard to read, and I would never ever consider writing that in a piece of production code.
So in short, why does Perl::Critic consider my preferred way bad? Am I really committing a heinous crime unpacking by using shift?
Would this be something that people other than myself think should be brought up with the Perl::Critic maintainers?
The simple answer is that Perl::Critic is not following PBP here. The
book explicitly states that the shift idiom is not only acceptable, but
is actually preferred in some cases.
Running perlcritic with --verbose 11 explains the policies. It doesn't look like either of these explanations applies to you, though.
Always unpack #_ first at line 1, near
'sub xxx{ my $aaa= shift; my ($bbb,$ccc) = #_;}'.
Subroutines::RequireArgUnpacking (Severity: 4)
Subroutines that use `#_' directly instead of unpacking the arguments to
local variables first have two major problems. First, they are very hard
to read. If you're going to refer to your variables by number instead of
by name, you may as well be writing assembler code! Second, `#_'
contains aliases to the original variables! If you modify the contents
of a `#_' entry, then you are modifying the variable outside of your
subroutine. For example:
sub print_local_var_plus_one {
my ($var) = #_;
print ++$var;
}
sub print_var_plus_one {
print ++$_[0];
}
my $x = 2;
print_local_var_plus_one($x); # prints "3", $x is still 2
print_var_plus_one($x); # prints "3", $x is now 3 !
print $x; # prints "3"
This is spooky action-at-a-distance and is very hard to debug if it's
not intentional and well-documented (like `chop' or `chomp').
An exception is made for the usual delegation idiom
`$object->SUPER::something( #_ )'. Only `SUPER::' and `NEXT::' are
recognized (though this is configurable) and the argument list for the
delegate must consist only of `( #_ )'.
It's important to remember that a lot of the stuff in Perl Best Practices is just one guy's opinion on what looks the best or is the easiest to work with, and it doesn't matter if you do it another way. Damian says as much in the introductory text to the book. That's not to say it's all like that -- there are many things in there that are absolutely essential: using strict, for instance.
So as you write your code, you need to decide for yourself what your own best practices will be, and using PBP is as good a starting point as any. Then stay consistent with your own standards.
I try to follow most of the stuff in PBP, but Damian can have my subroutine-argument shifts and my unlesses when he pries them from my cold, dead fingertips.
As for Critic, you can choose which policies you want to enforce, and even create your own if they don't exist yet.
In some cases Perl::Critic cannot enforce PBP guidelines precisely, so it may enforce an approximation that attempts to match the spirit of Conway's guidelines. And it is entirely possible that we have misinterpreted or misapplied PBP. If you find something that doesn't smell right, please mail a bug report to bug-perl-critic#rt.cpan.org and we'll look into it right away.
Thanks,
-Jeff
I think you should generally avoid shift, if it is not really necessary!
Just ran into a code like this:
sub way {
my $file = shift;
if (!$file) {
$file = 'newfile';
}
my $target = shift;
my $options = shift;
}
If you start changing something in this code, there is a good chance you might accidantially change the order of the shifts or maybe skip one and everything goes southway. Furthermore it's hard to read - because you cannot be sure you really see all parameters for the sub, because some lines below might be another shift somewhere... And if you use some Regexes in between, they might replace the contents of $_ and weird stuff begins to happen...
A direct benefit of using the unpacking my (...) = #_ is you can just copy the (...) part and paste it where you call the method and have a nice signature :) you can even use the same variable-names beforehand and don't have to change a thing!
I think shift implies list operations where the length of the list is dynamic and you want to handle its elements one at a time or where you explicitly need a list without the first element. But if you just want to assign the whole list to x parameters, your code should say so with my (...) = #_; no one has to wonder.

How do I create new variables with indexed names in 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)

How many ways can you call a subroutine and ignore its prototype in Perl?

We should all be familiar with the problems related to prototypes in Perl. Here are the two biggies:
they don't work like prototypes in other languages, so people misunderstand them.
they don't apply to all ways of calling a subroutine.
The second item is the one I am curious about at the moment.
I know of two ways to subvert/work around/ignore prototype enforcement when calling a subroutine:
Call the sub as a method. Foo->subroutine_name();
Call the sub with a leading & sigil. &subroutine_name();
Are there any other interesting cases I've missed?
Udpate:
#brian d foy, I don't particularly want to evade prototypes, but I wondered "how many ways are there to do it?" I ask this question out of curiosity.
#jrockway, I agree with you, and I believe that you have more explicitly and more concisely described my first point regarding the problems with prototypes, that people misunderstand them. Perhaps the problem lies in programmer expectations and not in the feature. But that is really a philosophical question of the sort I don't want to have.
Call it via a subroutine reference.
sub foo($) { print "arg is $_[0]\n" }
my $sub = \&foo;
$sub->();
Call it before Perl has seen the prototype (important because perl doesn't make you declare subs before use):
foo();
sub foo($) { print "arg is $_[0]\n" }
Using the goto &name syntax.
Type-glob.
sub foo($) { print "arg is $_[0]\n" }
*foo{CODE}()
Also, consider Bar->foo() rewritten in indirect notation:
foo Bar
Any more? c'mon, bring it.

What's good practice for Perl special variables?

First off, does anyone have a comprehensive list of the Perl special variables?
Second, are there any tasks that are much easier using them? I always unset $/ to read in files all at once, and $| to automatically flush buffers, but I'm not sure of any others.
And third, should one use the Perl special variables, or be more explicit in their coding. Personally I'm a fan of using the special variables to manipulate the way code behaves, but I've heard others argue that it just confuses things.
They are all documented in perlvar.
Note that the long names are only usable if you use English qw( -no_match_vars ); first.
Always remember to local'ize your changes to the punctuation variables. Some of the punctuation variables are useful, others should not be used. For instance, $[ should never be used (it changes the base index of arrays, so local $[ = 1; will cause 1 to refer to the first item in a list or array). Others like $" are iffy. You have to balance the usefulness of not having to do the join manually. For instance, which of these is easier to understand?
local $" = " :: "; #"
my $s = "#a / #b / #c\n";
versus
my $sep = " :: ";
my $s = join(" / ", join($sep, #a), join($sep, #a), join($sep, #a)) . "\n";
or
my $s = join(" / ", map { join " :: ", #$_ }, \(#a, #b, #c)) . "\n";
1) As far as which ones I use often:
$! is quintessential for IO error handling
$# for eval error handling when calling mis-designed libraries (like database ones) whose coders weren't considerate enough to code in decent error handling other than "die"
$_ for map/grep blocks, although I 100% agree with a poster above that using it for regular code is not a good practice.
$| for flushing buffers
2) As far as using punctuation vs. English names, I'll pick on Marc Bollinger's reply above although the same rebuttal goes for anyone arguing that there's no benefit to using English names.
"if you're using Perl, you're obviously not choosing it for neophyte readability"
Marc, I find that is not always (or rather almost never) true. Then again, 99% of my Perl experience is writing production Perl code for large companies, 90% of it full fledged applications instead of 10-line hack scripts, so my analysis may not apply in other domains. The reasons such thinking as Marc's is wrong are:
Just because I'm a Perl non-neophyte (to put it mildly), some noob analyst hired a year ago - or an outsourced "genius" - is probably not. You may not want to confuse them any more than they already are. "If code was hard to write, it should be hard to read" is not exactly high on the list of good attitudes of professional developers, in any language.
When I'm up at 2am, half-asleep and troubleshooting a production problem, I really do not want to depend on the ability of my already-nearly-blind eyes to distinguish between $! and $|. Especially in a code written by before mentioned "genius" who may not have known which one of them to use and switched them around.
When I'm reading a code left unfinished by a guy who was cough "restructured" cough out of the company a year ago, I'd rather concentrate on intricacies of screwy logic than readability of the punctuation soup.
The three I use the most are $_, #_ and $!.
I like to use $_ when looping through an array, retrieving parameters (as pointed out by Motti, this is actually #_) or performing substitutions:
Example 1.1:
foreach (#items)
{
print $_;
}
Example 1.2:
my $prm1 = shift; # implicit use of #_ or #ARGV depending on context
Example 1.3:
s/" "/""/ig; # implicit use of $_
I use $! in cases like this:
Example 2.1:
open(FILE, ">>myfile") || die "Error: $!";
I do agree though, it makes the code more confusing to someone not familiar with Perl. But confusing other people is one of the joys of knowing the language! :)
Typical ones I use are $_, #_, #ARGV, $!, $/. Other ones I comment heavily.
Brad notes that $# is also a pretty common variable. (Error value from eval()).
I say use them--if you're using Perl, you're obviously not choosing it for neophyte readability. Any more-than-casual developer will likely have a browser/reference window open, and sifting through the perlvar manpage in one window is likely no less arduous than looking up definitions of (and assignments to!) global or external variables. As an example, I just recently encountered the new-in-5.10.x named capture buffers:
/^(?<myName>.*)$/;
# and later
my $capture = %+{'myName'};
And figuring out what was going on wasn't any harder than going into parlvar/perlre and reading a little bit.
I'd much rather find a bunch of wacky special vars in undocumented code than a bunch of wacky algorithms in undocumented code.