Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
May the source be with you, but remember the KISS principle ;-)
Skepticism and critical thinking is not panacea, but can help to understand the world better

Perl as powerful and flexible tool for Unix system administrators and defensive programming in Perl

Perl was developed as the language for processing logs for NSA,
then emerged as the language of choice for elite Unix sysadmins,
then enjoyed a short love affair with CGI programming but quickly was displaced by PHP
(PHP started out as a set of "Perl hacks" and cloned many Perl features),
and now returned to its roots -- it again became the language for elite Unix sysadmins


Scripting Languages

eBook: Perl for system admins

Recommended Perl Books Recommended Links Defensive programming Perl Language Perl Reference
Perl as a command line tool Perl Regular Expressions Overview of Perl regular expressions More Complex Perl Regular Expressions Perl namespaces Perl modules Subroutines and Functions Pipes
Perl Debugging Perl applications Perl One Liners HTML Matching Examples Perl IDE Perl Certification Notes on Perl Hype Perl for Win32
Perl Style Beautifiers and Pretty Printers Neatperl -- a simple Perl prettyprinter  Perl Xref Perl power tools Perl IDE and Programming Environment Perl Warts Perl Error Checklist
Larry Wall Larry Wall Articles and Interviews Perl evolution  Perl history Perl-related Humor Larry Wall On Perl, Sep 06 2002 Larry Wall Computerworld Interview, 2008 Larry Wall interview to Linux Format, Aug 14, 2009
Perl POD documentation Annotated Perl Articles Quotes Larry Wall - Wikiquote Tips Sysadmin Horror Stories Humor  


  • Anything that can go wrong will go wrong.
  • Nothing in programming is as easy as it looks. Everything takes at least twice longer than you think.
  • If there is a possibility of several things going wrong, the one that will cause the most damage will be the one to go wrong.
    • Corollary: If there is a worse time for something to go wrong, it will happen then.
  • If anything simply cannot go wrong, it will anyway. If you perceive that there are four possible ways in which a procedure can receive wrong  parameters, there is always be a fifth way.
  • Due to maintenance and enhancements which breaks conceptual integrity programs tend to degenerate from bad to worse and number of bugs in later version does not decrease. It increases.
  • If logs suggest everything seems to be going well, you have obviously overlooked something.
  • Hardware always sides with the flaws in software.
  • It is extremely difficult to make a program foolproof because fools are so ingenious.
  • Whenever you set out to do something really important, something else comes out that should be done first.
  • Every solution of a problem breeds new problems, often more nasty...

Murphy laws of engineering
(author adaptation)

Defensive programming is a style of programming which stems from programming style adopted by compiler writers who represent the elite of the programming community and includes such names as:

and many other. We can add several people who developed scripting language interpreters:

You can only design and write a few compilers from a reasonably complex language in your lifetime (Nicklaus Wirth manages to write three, and while the languages involved were not on the level of complexity of PL/1 or Perl, this probably is a record).  Besides the complexity of the code generation, hardware moves head for those years you are writing it, making some compromises during the design phase obsolete. So creating a solid architecture of a portable complier for a particular language correctly guessing trends in hardware for the next several years and writing a successful is a high art of system programming. The art which can be mastered  by a few especially gifted programmers.  

The basic idea behind this approach is to write the program like a compiler so that it is able to run properly even through unforeseen input by users. In many ways, the concept of defensive programming is much like that of defensive driving, in that it tried to anticipate problems before they arise. One common feature is the ability handle strange input without crashing or creating a disaster.

In a way, defensive programming tried to eliminate many bugs before they happen. The classic example of "non-defensive" programming is the absence of checking of a return code for an external routine or some Unix utility. This type of bugs often slips in production code and they are discovered only during production runs, possibly many years from initial release of the product, often at a great cost. Just enforcement of the rule that no external module or utility can be used without checking its return code prevent many bugs from happening. 

In general the deeper in development cycle you find the bug, the more costly it is for fix. So while defensive programming might produce some minor overhead in both source code lines count and the run time (which for system utilities does not matter at all)  it dramatically cheapens the total development costs as fewer bugs slip into most costly for detention and elimination stage: the production phase. 

That essentially means that that the program is written in such way that it is able to able to protect itself against all invalid inputs. Which is the standard behaviour of the complier, but which can be extended to other types of programs.  It also emphasizes the quality of diagnostic of wrong inputs and situations and "intelligent" dealing with those that still can guarantee the correct results.

The invalid inputs (aka bad data) can come from user input via the command line, as a result undetected errors on other parts of the program, as a special conditions related to various objects such as file (i/o error in the file, missing file, insufficient permissions, etc). Bad data can also come from other routines in your program via input parameters. Defensive programming is greatly facilitated by an awareness of specific, typical blunders (aka SNAFU),  and vulnerabilities ( for example for sysadmin scripts and utilities a collection of "Horror Stories"  exists; see for example Creative uses of rm )

In other words, defensive programming is about making the software work in a predictable manner in spite of unexpected inputs.

Another "re-incarnation" of this concept can be traced to the period of creation of ADA programming language (1977-1983) or even earlier in the context of writing real time software.   Former DOD standard for large scale safety critical software development emphasized encapsulation, data hiding, strong typing of data, minimization of dependencies between parts to minimize impact of fixes and changes. Which is the right dose (determining of which requires programming talent) can improve the quality of programs and simplify ( but not necessary shorten ) the debugging and testing stages of program development.

One typical problem in large software modification is that creating changes by person who is not the original developer often damages conceptual integrity of the product. In this case fixing one problem creates multiple others still to be detected and fixed (one step forward, two steps back).  One way to fight this problem of "increasing entropy with age" or loss of conceptual integrity is to institute a set of  sanity checks which detect abnormal parameters values (assertions or some similar mechanism). In most systems resulting overhead is negligible as such check usually are administered outside the most inner loops. but the positive effect is great. 

Many people independently came to the subset of ideas of defensive programming, so it is impossible to attribute this concept to a single author. As an example of early attempt to formulate some principles of defensive programming style we can list  Tom Christiansen recommendations (Jan 1, 1998) for Perl language. Perl does not have strict typing of variables and, by default, does not  require any declaration of variables, creating potential for misspelled variables slipping into production version of the program. (unless you use strict pragma -- the use the latter became standard in modern Perl). While they are more then 20 years old they are still relevant:  

Out of those the most interesting is taint option (strict is also interesting but it simply partially fixes oversights in the initial design of the language; Python uses more sound idea of typing values and requires explicit conversion between values of different types). Here is a quote from Perl Command-Line Options -

The final safety net is the -T option. This option puts Perl into "taint mode." In this mode, Perl inherently distrusts any data that it receives from outside the program's source -- for example, data passed in on the command line, read from a file, or taken from CGI parameters.

Tainted data cannot be used in an expression that interacts with the outside world -- for example, you can't use it in a call to system or as the name of a file to open. The full list of restrictions is given in the perlsec manual page.

In order to use this data in any of these potentially dangerous operations you need to untaint it. You do this by checking it against a regular expression. A detailed discussion of taint mode would fill an article all by itself so I won't go into any more details here, but using taint mode is a very good habit to get into -- particularly if you are writing programs (like CGI programs) that take unknown input from users.

Is Perl dying ? No, it remains an essential and very popular tool for system administrators,
probably the best second language after BASH unless you learned Python at the college

There are a lot well-meaning and not so well meaning  pundits which claim that Perl is dying, etc. But after language became widespread and complier/interpreter is still supported it can fade but never die. Just look at the Fortran.

Perl has an interesting historical path: from a language for elite system administrators to mass Web development  language and back to the tool for elite system administrators.  Several (or may be most) early adopters of Perl such as  Randal L. Schwartz  and Tom Christiansen (author of Csh Programming Considered Harmful, 1995  ) were outstanding Unix  system administrators.

Perl has an interesting historical path: from a language for elite system administrators to mass Web development language, and back to the tool for elite system administrators

Perl is here to stay at least for the community of elite Unix sysadmin (which is a large community and it is the community in which Perl started), because it is a natural fit. It was created by a sysadmin and carry a lot of commonality with classic Unix tool set. and first of all Unix shell, which is the language which all sysadmin known and use.  In this respect it beats Python and Ruby hands down. Both Python and Ruby also carry too heavy OO baggage and that's also diminishes their value as sysadmin tools -- only few tasks in system administration area can benefit from OO approach.

Unfortunately one can see that in Perl 6 Larry Wall bought  Simula -67 based OO paradigm used in Python and Ruby  "hook, line and sinker", and that was a questionable decision, making  Perl 6 "Jonny come lately" in this category.  There were several much simpler areas were Perl 5 could be more profitably be extended such as exceptions, coroutines and, especially, introducing types of variables. He also did not realize that Javascript prototypes based OO model is a much better implementation of OO then Simula-67 model. And that Perl 5 modules do 80% of what is useful in classes (namely provide a separate namespace and the ability to share variables in this namespace between several subroutines). Even primitive constructor often can be implemented as a BEGIN block.

This synergy with Unix shell and access to Unix API alone makes Perl preferable language for writing small utilities which can help of automate sysadmin tasks -- the main use of any scripting language for sysadmins. As it is partially was created as an attempt to merge shell and AWK on a new level it has strong conceptual linkage to bash.  It is , essentially Borne shell that would be created if  Stephen_R._Bourne  was replaced by the developers of AWK ;-)

As of 2019 Perl remains one of the major  scripting languages and has probably the second largest amount of production code running of any scripting language, although most of it was written a while ago. Outside system administration, few large system development projects now use Perl ( was probably the last large project of this type and it is gradually is replaced by biopython). In the past several large Web sites such as Yahoo and Amazon used Perl as the programming language. 

Perl no longer is used much for Web development, but the level of suitability to sysadmin tasks was and remain unsurpassed.  Because Python is used in Universities for teaching programming it became more popular for sysadmin tasks as well, but Perl in this niche still is superior to any viable alternative including Python.   So Python ascendance was not only due to the quality of the language and its implementation, but also due to so called "Peter Naur effect":  Peter Naur (of Algol 60 report and BNF notation fame) in his 1975 lecture  "Programming languages, natural languages, and mathematics" which later was reprinted in hypothesized that since late 70th  only those future languages what  can be thought to beginners have changes to enter the "main" programming languages space. All others are limited to niche applications.  In this sense Perl is a clear violation of Peter Naur hypothesis ;-).

Anther important factor in Perl success is that Perl is a very interesting language with highly unorthodox design, which despite its warts produced a lot of innovative, even for this day concepts. As such it is attractive to elite programmers and system administrators who can master the language complexity and benefit form its expressiveness. For example it is one of the few scripting languages which has concept of pointers as a data type, much like C. Also it is unique in a sense that has explicit directives (package) for managing namespace. Not to say an excellent access to Unix internals (Larry Wall was a "superstar" Unix system administrator and it shows)

Perl also has several very well written textbooks although latest popular O'Reilly books are mostly junk as they were captured clueless OO advocates (see Perl for system admins for extended discussion). Perl pioneered huge testing suit for the language and is very stable.   Versions 5.8.8 used in older Linux version (like RHEL 5) and version 5.10 that is used on many current Linux distributions are very stable indeed. Version 5.10 is preferable as it introduced several new features useful for sysadmin tasks and first of all state variables -- variable that can be declared in subroutines but which behave like static variable and are not reinitialized on entry to the subroutine.   Also strict mode helps to cope with the problem of contextual declaration of variables, which the source of nasty and difficult to find errors as misspelled variables are viewed as just another variable with the default initial value.

Perl script can be writing in a way when they are transparent, readable and manageable. No less so then Python scripts which typically suffer from the abuse of OO. The pervert trend of some Perl guru to push to the limit expressiveness of Perl and used difficult to comprehend idioms should be resisted.  Actually if you look at Larry Wall early scripts in Perl 4 he also abused this capability of the language, but he can be excused as a designed of the language. But people like Randal L. Schwartz who make the abuse of language expressiveness a semi-legitimate "Perl Guru" style which gave Perl a bad name should be condemned and never followed.  Here I am reminded Talleyrand advice to young diplomats "First and foremost not too much zeal".

This is a very limited effort to help Unix sysadmins to learn of Perl. It is based on my FDU lectures to CS students.   See also my ebook Introduction to Perl for Unix system administrators It discuss an approach to programming known as "defensive programming" and limits  exposure of Perl to a subset of Perl which can be called "Minimal Perl". Which is only logical as this site explicitly condemns and tries to counter "excessive complexity" drive that dominates many Perl-related sites and publications. 

For sysadmins Perl hits a "sweet spot": (a) it is available on for all Linux distributions (it is important as often in large corporate environment installation of additional languages is prohibited by the security department); (b) it integrates very well (I would say amazingly well)  in the shell environment; (c) it easily replaces multiple utilities (sed, awk, bash for longer scripts, etc.) and is uniform between different flavors of Unix solution; (d)  there are modules to interact with the entire application stack including databases.

One important advantage of Perl over Python is that is very close to shell and programming skills for shell can be reused in Perl; no so much in Python which stems from European school of language and compliers represented by Nicklaus Wirth.   Also Perl also significantly faster then Python, which carry the burden of object orientation even to single variables (creating for each of them something like inode) although on modern CPUs and for the tasks of writing utilities this is critical only for a few tasks (log processing tasks is one example). 

And if one think that Python is a "regular language" I can tell you that it is not. For example variables in Python are treated in C/Perl style -- assignment creates a copy of the variable.

a=5 # at this point b is still equal 3, like in Perl 

But for arrays and other "compound objects" this is not the case:

alist = [25,50,75,100]
blist = alist # here Python copes the reference, not the array. so change arlist[0] actually changes blist[0] too

The same is true about overall complexity of the language. The complexity of Python was just pushed into modules, it did not disappeared. And for example for string processing Python is more complex and less expressive language then Perl in which most text processing is done via regex engine.  For example, Python does not  have anything close in convenience to double quoted literals with interpolation until Python 3.6.  Only in Python 3.6+ you have something similar with f-strings:

#!/bin/env python3

job  = 'foo'
cpus = 3
print(f"job {job}")
print(f"cpus {cpus}")

In older versions of Python you need to use C-style strings with % macros. And the best way to imitate Perl/shell double quoted string changes with each major version of Python (String interpolation - Wikipedia), which tell you something about consistency:

# in all versions
   apples = 4
   print("I have %d fruits" % apples)           # implementation via % operator; no longer recommended
   print("I have %(apples)d fruits" % apples )  # name of the variable is allowed; no longer recommended

# with Python 2.6+
   print("I have {0} fruits".format(apples))    # do now this is a method
   print("I have {a} fruits".format(a=apples))  # names instead of positional numerics

# with Python 2.7+
   print("I have {} fruits".format(apples))     # positional value now can be omitted
# with Python 3.0+
    from string import Template
    s = Template('I have $frutno fruits')      # The template object
    s.substitute(frutno=apples)                # actual substitution

# or with Python 3.6+
   print(f"I have {apples} apples")             # radically new implementation based on f-string

If you want interpolation in HERE strings in Perl you do not need to do anything special -- its automatic. But with Python only version 3.6+ has some analog called triple-quoted f-string:

cpus = 3
job  = 'foo'
job {job}
cpus {cpus}''')

And if you you think that Python is logical original language superior to Perl I have a Brooklyn  bridge to sell to you. For example in Python search of the string can be performed with find method (C programmers and Perl users be  damned):

message = "hello world"
pos = message.find("lo")
If the substring is not present, find returns a value of -1 like index function in Perl.  But the find() method should be used only if you need to know the position of the substring. To check if substring is present in the string in  conditional expression you need to use the in operator. And there is also index function in Python that behave differently, just to make C -programmers crazy ;-) It throws exception if the substring is not found.  This incompatibility suggests that Python designers have very little knowledge/respect of Unix and C when they started their project.

Moreover, if one wants to to calculate the length of the string in Python, he/she needs to use len function, not length method as one would expect.

message = "hello world"
mlen = len(message)
And such "non-uniformities" and special cases are all over Python language.  Also the mere number of methods provided in for each type is overwhelming in Python. For example there are 37 (thirty seven) string methods. Perl has just a dozen string functions. Everything else is done via regular expression. Strings in Python are immutable which create performance penalty.

Evolution of Perl

Despite the slide in popularity Perl experienced since 2000 Perl and severe lack of resources for the development of the language, Perl continues to evolve and improve. Thankfully it evolves slowly, but during the last decade we got state variables (5.10) and a couple of other useful features. Along with  several useless features or features that  which many would consider redundant or even harmful and that should probably be removed from the language. The latter is due to the fact that after the create of the language steps down there is no high authority to "bless" changes for conceptual integrity. And petty people with high opinion about themselves and pretentions to become high priests of the community try to make their "scratch" by spoiling the language :-(.  This is a common, well known  problem with large open source project is which original developer stepped down and it is not limited to Perl. It is often described under the title "the loss of conceptual integrity" *the term introduced in the The Mythical Man Month by Fred Brooks. Different manifestation of the same are also known  Software Peter principle Software entropy  and  Featuritis

So far the evolution of Perl failed to resolve the most obvious problem with the language such as

Contrary to popular opinion the use of sigils in Perl is more or less logical especially for scalar variables. Sigil $ denotes derefercing. It is also undeniable that string interpolation inside double quoted string is easier with sigils. Moreover sigils also clearly demarcate variables from built-in functions and subroutines  making wting syncax coloring in editors easier.  So this particular decision withstand the test of the time.

Contrary to popular opinion, syntax of Perl 5 is pretty regular, and closely adheres to traditional C-style syntax which makes it easy to learn for both sysadmin coming from BASH or ksh and C or C++ programmers coming from respective language.  It can favorably compared with the disaster which is syntax of Borne shell.

Actually it does not  look too bad in comparison with Python which has syntax rules which are much farther from C and Unix. Python creates severe cognitive dissonance for people who program in C or C++. Especially with some decisions like usage of whitespace to determine the nesting. This decision  has serious negative effects for long multipage loops and other control constructs, forcing to make them shorter.   Not that C-style solution used in Perl is perfect (runaway unclosed '{' bracket is a huge problem with this notation), but at least it is uniform with C and C++, which is important. People who spend many years programming C or C++ have their own methods to compensate for the deficiency of this notation and accumulate tremendous skills of reading it and using it large programs. Experience that Python just sends to the dust bin.

Somehow due to his natural talent (he was never trained as a compiler writer and does not have CS degree) Larry Wall managed to avoid most classic pitfalls in creating of the syntax of the language, pitfalls in which creators on PHP readily fell ("dangling else" in PHP is one example) and from which Python suffers as well.

Just as a side note Python inherits from C usage of = for assignment and == for comparison, the blunder that has very serious consciences as for the amount of errors both in C and Perl. In Python assignment is invalid in conditional expressions, which makes it safer and eliminates this type of errors, but at the same time losing expressive power and making programs more verbose:

   if a=1 : print a
SyntaxError: invalid syntax

Perl debugger is one of better kept secrets of the language. It is an amazingly powerful tool

One of Perl’s better-kept secrets is its built-in debugger that allows developers to test their programs with ease and to rapidly track down errors in their Perl scripts. Python only recently got a semi-decent debugger. Before that the language sucked badly. PHP is another similar sicker. Actually for qualified programmer the quality of the debugger is as important if not more important then the quality of the language. In this area Perl really shines as it has powerful debugger as long as I remember (it did have it in 1994 when I started to use it)

This is a very powerful tool that unfortunately few Perl programmers (and even fewer sysadmins)  know well. It allows to create debugging scripts, create you own set of aliases for each program you debug, as well as remote debugging.  I view it a crown jewel of the Perl language environment.

While number of IDE that Perl has is less then Python you can use free Komodo editor (somewhat buggy and idiosyncratic, but OK) or  pycharm  which does not advertize its support of Perl but does it really well (and it has a free version for individual developers).  Eclipse has Perl plug-in as well.  all of them integrates with  Perl debugger.

I think the second book about the language you should read should be a book about Perl debugger (see below)

Perl is installed by default in all flavors of Linux and all other enterprise flavors of Unix (Solaris, HP-UX and AIX)

While Python is not installed by default in all major Linux distributions  too, this is not true for AIX, Solaris and HP-US.  And in highly secure environment you are prohibited installing such huge packages without jumping via so many bureaucratic hoops that you regret that you started this adventure.

Systems administrators need to deal with many repetitive tasks in a very complex, and changing environment which often includes several different flavors of Linux (RHEL and Suse) and Unix (Solaris, HP-UX and AIX). Linux has Perl installed by  default.  It is also included in all major Unix flavors but version installed might be outdated and need upgrading. For example Oracle installs Perl too, so it is automatically present on all servers with Oracle database.  Some other application install Perl too.  That means that it provides the simplest way to automate recurring tasks on multiple platforms. Among typical tasks which sysadmin need to deal with:

You definitely can greatly simplify your life as well as improve "manageability" of the servers (or group of servers) with additional Perl scripts, some written by use, some borrowed and adapted to your environment.  As long  as you still apply KISS principle and do not try to overload those scripts with "features".  Because at some point the task of maintaining the scripts became evident and unless scripts are simple the game might not worth the candles.   that's the gotchas, which catches many  sysadmin  who overreached  and added too much complexity to their scripts.  The slogan KISS can be in this contest mean: keep it simple sysadmin.

As most sysadmins already know shell, the affinity with shell is one of the major advantages of using Perl as the second scripting language for Unix sysadmin. no other language come close in this respect: Perl allow to reuse most of the key concepts of the shell.

What Softpanorama can offer to sysadmins who want to learn Perl

IMHO the main advantage of using powerful complex language like Perl is the ability to write simple programs which in the past required for sysadmin to use several languages (bash+AWK+SED). It also was created without OO which later was "bolted on". And I consider this a very important advantage for sysadmin domain of utilities. Perhaps the world has gone overboard on this object-oriented thing.  I do not see much use of it for utilities space -- they add nothing and the attempt to structure utilities in OO fashion typically backfires and leads to excessive complexity and bloat. Often it leads to the creating what is called "object oriented spaghetti".

At the same time Perl is surprisingly high level language and for writing sysadmin utilities is has higher level then Python. You do not need many tricks used in lower level languages as Perl itself provides you high level primitives for the task.

This page is linked to several sub-pages in the top "contents" table. The most important among them are:

All language have quirks, and all inflict a lot of pain before one can adapt to them. Once learned the quirks become incorporated into your understanding of the language. But there is no royal way to mastering the language. The more different is one's background is, more one needs to suffer. Generally any user of a new programming language needs to suffer a lot ;-)

Adapting to the language quirks and warts

When mastering a new language first you face a level of "cognitive overload" until the quirks of the language become easily handled by your unconscious mind. At that point, all of the sudden the quirky interaction becomes a "standard" way of performing the task. For example, regular expression syntax seems to be a weird base for serious programs, fraught with pitfalls, a big semantic mess as a result of outgrowing its primary purpose. On the other hand, in skilled hands this is a very powerful tool that can serve a reliable parser for complex data and in certain cases as a substitute for string functions such as index and substr.

There are several notable steps in adaptation to Perl idiosyncrasies for programmers who got used to other languages:

  1. Missing semicolon at the end of statement. This is a typical problem for all languages that delimit statements with the semicolon. There is something unnatural to humans in this arrangement. It looks to me that Fortran approach (statements ends at the end of the line unless the line contains  \ at the end is a better deal.  IBM PL/1 debugging  complier  designers (one of greatest teams ever to design compilers)  implemented the idea of "soft semi-colon" -- if the insertion of semicolon allow to continue parsing then correct  this error and inform the user. But this was during the day of batch compliers and this approach has its own  drawbacks, as it can introduce errors to the program due to automatic correction.

    The problem is that this error is persistent and continue to occur for highly qualified users of Perl with amazing and consistent regularity. Multiple years of using the language under the belt does not help.  One way to lessen this problem is to check for it before you submit  the script to the interpret.  Prettyprinter can label such line  too if you have your custom Prettyprinter (I have)
  2. Forgetting to put $ in front of scalar variable. This problem is aggravated if you use several language with the other that does not require this prefix. One early sign is when you start to put $ on all scalar variables automatically.  C programmer can think about $ as as a dereferencing operator to the pointer to the value of the variable. So if line is as pointer, then $line is the value of the variable referenced by this pointer.  and $$line is the second level dereferencing.

    That's easy for those people who use write their own shell scripts and generally is not a problem for sysadmins. Most mistakes when you omit $ in front of the variable are diagnosed by interpreter, but some cases like $location{city} are not. The problems arise if  along with Unix shell you use the third language, for example C.  In this case you automatically makes make mistakes, despite your experience, and you need conscious effort to avoid them all the time. This is the case with me.

  3. Using two different comparison operations, one for strings and the other for numerical values ("==" for numbers vs. eq for strings) for comparison numbers and strings.  This is design blunder Perl inherited from Unix shell.  That also makes operation "typed", which is an interesting, but very questionable approach inhereted by Perl from Shell. The problm is that the game is not worth candles -- practice convincingly had shown that this adds very little to the language power and expressivness,  but introduces nasty bugs and it is better to allow only explicit type conversions.  In case a constant is involved ( like $line == 'EOF' ) Perl provides warnings, but if two variables are involved, the interpreter does not provide any warnings, so you need to be very careful.

    Especially if you use other language in parallel with Perl. In this case such errors crop into your scripts automatically. Only if one of the operators of "==" is a string constant, meaningful automatic diagnostic can be provided.

  4. Use of "=" as equality predicate for numbers instead of ==. If you use and C-style which uses "=" for assignments you are in trouble: you can easy make an error using it instead of == in conditional. Please note that Algol60 avoided this by using := for assignment, so even early languages recognized this problem., So in away this can be viewed as a blunder in C-language design (or more correctly in PL/1 language design as C for all practical purposes is just a subset of PL/1 with pointers; and it was designed as such (PL/1 was system programming language for Multics what was the major school of programming for Thomson and Richie) 

    The pitfall of using "=" for assignment,  results in the side effect of introducing errors in comparisons in Perl, as you put "=" instead of "==".  For example,    if ($a=1)...  instead of if  ($a==1)... This problem was understood by designers on Algol 60 ( To avoid it they used := for assignment instead of plain =), which was designed is late 50th. But Perl designers followed C designers (which make this blunder, along with several other in designing C)  and naturally stepped on this rake again. With predictable result. Actually the designers of Fortran, PL/1, C (as derivative of PL/1), C++ and Java ignored this lesson (Fortran designers are actually not guilty as it predates Algol 60). But  because C  (with its derivatives such as C++ and Java) became dominant programming language we have, what we have: propagation of this blunder to many top programming languages. Now think a little, about the notion of progress in programming language design ;-)  It's sad that the design blunder about which designers knew 65 years ago still is present in the most popular languages used today ;-). In all languages that have lexical structure of C, this blunder remains one of the most rich source of subtle errors for novices. Naturally this list includes Perl. C programmers typically are already trained to be aware about  this language pitfall. But in Perl you too can use several protective measures
    1. Modify syntax highlighting in your editor  so that such cases were marked in bold red.
    2. Manually or automatically (simple regex done in the editor can detected ~ 99% of cases) reorganize such comparisons
    3. Put the constant on the left part of comparison, like in  if (1==$a)....
    4. Recent versions of Perl interpreter provide warning in this case, so checking your script with option -cw  or better using use warnings  pragma in all your scripts. It also helps if IDE provides capability to display of results of checking of syntax in one of the windows and jump to the line in code listed in the error or warning (this is a standard feature of all IDEs and actually this can be done in most editors too). 
  5. Missing closing "}" problem . This problem is typical for all C-style languages and generally requires pretty printer to spot.  But Perl interpreter has a blunder -- it does not recognize the fact that in Perl subroutines can't be nested within blocks and does not point to the first subroutine as the diagnostic point -- it points to the end of the script.  Usually you need a Prettyprinter to spot this error. In you do notr have one and do not  want to get one and learn to use it (big mistake) one of the best way to find exact point of this error is to extract suspicious section into a new file and check it separately, cutting not relevant parts, until you detect the problem. The longer the program is the more acute this problem becomes. BTW this problem was elegantly solved in PL/1 which was created in early 60th: PL/1 has labels for closing statements as in "mainloop: do... end mainloop" which close all intermediate constructs automatically. Both C and Perl failed to adopt this innovation.  Neither Perl not C also use the concept of Pascal "local numeric labels"  -- labels that exist only until they are redefined, see discussion at Knuth.

    I would way that the lack of build-in Prettyprinter in Perl is a blunder of the designers of Perl interpreter. It is understandable as Perl never enjoyed sizable material support from big corporations, but still...

  6. Missing round brackets  or unbalanced round brackets  in control statements like if, while, etc . Like "missing ';' " problem this error is persistent and does not evaporates with the increate of your Perl skills. Looks like this is a design flow of the language and you need to check you scripts for this particular error manually. Good Prettyprinter can point most of those errors because  they are more local than missing "}" error.
  7. Missing " (double quote) or ' (single quote) problem.  With good editor this is not a problem as syntax highlighting points you where the problem begins.  Perl has pragma of specified max constant length, which is one way to improve quality of detection of this error. You can also implement  program (one line sting literals only) in the interpreter, because multiline strings pretty rate in real programs.  To put multilateral string you can need to disable this pragma for the  fragment of the script where it is located.
  8. Typos in variables which creates variables used only once.  You can block this  error now with strict pragma, so it is less important unless yyou need to maintain huge legacy scripts.  Also Perl interpreter provides warnings for all such cases.  Looks like that requrement to declare all variables before use is a sound programming language design practice.  The gains from contextual  typing of variables (introduced BTW in Fortran)  do not compensate the damage from such an error.

Please note that as syntax of Perl is complex. So the diagnostic in Perl interpreter is really bad and often point to the spot far below where the error occurred.  It is nowhere near the quality of diagnostics that mainframe programmers got in IBM PL/1 diagnostic complier, which is also probably 50 years old and run on tiny by today standard machines with 256K (kilobytes, not megabytes)  of RAM and 7M (megabytes, not gigabytes, or terabytes) harddrives.  The only comfort  is that other scripting languages are even worse then Perl ;-).

Benefits that Perl brings to system administration 

All-in-all Perl is the language that fits most sysadmin needs, It' not fancy and its general usage is in decline since 2000 but fashion should never be primary factor in choosing the scripting language. Perl has stable and well tested  interpreter and is close to shell (to the extent  that most concepts of shell can be directly reused). And that's what important. As on modern servers Perl interpreter loads in a fraction of a second, Perl also allows to get rid of most usage of AWK and SED, making you environment more uniform and less complex. This is an important advantage.  Among benefits that Perl bring to system administration are

In short if make sense to learn Perl as it makes sysadmin like a lot easier. Probably more so then any other tool in sysadmin arsenal...

Perl is really great for text processing and in this particular domain is probably unmatched. For example in Python regular expressions are implemented via standard library module; they are not even a part of the language.

A warning about relative popularity

 As of 2017 Perl no longer belongs to the top 10 programming languages (Scripting languages slip in popularity, except JavaScript and Python, Infoworld, Nov 13, 2017).  It's still more popular then Visual Basic, so there nothing to worry about.  But far less then popular then Python.  Of cause popularity is not everything. Python and Perl share some characteristics, but don't exactly occupy the same niches. But it is a lot: fashion rules the programming, so this is a factor that you need consciously evaluate and be aware of.

In large enterprise environment, outside system administration area Perl now is almost invisible. Python is gaining ground in research. Mostly because universities both in the USA and Europe now teach Python in introductory classes and engineers come "knowing some Python". This looks like "Java success story" of late 1990th on new level. Like Perl, Python is also now installed on all Linux distributions by default and there are several important linux system programs written in Python (yum, Anaconda, etc) which implicitly suggest that Python has Red Hat mark of adoption/approval too (yum was originally written at Duke University Department of Physics)

So there is now a pressure to adopt Python. That's sad, because IMHO Perl is a great scripting language which can be used on many different levels, starting from AWK/SED replacement tool (this especially make sence if you use different platforms. for example their behavior differs between Mac OS X and Linux. But PERL is the same in both those environments.). Going from Perl to Python for text processing to me feels like leaving a Corvette and driving a station wagon. Python will gets you there. But it's not fun and will take more time although you probably might feel more comfortable inside.

Here is an insightful post on this topic (Which is better, Perl or Python Which one is more robust How do they compare with each other):

Joe Pepersack, Just Another Perl Hacker Answered May 30 2015

Perl is better. Perl has almost no constraints.  It's philosophy is that there is more than one way to do it (TIMTOWTDI, pronounced Tim Toady). Python artificially restricts what you can do as a programmer.  It's philosophy is that there should be one way to do it.   If you don't agree with Guido's way of doing it, you're sh*t out of luck.

Basically, Python is Perl with training wheels.   Training wheels are a great thing for a beginner, but eventually you should outgrow them.  Yes, riding without training wheels is less safe.   You can wreck and make a bloody mess of yourself.   But you can also do things that you can't do if you have training wheels.   You can go faster and do interesting and useful tricks that aren't possible otherwise. Perl gives you great power, but with great power comes great responsibility.

A big thing that Pythonistas tout as their superiority is that Python forces you to write clean code.   That's true, it does... at the point of a gun, sometimes at the detriment of simplicity or brevity.   Perl merely gives you the tools to write clean code (perltidy, perlcritic, use strict, /x option for commenting regexes) and gently encourages you to use them.

Perl gives you more than enough rope to hang yourself (and not just rope, Perl gives you bungee cords, wire, chain, string, and just about any other thing you can possibly hang yourself with).   This can be a problem.   Python was a reaction to this, and their idea of "solving" the problem was to only give you one piece of rope and make it so short you can't possibly hurt yourself with it.    If you want to tie a bungee cord around your waist and jump off a bridge, Python says "no way, bungee cords aren't allowed".  Perl says "Here you go, hope you know what you are doing... and by the way here are some things that you can optionally use if you want to be safer"

Some clear advantage of Perl:

Advantages of Python

IDE that you can use with Perl

Usage of IDE is a must in the current environment. Often sysdmins neglect this, but it does diminished their productivity. the key here is a powerful editor, built-in  remote debugger  while nice is not absolutely necessary. But ability to compare two versions, show usage of particular variable and prompt for the  write variable when writing statements are important. Show of nesting and pretty printing are also important but  can be done with the external tools.  Also important is the  ability to work with data-space (renaming varibale in files for the whole project, etc). Perl does not even ship with the "Standard IDE". But there are several usable options:

  1. Paradoxically GVIM is not that bad and can be installed both on Windows and Linux. 
  2. Padre, which is somewhat competitive with Komodo is available for free. The problem is that  but the latest binary distribution suitable for beginners is from 2012. It's still highly usable.
  3. Komodo Edit can serve as a surrogate IDE too. It is a decent editor and for Perl I would rate it slight higher then Notepad++. It does a couple slick things: support macros and support syntax checking.  
  4. pycharm -- the most popular Python IDE can work with Perl and works well. Attractive if you use some Python.  
  5. Eclipse via Perl plug-in.
  6. Visual Studio, if you already use it for other projects.  Adding Visual Studio editor support for other languages Microsoft Docs See also

My feeling is that for Perl to remain competitive IDE should be maintained and shipped along with Perl interpreter (like in Python and R distributions).  May be at the expense of some esoteric modules included in standard  library.

Books to read

Python now dominate books  on scripting languages and  number of books per year devoted to Python and available via Amazon for 2017 is at least one order of magnitude larger then the number of books devoted to Perl (quality issues aside). All this creates a real pressure to use Python everywhere, even in system administration.  But first of all very few Python books  are good. Most do not explain the language well. And the second  is that you need just a couple of them not a dozen. So while on number front Perl definitely can't compete with Python several quality books (most not from O'Reilly) are available.  i would recommend (Recommended Perl Books)

The most common versions of Perl  5 in production

RHEL 6.x now ships with Perl 5.10. Many classic Unixes still ship with Perl 5.8.8. Older versions of  Solaris and HP-US servers might have version below Perl 5.8.8 but in 2017 that's rare as most of such servers are decommissioned (typical lifespan of a server in corporate environment is 5-7 years). 

It you need compatibility with all major flavor of Unix in you scripts it is a safe bet to write for Perl 5.8.8. Such a decision virtually guarantee compatibility with all enterprise servers, except those that should be discarded 5 or 10 years ago. In other words no "state" variables, if you want "perfect" compatibility. Non perfect, but acceptable.

If you need only Linux deployment compatibility that can be achieved by using version 5.10 which allow you to use "state" variables.

If you need compatibility with linux servers only version 5.10 look like a more or less safe bet too (very few enterprise servers in 2017 are now below version RHEL 6; those typically have Perl 5.8). 

Also too high version of Perl 5 is actually not desirable --  see note about Perl 5.22. (the current version of Perl 5 is version 30).  Hopefully warts added to version 22  will be corrected based on the feedback. Here is a slide from Oct 3, 2016 by Tom Radcliffe The Perl Paradox

The problem of Perl complexity junkies

There is a type of Perl books authors that enjoy the fact that Perl is complex non-orthogonal language and like to drive this notion to the extreme. I would call them complexity junkies. Be skeptical and do not take recommendations of Perl advocates like Randal L. Schwartz  or Tom Christiansen for granted :-) Fancy idioms are very bad for novices. Please remember about KISS principle and try to write simple Perl scripts without complex regular expressions and/or fancy idioms. Some Perl gurus pathological preoccupation with idioms is definitely not healthy and is part of the problem, not a part of the solution...

We can defines three main types of Perl complexity junkies:

My issues with Perl is when people get Overly Obfuscated with their code,
because the person thinks that less characters and a few pointers makes the code faster

Please remember about KISS principle and try to write simple Perl scripts without overly complex regular expressions or fancy idioms.  If you do this Perl is great language, unmatched for sysadmin domain. Simplicity has great merits even if goes again current fancy.

Generally the problems with OO mentioned above are more fundamental than the trivial "abstraction is the enemy of convenience". It is more like that badly chosen notational abstraction at one level can lead to an inhibition of innovative notational abstraction on others. In general OO is similar to idea of "compiler-copiler" when you create a new language in such a way that it allow to compile new constructs with the existing complier.  While in some cases useful or even indispensible, there is always a price to pay for such  fancy staff.


Detecting missing semicolon problem in Perl

Some deficiencies of Perl syntax were directly inherited from C. One of the most notable "obligatory semi-colon after ach statement. Which lead to tremendous amount of errors. You can use "soft semicolon" approach (implied semicolon on line end if round brackets or similar symmetrical symbols are balanced) and put semicol on each line and then depete it on a fewline that do not need it

It is eady to implement using any editor maro (for example in vi) or as a mode of the pretty printer.

Such an approach cuts number of iteration required to get rid of syntax errors by two or three.

Avoiding mistyping "=" instead of "==" blunders by reversing comparison with the constant

One of most famous C design blunder was the introduction of a small lexical difference between assignment and comparison (remember that Algol used := for assignment; PL/1 uses = for both) caused by the design decision to make the language more compact (terminals at this type were not very reliable and number of symbols typed matter greatly. In C assignment is allowed in if statement but no attempts were made to make language more failsafe by avoiding possibility of mixing up "=" and "==". In C syntax if ($a = $b) assigns the contents of $b to a and executes the code following if b not equal to 0. It is easy to mix thing and write if ($a = $b ) instead of (if ($a == $b) which is a pretty nasty bug. You can often reverse the sequence and put constant first like in

if ( 1==$i ) ...
if ( 1=$i ) ...
does not make any sense, such a blunder will be detected on syntax level.

Locating unbalanced "}" errors using pretty printer

This is the problem with all C-style language not only Perl. Ruby managed to avoid it switching to Algol-style delimiters, Typically this is connected with your recent changes so you should know where to look. Pretty printer (even simplistic Neatperl) allows instantly detent this type of errors

If you do not access to any pretty-printer (a very sad situation indeed) use diff with the last version that complied OK (I hope you use come kind of CMS like subversion or git)

The optimal way to spot missing '}' is to use pretty printer. In the absence of pretty printer you can insert '}' in binary search fashion until you find the spot where it is missing.

You can also extract part of your script and analyze it separately, deleting "balanced" parts one by one. This error actually discourages writing very long "monolithic" Perl scripts so the is a silver lining in each dark cloud.

You can also use pseudo comments that signify nesting level zero and check those points with special program or by writing an editor macro. One also can mark closing brackets with the name of construct it is closing

if (... ) { 

} # if 

Problem of unclosed quote at the end of the line string literal ("...")

Use a good editor. moreover often you can split long literals into one line literals and concatenate them with dot operator. Perl process those at complite time so there is not run-time hit for using this (and it should not be for any other language with a decent complier -- this complier optimization is classed constant folding and is a standard in modern compliers).

As a historical note specifying max length of literals is an effecting way of catching missing quote that was implemented in PL/1 compilers. You can also have an option to limit literal to a single line. In general multi-line literals should have different lexical markers (like "here" construct in shell). Perl provides the opportunity to use concatenation operator for splitting literals into multiple line, which are "merged" at compile time, so there is no performance penalty for this constructs. But there is no limit on the number of lines string literal can occupy so this does not help much. If such limit can be communicated via pragma statement at compile type in a particular fragment of text this is an effective way to avoid the problem. Usually only few places in program use multiline literals, if any. Editors that use coloring help to detect unclosed literal problem but there are cases when they are useless.

How to avoid using wrong comparison operator comparing two variable

If you are comparing a variable and a constant Perl interpret can help you to detect this error. but if you are comparing two variable you are on your own. And I often use wrong comparison operator just out of inertia or after usage of C. the most typical for ma error is to use == for stings comparison.

One way is to comment sting comparisons and then match comments with the comparison operator used using simple macro in editor (you should use programmable editor, and vim is programmable)

Usage of different set of comparison operator for number and string comparison is probably the blunder in Perl design (which Python actually avoided) and was inherited from shell. Programmer that use other languages along with Perl are in huge disadvantage her as other language experience force them to make the same errors again and again. Even shell solution (using different enclosing brackets); it might well be that in Perl usage of ( ) for arithmetic comparison and ((...)) for string would be a better deal. They still can be used as a part of defensive programming so that you can spot inconsistencies easier

Perl as a new programming paradigm

Perl + C and, especially Perl+Unix+shell represent a new programming paradigm in which the OS became a part of your programming toolkit and which is much more productive for large class of programs that OO-style development (OO-cult ;-). It became especially convenient in virtual machine environment when application typically "owns" the machine. In this case the level of integration of the language and operating system became of paramount importance and Perl excels in this respect. You can use shell for file manipulation and pipelines, Perl for high-level data structure manipulation and C when Perl is insufficient or too slow. The latter question for complex programs is non-trivial and correct detection of bottlenecks needs careful measurements; generally Perl is fast enough for most system programs.
Exploiting high level of integration of Perl with shell and Linux is a new programming paradigm which became especially convenient in virtual machine environment when application typically "owns" the machine. In this case the level of integration of the language and operating system became of paramount importance and Perl excels in this respect. In a way it is similar to LAMP paradigm.

The key idea here is that any sufficiently flexible and programmable environment - and Perl is such an environment -- gradually begins to take on characteristics of both language and operating system as it grows. See Stevey's Blog Rants Get Famous By Not Programming for more about this effect.

Any sufficiently flexible and programmable environment - and Perl is such an environment -- gradually begins to take on characteristics of both language and operating system as it grows.

Unix shell can actually provide a good "in the large" framework of complex programming system serving as a glue for the components.

From the point of view of typical application-level programming Perl is very under appreciated and very little understood language. Almost nobody is interested in details of interpreter, where debugger is integrated with the language really brilliantly. Also namespaces in Perl and OO constructs are very unorthodox and very interesting design.

References are major Perl innovation

References are Perl innovation: classic CS view is that scripting language should not contain references (OO languages operate with references but only implicitly). Role of list construct as implicit subroutine argument list is also implemented non trivially (elements are "by reference" not "by name") and against CS orthodoxy (which favors default "by name" passing of arguments). There are many other unique things about design of Perl. All-in-all for a professional like me, who used to write compilers, Perl is one of the few relatively "new" languages that is not boring :-).

Never forget that Perl has a great debugger

The quality of the debugger for the language is as important as the quality of language itself. Perl debugger is simply great. See Debugging Perl Scripts

Brilliance of Perl Artistic license

Perl license is a real brilliance. Incredible from my point of view feat taking into account when it was done. It provided peaceful co-existence with GPL which is no small feat ;-). Dual licensing was a neat, extremely elegant cultural hack to make Perl acceptable both to businesses and the FSF.

It's very sad that there no really good into for Perl written from the point of view of CS professional despite 100 or more books published.

Perl warts

A small, crocky feature that sticks out of an otherwise clean design. Something conspicuous for localized ugliness, especially a special-case exception to a general rule. ...

Jargon File's definition of the term "wart"

Language design warts

Perl extended C-style syntax in innovative way. For example if statement always uses {} block, never an individual statement, also ; before } is optional. But it shares several C-style syntax shortcomings and introduced a couple of its own:

For a language aficionado Larry Wall make way too many blunders in the design of Perl. Which is understandable (he has no computer science background and was hacker in heart), but sad.

There are also several semantically problems with the language:

Absence of good development environment

R-language has RStudio which probably can be viewed as gold standard of minimal features needed for scripting language GUI. While RStudio has a weak editor it has syntax highlighting and integration with debugger and as such is adequate for medium scripts.

There is no similar "established" as standard de-facto GUI shipped with Perl interpreter and looks like nobody cares. That's a bad design decision although you can use Orthodox file manager (such as Midnight commander, or in Windows Far or Total Commander) as poor man IDE. Komodo Edit is more or less OK editor for Perl and is free although in no way it is full IDE.

This is not a show stopper for system administrators as they can use screen and multiple/different terminal sessions for running scripting and editing them. Also mcedit is handy and generally adequate for small scripts. To say nothing that each sysadmin know badic set of command for vi/vim, and many know it well.

But this is a problem when you try to write Perl scripts with over 1K lines which consist of multiple files. Many things in modern IDE helps to avoid typical errors (for example identifiers can be picked up from the many by right clicking, braces are easier to match if editor provide small almost invisible vertical rulers, color of the string help to detect running string constants, etc.

Currently Komodo and free Komodo editor are almost the only viable game in town.


for additional discussion.

Lost development priorities

For mature language the key area of development is not questionable enhancements, but improvement of interpreter diagnostics and efforts in preventing typical errors (which at this point are known).

Perl version 5.10 was the version when two very useful enhancement to the language were added:

Still very little was done to improve interpreter in order to help programmers to avoid most typical Perl errors. that means that the quality of the editor for Perl programmers is of paramount importance. I would recommend free Komodo editor. It allows you to see the list of already declared variables in the program and thus avoid classic "typo in the variable" type of errors.

Not all enhancements that Perl developers adopters after version 5.10 have practical value. Some, as requirement to use backslash in regular expressions number of iterations ( so that /\d{2}/ in "normal" Perl became /\d\{2}/ in version 5.22), are counterproductive. For that reason I do not recommend using version 5.22. You can also use pragma

use v5.12.0

to avoid stupid warnings version 5.20 generates.

There is no attempts to standardize Perl and do enhancements via orderly, negotiated by major stakeholders process. Like is done with C or Fortran (each 11 years; which is a very reasonable period which allow current fads to die ;-). At the same time quality of diagnostics of typical errors by Perl interpreter remains weak (it imporved with the introduction of strict though).

Support for a couple of useful pragma, for example, the ability to limit the length of string constants to a given length (for example 120) for certain parts of the script is absent. Ot something similar like "do not cross the line" limitation.

Local labels might help to close multiple level of nesting (the problem of missing curvy bracket is typical in al C-style languages)

 1:if( $i==1 ){
     if( $k==0 ){
         if ($m==0 ){
   # the curvy bracket below closes all opened clock since the local label 1

Multiple entry points into subroutines might help to organize namespaces.

Working with namespaces can and should be improved and rules for Perl namespaces should be much better better documented. Like pointers namespaces provide powerful facity to structuring language programs. which can be used with or without modules framework. this is a very nice and very powerful Perl feature that makes Perl a class or its own for experienced programmers. Please note that modules are not the only game in town. Actually the way they were constructed has some issues and (sometime stupid) overemphasis on OO only exacerbate those issues. Multiple entry points in procedures would be probably more useful and more efficient addition to the language. Additional that is very easy to implement. The desire to be like the rest of the pack often backfire... From SE point of view scripting language as VHL stands above OO in pecking order ;-). OO is mainly force feed for low level guys who suffer from Java...

Actually there are certain features that should probably be eliminated from Perl 5. For example use of unquoted words as indexes to hashes is definitely a language designers blunder and should be gone. String functions and array functions should be better unified. Exception mechanism should be introduced. Assignment in if statements should be somehow restricted. Assignment of constants to variables in if statement (and all conditions) should be flagged as a clear error (as in if ($a=5) ... ). I think latest version of Perl interpreter do this already.

Problems with Perl 5. 22

Attention: The release contains an obvious newly introduced wart in regex tokenizer, which now requires backslash for number of repetitions part of basic regex symbols. For example in case of /\d{2}/ which you now need to write /\d\{2}/ -- pretty illogical as a curvy brace here a part of \d construct, not a separate symbol (which of course should be escaped);

Looks to me like a typical SNAFU. But the problem is wider and not limited to Perl. There is generally tendency for a gradual loss of architectural integrity after the initial author is gone and there is no strong "language standard committee" which drive the language development (like in Fortran, which issues an undated version of the standard of the language each 11 years).

So some languages like Python this is still in the future, but for many older languages is is already reality and a real danger. Mechanism for preventing this are not well understood. The same situation happens with OS like Linux (systemd).

This newly introduced bug (aka feature) also affects regexes that use opening curvy bracket as a delimiter. Which is a minor but pretty annoying "change we can believe in" ;-). I think that idiosyncrasy will prevent spread this version into production version of Linux Unix for a long, long time (say 10 years) or forever. Image the task of modification of somebody else 30-50K lines Perl scripts for those warnings that heavily uses curvy braces in regex or use \d{1,3} constructs for parsing IP addresses.

This looks more and more like an artificially created year 2000 problem for Perl.

Dr. Nikolai Bezroukov

Top Visited
Past week
Past month


Old News ;-)

[Oct 22, 2019] Larry Wall Approves Re-Naming Perl 6 To Raku

Oct 22, 2019 |

( 100 hondo77 notes that Larry Wall has given his approval to the re-naming of Perl 6.

In the "Path to Raku" pull request, Larry Wall indicated his approval, leaving this comment: I am in favor of this change, because it reflects an ancient wisdom :

"No one sews a patch of unshrunk cloth on an old garment, for the patch will pull away from the garment, making the tear worse. Neither do people pour new wine into old wineskins. If they do, the skins will burst; the wine will run out and the wineskins will be ruined. No, they pour new wine into new wineskins, and both are preserved."

"Perl 6 will become Raku, assuming the four people who haven't yet approved the pull request give their okay," reports the Register, adding that Perl 5 will then become simply Perl .

Dozens of comments on that pull request have now already been marked as "outdated," and while a few contributors have made a point of abstaining from the approval process, reviewer Alex Daniel notes that "this pull request will be merged on October 14th if nobody in the list rejects it or requests more changes."

[Oct 13, 2019] What are Donald Knuth's main original contributions to computer science - Quora

Oct 13, 2019 |

Radu Grigore , argued rigor Answered Apr 22 2012 I think some of the main original contributions to Computer Science are the following:

He also did some work in mathematics. If I remember correctly, I saw him in a video saying that the article he is most proud of is The Birth of the Giant Component . Mark VandeWettering , I have a lab coat, trust me! Answered Jan 10, 2014 · Author has 7.2k answers and 23.3m answer views Knuth won the Turing Award in 1974 for his contributions to the analysis of algorithms I'd submit that his "expository" work in the form of The Art of Programming go well beyond simple exposition, and brought a rigor and precision to the analysis of algorithms which was (and probably still is) unparalleled in term of thoroughness and scope. There is more knowledge in the margins of The Art of Programming than there is in most programming courses. 1.2k views · View 7 Upvoters Eugene Miya Eugene Miya , Ex-Journal Editor, parallelism DB, committees and conferences, etc. Answered Sep 9, 2014 · Author has 11.2k answers and 7.9m answer views Everyone cites and overcites TAOCP.

Start collecting Selected Papers (in|on) ... He has 8 volumes. If you need the titles consider Amazon: Online Shopping for Electronics, Apparel, Computers, Books, DVDs & more or Barnes &Noble: Books, Textbooks, eBooks, Toys, Games & More for their ToC.

[Oct 13, 2019] 7 of the most useful Perl command line options by Gabor Szabo

Oct 13, 2019 |

-e execute code on the command line

For one-off tasks it can be very useful to be able to run a piece of Perl code without creating a file. The code itself needs to be between quotes. Due to differences between the Unix/Linux shell and the MS Windows Command prompt we need to use different quotes around our code.

On Unix/Linux systsem (including Mac OSX) it is recommended to put our code in single quotes as in the following example:

$ perl -e 'print qq{Hello World\n}'

Hello World

On MS Windows we must use double quotes around our code.

$ perl -e "print qq{Hello World\n}"

Hello World

Internally, it is probably the best to use q and qq instead of single-quote and double-quote, respectively. That might help reduce the confusion caused by the behavior of the shell and command prompt.

-E execute code on the command line with all the latest features enabled

Since version 5.10 of Perl has been released, Perl includes some additional keywords (called features) in the language. For improved backward compatibility these keywords are only enabled if the user explicitly ask for them with use feature ... . For example by writing use feature qw(say); , or by declaring a minimal version of Perl with use 5.010; .

On the command line we can achieve the same by using -E instead of -e . It will turn on all the features of the version of Perl we are currently running.

For me the most important of all these features, at least in one-liners is the say keyword introduced in perl 5.10 . It is just print with a trailing newline added. Nothing fancy, but makes the one-liners even shorter.

The above examples would look like these:


$ perl -E 'say q{Hello World}'

Hello World

MS Windows:

$ perl -E "say q{Hello World}"

Hello World

You can notice the change from qq to q . As we don't need to include a newline \n in our strings we could switch from qq to q .

-n wrap the -e/-E code in a while loop

If we provide the -n command line option it will wrap our code provided using either the -e or the -E options in a while with a diamond operator .


perl -n -E 'say if /code/' file.txt

is the same as

while (<>) {
    say if /code/;

That will go over all the lines of all the files provided on the command line (in this case it is file.txt) and print out every line that matches the /code/ regex.

-p is like -n with print $_

The -p option is very similar to the -n flag, but it also prints the content of $_ at the end of each iteration.

So we could write:

perl -p -E 's/code/foobar/' file.txt

which would become

while (<>) {

That will print the result to the screen.

-i for in-place editing

The most common use of -p is together with the -i option that provides "in-place editing". It means that instead of printing to the screen, all the output generated by our one-liner will be written back to the same file it was taken from.

So this one-liner will replace the first appearance of the string "code" by "foobar" in every line of the file "file.txt".

perl -i -p -E 's/code/foobar/' file.txt

[Oct 09, 2019] oop - Perl Importing Variables From Calling Module - Stack Overflow

Oct 09, 2019 |

Perl Importing Variables From Calling Module Ask Question Asked 9 years, 1 month ago Active 9 years, 1 month ago Viewed 4k times 0 1

Russell C. ,Aug 31, 2010 at 20:31

I have a Perl module ( that initializes a number of variables, some of which I'd like to import ($VAR2, $VAR3) into additional submodules that it might load during execution.

The way I'm currently setting up is as follows:

package Module;

use warnings;
use strict;

use vars qw($SUBMODULES $VAR1 $VAR2 $VAR3);

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw($VAR2 $VAR3);

sub new {
    my ($package) = @_;
    my $self = {};
    bless ($self, $package);
    return $self;

sub SubModules1 {
    my $self = shift;
    if($SUBMODULES->{'1'}) { return $SUBMODULES->{'1'}; }

    # Load & cache submodule
    require Module::SubModule1;
    $SUBMODULES->{'1'} = Module::SubModule1->new(@_);    
    return $SUBMODULES->{'1'};

sub SubModules2 {
    my $self = shift;
    if($SUBMODULES->{'2'}) { return $SUBMODULES->{'2'}; }

    # Load & cache submodule
    require Module::SubModule2;
    $SUBMODULES->{'2'} = Module::SubModule2->new(@_);    
    return $SUBMODULES->{'2'};

Each submodule is structured as follows:

package Module::SubModule1;

use warnings;
use strict;
use Carp;

use vars qw();

sub new {
    my ($package) = @_;
    my $self = {};
    bless ($self, $package);
    return $self;

I want to be able to import the $VAR2 and $VAR3 variables into each of the submodules without having to reference them as $Module::VAR2 and $Module::VAR3. I noticed that the calling script is able to access both the variables that I have exported in in the desired fashion but and still have to reference the variables as being from

I tried updating each submodule as follows which unfortunately didn't work I was hoping:

package Module::SubModule1;

use warnings;
use strict;
use Carp;

use vars qw($VAR2 $VAR3);

sub new {
    my ($package) = @_;
    my $self = {};
    bless ($self, $package);
    $VAR2 = $Module::VAR2;
    $VAR3 = $Module::VAR3;
    return $self;

Please let me know how I can successfully export $VAR2 and $VAR3 from into each Submodule. Thanks in advance for your help!

Russell C. ,Aug 31, 2010 at 22:37

In your submodules, are you forgetting to say
use Module;

? Calling use Module from another package (say Module::Submodule9 ) will try to run the Module::import method. Since you don't have that method, it will call the Exporter::import method, and that is where the magic that exports Module 's variables into the Module::Submodule9 namespace will happen.

In your program there is only one Module namespace and only one instance of the (global) variable $Module::VAR2 . Exporting creates aliases to this variable in other namespaces, so the same variable can be accessed in different ways. Try this in a separate script:

package Whatever;
use Module;
use strict;
use vars qw($VAR2);

$Module::VAR2 = 5;
print $Whatever::VAR2;    # should be 5.
$VAR2 = 14;               # same as $Whatever::VAR2 = 14
print $Module::VAR2;      # should be 14

Russell C. ,Aug 31, 2010 at 21:38

Well there is the easy way:


package M;

use strict;
use warnings;

#our is better than "use vars" for creating package variables
#it creates an alias to $M::foo named $foo in the current lexical scope 
our $foo = 5;

sub inM { print "$foo\n" }


In M/

package M;

#creates an alias to $M::foo that will last for the entire scope,
#in this case the entire file
our $foo;

package M::S;

use strict;
use warnings;

sub inMS { print "$foo\n" }


In the script:


use strict;
use warnings;

use M;
use M::S;


But I would advise against this. Global variables are not a good practice, and sharing global variables between modules is even worse.

[Oct 09, 2019] Package variables

Oct 09, 2019 |

These are the oldest type of variables in Perl. They are still used in some cases, even though in most cases you should just use lexical variables.

In old times, if we started to use a variable without declaring it with the my or state keywords, we automatically got a variable in the current namespace. Thus we could write:

  1. $x = 42 ;
  2. print "$x\n" ; # 42

Please note, we don't use strict; in these examples. Even though you should always use strict . We'll fix this in a bit.

The default namespace in every perl script is called "main" and you can always access variables using their full name including the namespace:

  1. $x = 42 ;
  2. print "$x\n" ; # 42
  3. print "$main::x\n" ; # 42

The package keyword is used to switch namespaces:

  1. $x = 42 ;
  2. print "$x\n" ; # 42
  3. print "$main::x\n" ; # 42
  4. package Foo ;
  5. print "Foo: $x\n" ; # Foo:

Please note, once we switched to the "Foo" namespace, the $x name refers to the variable in the Foo namespace. It does not have any value yet.

  1. $x = 42 ;
  2. print "$x\n" ; # 42
  3. print "$main::x\n" ; # 42
  4. package Foo ;
  5. print "Foo: $x\n" ; # Foo:
  6. $x = 23 ;
  7. print "Foo: $x\n" ; # Foo 23;

Do we really have two $x-es? Can we reach the $x in the main namespace while we are in the Foo namespace?

  1. $x = 42 ;
  2. print "$x\n" ; # 42
  3. print "$main::x\n" ; # 42
  4. package Foo ;
  5. print "Foo: $x\n" ; # Foo:
  6. $x = 23 ;
  7. print "Foo: $x\n" ; # Foo 23
  8. print "main: $main::x\n" ; # main: 42
  9. print "Foo: $Foo::x\n" ; # Foo: 23
  10. package main ;
  11. print "main: $main::x\n" ; # main: 42
  12. print "Foo: $Foo::x\n" ; # Foo: 23
  13. print "$x\n" ; # 42

We even switched back to the main namespace (using package main; ) and if you look closely, you can see that while we were already in the main package we could reach to the $x of the Foo package using $Foo::x but if we accessed $x without the full package name, we reach the one in the main namespace.

Every package (or namespace) can hold variables with the same name.

[Oct 09, 2019] Perl Import Package in different Namespace - Stack Overflow

Oct 09, 2019 |

Perl Import Package in different Namespace Ask Question Asked 1 year ago Active 7 months ago Viewed 150 times We're doing things differently. View all 8 job openings! 2

choroba ,Sep 28, 2018 at 22:17

is it possible to import ( use ) a perl module within a different namespace?

Let's say I have a Module A (XS Module with no methods Exported @EXPORT is empty) and I have no way of changing the module.

This Module has a Method A::open

currently I can use that Module in my main program (package main) by calling A::open I would like to have that module inside my package main so that I can directly call open

I tried to manually push every key of %A:: into %main:: however that did not work as expected.

The only way that I know to achieve what I want is by using package A; inside my main program, effectively changing the package of my program from main to A . Im not satisfied with this. I would really like to keep my program inside package main.

Is there any way to achieve this and still keep my program in package main?

Offtopic: Yes I know usually you would not want to import everything into your namespace but this module is used by us extensively and we don't want to type A:: (well the actual module name is way longer which isn't making the situation better)in front of hundreds or thousands of calls

Grinnz ,Oct 1, 2018 at 6:26

This is one of those "impossible" situations, where the clear solution -- to rework that module -- is off limits.

But, you can alias that package's subs names, from its symbol table, to the same names in main . Worse than being rude, this comes with a glitch: it catches all names that that package itself imported in any way. However, since this package is a fixed quantity it stands to reason that you can establish that list (and even hard-code it). It is just this one time, right?


use warnings;
use strict;
use feature 'say';

use OffLimits;

    # The list of names to be excluded
    my $re_exclude = qr/^(?:BEGIN|import)$/;  # ...
    my @subs = grep { !/$re_exclude/ } sort keys %OffLimits::;
    no strict 'refs';
    for my $sub_name (@subs) {
        *{ $sub_name } = \&{ 'OffLimits::' . $sub_name };

my $name = name('name() called from ' . __PACKAGE__);
my $id   = id('id() called from ' . __PACKAGE__);

say "name() returned: $name";
say "id()   returned: $id";


package OffLimits;    
use warnings;
use strict;

sub name { return "In " .  __PACKAGE__ . ": @_" }
sub id   { return "In " .  __PACKAGE__ . ": @_" }


It prints

name() returned: In OffLimits: name() called from  main
id()   returned: In OffLimits: id() called from  main

You may need that code in a BEGIN block, depending on other details.

Another option is of course to hard-code the subs to be "exported" (in @subs ). Given that the module is in practice immutable this option is reasonable and more reliable.

This can also be wrapped in a module, so that you have the normal, selective, importing.

package WrapOffLimits;
use warnings;
use strict;

use OffLimits;

use Exporter qw(import);

our @sub_names;
our @EXPORT_OK   = @sub_names;
our %EXPORT_TAGS = (all => \@sub_names);

    # Or supply a hard-coded list of all module's subs in @sub_names
    my $re_exclude = qr/^(?:BEGIN|import)$/;  # ...
    @sub_names = grep { !/$re_exclude/ } sort keys %OffLimits::;

    no strict 'refs';
    for my $sub_name (@sub_names) {
        *{ $sub_name } = \&{ 'OffLimits::' . $sub_name };

and now in the caller you can import either only some subs

use WrapOffLimits qw(name);

or all

use WrapOffLimits qw(:all);

with otherwise the same main as above for a test.

The module name is hard-coded, which should be OK as this is meant only for that module.

The following is added mostly for completeness.

One can pass the module name to the wrapper by writing one's own import sub, which is what gets used then. The import list can be passed as well, at the expense of an awkward interface of the use statement.

It goes along the lines of

package WrapModule;
use warnings;
use strict;

use OffLimits;

use Exporter qw();  # will need our own import 

our ($mod_name, @sub_names);

our @EXPORT_OK   = @sub_names;
our %EXPORT_TAGS = (all => \@sub_names);

sub import {
    my $mod_name = splice @_, 1, 1;  # remove mod name from @_ for goto

    my $re_exclude = qr/^(?:BEGIN|import)$/;  # etc

    no strict 'refs';
    @sub_names = grep { !/$re_exclude/ } sort keys %{ $mod_name . '::'};    
    for my $sub_name (@sub_names) {    
        *{ $sub_name } = \&{ $mod_name . '::' . $sub_name };

    push @EXPORT_OK, @sub_names;

    goto &Exporter::import;

what can be used as

use WrapModule qw(OffLimits name id);  # or (OffLimits :all)

or, with the list broken-up so to remind the user of the unusual interface

use WrapModule 'OffLimits', qw(name id);

When used with the main above this prints the same output.

The use statement ends up using the import sub defined in the module, which exports symbols by writing to the caller's symbol table. (If no import sub is written then the Exporter 's import method is nicely used, which is how this is normally done.)

This way we are able to unpack the arguments and have the module name supplied at use invocation. With the import list supplied as well now we have to push manually to @EXPORT_OK since this can't be in the BEGIN phase. In the end the sub is replaced by Exporter::import via the (good form of) goto , to complete the job.

Simerax ,Sep 30, 2018 at 10:19

You can forcibly "import" a function into main using glob assignment to alias the subroutine (and you want to do it in BEGIN so it happens at compile time, before calls to that subroutine are parsed later in the file):
use strict;
use warnings;
use Other::Module;

BEGIN { *open = \&Other::Module::open }

However, another problem you might have here is that open is a builtin function, which may cause some problems . You can add use subs 'open'; to indicate that you want to override the built-in function in this case, since you aren't using an actual import function to do so.

Grinnz ,Sep 30, 2018 at 17:33

Here is what I now came up with. Yes this is hacky and yes I also feel like I opened pandoras box with this. However at least a small dummy program ran perfectly fine.

I renamed the module in my code again. In my original post I used the example A::open actually this module does not contain any method/variable reserved by the perl core. This is why I blindly import everything here.

    # using the caller to determine the parent. Usually this is main but maybe we want it somewhere else in some cases
    my ($parent_package) = caller;

    package A;

    foreach (keys(%A::)) {
        if (defined $$_) {
            eval '*'.$parent_package.'::'.$_.' = \$A::'.$_;
        elsif (%$_) {
            eval '*'.$parent_package.'::'.$_.' = \%A::'.$_;
        elsif (@$_) {
            eval '*'.$parent_package.'::'.$_.' = \@A::'.$_;
        else {
            eval '*'.$parent_package.'::'.$_.' = \&A::'.$_;

[Sep 24, 2019] PARTutorial - Cross-Platform Packaging and Deployment with PAR -

Some thing like 1200 lines of Perl code... -
Sep 24, 2019 |

This is a tutorial on PAR, first appeared at the 7th Perl Conference. The HTML version of this tutorial is available online as

DESCRIPTION On Deploying Perl Applications
% -rootpw= "Z1ON0101" Perl v5.6.1 required--this is only v5.6.0, stopped at line 1. BEGIN failed--compilation aborted at line 1.
PAR, the Perl Archive Toolkit Simple Packaging PAR Loaders Dependency Scanning Perl Packager: pp How it works Aggregating multiple programs The Anatomy of a PAR file Special files Advantages over perlcc, PerlApp and Perl2exe MANIFEST: Best viewed with Mozilla META.yml: Metadata galore SIGNATURE: Signing and verifying packages Perl Servlets with Apache::PAR Hon Dah, A-par-che! On-demand library fetching Code Obfuscation Accessing packed files Packing GUI applications Precompiled CPAN distributions Platform-specific Tips Thank you! Bonus Slides: PAR Internals Overview of's Implementation Code References in @INC Source Filtering without Filter::* Modules Source Filtering without Filter::* Modules (cont.) Overriding DynaLoader::bootstrap Anatomy of a Self-Contained PAR executable Self-Bootstrapping Tricks Thank you (again)! SEE ALSO

PAR , pp , , parl

ex::lib::zip , Acme::use::strict::with::pride

App::Packer , Apache::PAR , CPANPLUS , Module::Install


Audrey Tang <>

You can write to the mailing list at <>, or send an empty mail to <> to participate in the discussion.

Please submit bug reports to <>.


Copyright 2003, 2004, 2005, 2006 by Audrey Tang <>.

This document is free documentation; you can redistribute it and/or modify it under the same terms as Perl itself.


[Sep 21, 2019] Larry Wall - Present Continuous, Future Perfect - OSDCIsrael Wiki

You can see that Larry Wall bought OO paradigm "hook, line and sinker" , and that was very bad, IMHO disastrous decision. There were several areas were Perl 5 could be more profitably be extended such as exceptions, coroutines and, especially, introducing types of variables. He also did not realize that Javascript prototypes based OO model has much better implementation of OO then Simula-67 model. And that Perl 5 modules do 80% of what is useful in classes (namely provide a separate namespace and the ability to share variables in this namespace between several subroutines)
Notable quotes:
"... Perl 5 had this problem with "do" loops because they weren't real loops - they were a "do" block followed by a statement modifier, and people kept wanting to use loop control it them. Well, we can fix that. "loop" now is a real loop. And it allows a modifier on it but still behaves as a real loop. And so, do goes off to have other duties, and you can write a loop that tests at the end and it is a real loop. And this is just one of many many many things that confused new Perl 5 programmers. ..."
"... We have properties which you can put on variables and onto values. These are generalizations of things that were special code in Perl 5, but now we have general mechanisms to do the same things, they're actually done using a mix-in mechanism like Ruby. ..."
"... Smart match operators is, like Damian say, equal-tilda ("=~") on steroids. Instead of just allowing a regular expression on the right side it allows basically anything, and it figures out that this wants to do a numeric comparison, this wants to do a string comparison, this wants to compare two arrays, this wants to do a lookup in the hash; this wants to call the closure on the right passing in the left argument, and it will tell if you if $x can quack. Now that looks a little strange because you can just say "$x.can('quack')". Why would you do it this way? Well, you'll see. ..."
Feb 26, 2006 |

Irrationalities in Other Languages (5:54)

Now, I'm not the only language designer with irrationalities. You can think of some languages to go with some of these things.

"We've got to start over from scratch" - Well, that's almost any academic language you find.

"English phrases" - We'll that's Cobol. You know, cargo cult English. ( laughter )

"Text processing doesn't matter much" - Fortran.

"Simple languages produce simple solutions" - C.

"If I wanted it fast, I'd write it in C" - That's almost a direct quote from the original awk page.

"I thought of a way to do it so it must be right" - That's obviously PHP. ( laughter and applause )

"You can build anything with NAND gates" - Any language designed by an electrical engineer. ( laughter )

"This is a very high level language, who cares about bits?" - The entire scope of fourth generation languages fell into this... problem.

"Users care about elegance" - A lot of languages from Europe tend to fall into this. You know, Eiffel.

"The specification is good enough" - Ada.

"Abstraction equals usability" - Scheme. Things like that.

"The common kernel should be as small as possible" - Forth.

"Let's make this easy for the computer" - Lisp. ( laughter )

"Most programs are designed top-down" - Pascal. ( laughter )

"Everything is a vector" - APL.

"Everything is an object" - Smalltalk and its children. (whispered:) Ruby. ( laughter )

"Everything is a hypothesis" - Prolog. ( laughter )

"Everything is a function" - Haskell. ( laughter )

"Programmers should never have been given free will" - Obviously, Python. ( laughter )

So my psychological conjecture is that normal people, if they perceive that a computer language is forcing them to learn theory, they won't like it. In other words, hide the fancy stuff. It can be there, just hide it. Fan Mail (14:42)

Q: "Dear Larry, I love Perl. It has saved my company, my crew, my sanity and my marriage. After Perl I can't imagine going back to any other language. I dream in Perl, I tell everyone else about Perl. How can you improve on perfection? Signed, Happy in Haifa."
A: "Dear Happy,
You need to recognize that Perl can be good in some dimensions and not so good in other dimensions. You also need to recognize that there will be some pain in climbing over or tunneling through the barrier to the true minimum."

Now Perl 5 has a few false minima. Syntax, semantics, pragmatics, ( laughter ), discourse structure, implementation, documentation, culture... Other than that Perl 5 is not too bad.

Q: "Dear Larry,
You have often talked about the waterbed theory of linguistic complexity, and beauty times brains equals a constant. Isn't it true that improving Perl in some areas will automatically make it worse in other areas? Signed, Terrified in Tel-Aviv."
A: "Dear Terrified,
No." ( laughter )

You see, you can make some things so they aren't any worse. For instance, we changed all the sigils to be more consistent, and they're just the same length, they're just different. And you can make some things much better. Instead of having to write all this gobbledygook to dereference references in Perl 5 you can just do it straight left to right in Perl 6. Or there's even more shortcuts, so multidimensional arrays and constant hash subscripts get their own notation, so it's even clearer, at least once you've learned it. Again, we're optimizing for expressiveness, not necessarily learnability.

Q: "Dear Larry,
I've heard a disturbing rumor that Perl 6 is turning into Java, or Python, or (whispered:) Ruby, or something. What's the point of using Perl if it's just another object-oriented language? Why are we changing the arrow operator to the dot operator? Signed, Nervous in Netanya."
A: "Dear Nervous,
First of all, we can do object orientation better without making other things worse. As I said. Now, we're changing from arrow to dot, because ... because ... Well, just 'cuz I said so!"

You know, actually, we do have some good reasons - it's shorter, it's the industry standard, I wanted the arrow for something else, and I wanted the dot as a secondary sigil. Now we can have it for attributes that have accessors. I also wanted the unary dot for topical type calls, with an assumed object on the left and finally, because I said so. Darn it.

... ... ...

No arbitrary limits round two : Perl started off with the idea that strings should grow infinitely, if you have memory. Just let's get rid of those arbitrary limits that plagued Unix utilities in the early years. Perl 6 is taking this in a number of different dimensions than just how long your strings are. No arbitrary limits - you ought to be able to program very abstractly, you ought to be able to program very concretely - that's just one dimension.

... .. ...

Perl 5 is just all full of these strange gobbledygooky variables which we all know and love - and hate. So the error variables are now unified into a single error variable. These variables have been deprecated forever, they're gone! These weird things that just drive syntax highlighters nuts ( laughter ) now actually have more regular names. The star there, $*GID, that's what we call a secondary sigil, what that just says is this is in the global namespace. So we know that that's a global variable for the entire process. Similarly for uids.

... ... ...

Perl 5 had this problem with "do" loops because they weren't real loops - they were a "do" block followed by a statement modifier, and people kept wanting to use loop control it them. Well, we can fix that. "loop" now is a real loop. And it allows a modifier on it but still behaves as a real loop. And so, do goes off to have other duties, and you can write a loop that tests at the end and it is a real loop. And this is just one of many many many things that confused new Perl 5 programmers.

... ... ...

Perl 5, another place where it was too orthogonal - we defined parameter passing to just come in as an array. You know arrays, subroutines - they're just orthogonal. You just happen to have one called @_, which your parameters come in, and it was wonderfully orthogonal, and people built all sorts of stuff on top of it, and it's another place where we are changing.

... .. ...

Likewise, if you turn them inside out - the french quotes - you can use the regular angle brackets, and yes, we did change here-docs so it does not conflict, then that's the equivalent of "qw". This qw interpolates, with single-angles it does not interpolate - that is the exact "qw".

We have properties which you can put on variables and onto values. These are generalizations of things that were special code in Perl 5, but now we have general mechanisms to do the same things, they're actually done using a mix-in mechanism like Ruby.

Smart match operators is, like Damian say, equal-tilda ("=~") on steroids. Instead of just allowing a regular expression on the right side it allows basically anything, and it figures out that this wants to do a numeric comparison, this wants to do a string comparison, this wants to compare two arrays, this wants to do a lookup in the hash; this wants to call the closure on the right passing in the left argument, and it will tell if you if $x can quack. Now that looks a little strange because you can just say "$x.can('quack')". Why would you do it this way? Well, you'll see.

... ... ..

There's a lot of cruft that we inherited from the UNIX culture and we added more cruft, and we're cleaning it up. So in Perl 5 we made the mistake of interpreting regular expressions as strings, which means we had to do weird things like back-references are \1 on the left, but they're $1 on the right, even though it means the same thing. In Perl 6, because it's just a language, (an embedded language) $1 is the back-reference. It does not automatically interpolate this $1 from what it was before. You can also get it translated to Euros I guess.

[Sep 21, 2019] Dr. Dobb's Journal February 1998 A Conversation with Larry Wall

Perl is unique complex non-orthogonal language and due to this it has unique level of expressiveness.
Also the complexity of Perl to a large extent reflect the complexity of Perl environment (which is Unix environment at the beginning, but now also Windows environment with its quirks)
Notable quotes:
"... On a syntactic level, in the particular case of Perl, I placed variable names in a separate namespace from reserved words. That's one of the reasons there are funny characters on the front of variable names -- dollar signs and so forth. That allowed me to add new reserved words without breaking old programs. ..."
"... A script is something that is easy to tweak, and a program is something that is locked in. There are all sorts of metaphorical tie-ins that tend to make programs static and scripts dynamic, but of course, it's a continuum. You can write Perl programs, and you can write C scripts. People do talk more about Perl programs than C scripts. Maybe that just means Perl is more versatile. ..."
"... A good language actually gives you a range, a wide dynamic range, of your level of discipline. We're starting to move in that direction with Perl. The initial Perl was lackadaisical about requiring things to be defined or declared or what have you. Perl 5 has some declarations that you can use if you want to increase your level of discipline. But it's optional. So you can say "use strict," or you can turn on warnings, or you can do various sorts of declarations. ..."
"... But Perl was an experiment in trying to come up with not a large language -- not as large as English -- but a medium-sized language, and to try to see if, by adding certain kinds of complexity from natural language, the expressiveness of the language grew faster than the pain of using it. And, by and large, I think that experiment has been successful. ..."
"... If you used the regular expression in a list context, it will pass back a list of the various subexpressions that it matched. A different computer language may add regular expressions, even have a module that's called Perl 5 regular expressions, but it won't be integrated into the language. You'll have to jump through an extra hoop, take that right angle turn, in order to say, "Okay, well here, now apply the regular expression, now let's pull the things out of the regular expression," rather than being able to use the thing in a particular context and have it do something meaningful. ..."
"... A language is not a set of syntax rules. It is not just a set of semantics. It's the entire culture surrounding the language itself. So part of the cultural context in which you analyze a language includes all the personalities and people involved -- how everybody sees the language, how they propagate the language to other people, how it gets taught, the attitudes of people who are helping each other learn the language -- all of this goes into the pot of context. ..."
"... In the beginning, I just tried to help everybody. Particularly being on USENET. You know, there are even some sneaky things in there -- like looking for people's Perl questions in many different newsgroups. For a long time, I resisted creating a newsgroup for Perl, specifically because I did not want it to be ghettoized. You know, if someone can say, "Oh, this is a discussion about Perl, take it over to the Perl newsgroup," then they shut off the discussion in the shell newsgroup. If there are only the shell newsgroups, and someone says, "Oh, by the way, in Perl, you can solve it like this," that's free advertising. So, it's fuzzy. We had proposed Perl as a newsgroup probably a year or two before we actually created it. It eventually came to the point where the time was right for it, and we did that. ..."
"... For most web applications, Perl is severely underutilized. Your typical CGI script says print, print, print, print, print, print, print. But in a sense, it's the dynamic range of Perl that allows for that. You don't have to say a whole lot to write a simple Perl script, whereas your minimal Java program is, you know, eight or ten lines long anyway. Many of the features that made it competitive in the UNIX space will make it competitive in other spaces. ..."
"... Over the years, much of the work of making Perl work for people has been in designing ways for people to come to Perl. I actually delayed the first version of Perl for a couple of months until I had a sed-to-Perl and an awk-to-Perl translator. One of the benefits of borrowing features from various other languages is that those subsets of Perl that use those features are familiar to people coming from that other culture. What would be best, in my book, is if someone had a way of saying, "Well, I've got this thing in Visual Basic. Now, can I just rewrite some of these things in Perl?" ..."
Feb 28, 1998 |

... ... ...

The creator of Perl talks about language design and Perl. By Eugene Eric Kim

DDJ : Is Perl 5.005 what you envisioned Perl to be when you set out to do it?

LW: That assumes that I'm smart enough to envision something as complicated as Perl. I knew that Perl would be good at some things, and would be good at more things as time went on. So, in a sense, I'm sort of blessed with natural stupidity -- as opposed to artificial intelligence -- in the sense that I know what my intellectual limits are.

I'm not one of these people who can sit down and design an entire system from scratch and figure out how everything relates to everything else, so I knew from the start that I had to take the bear-of-very-little-brain approach, and design the thing to evolve. But that fit in with my background in linguistics, because natural languages evolve over time.

You can apply biological metaphors to languages. They move into niches, and as new needs arise, languages change over time. It's actually a practical way to design a computer language. Not all computer programs can be designed that way, but I think more can be designed that way than have been. A lot of the majestic failures that have occurred in computer science have been because people thought they could design the whole thing in advance.

DDJ : How do you design a language to evolve?

LW: There are several aspects to that, depending on whether you are talking about syntax or semantics. On a syntactic level, in the particular case of Perl, I placed variable names in a separate namespace from reserved words. That's one of the reasons there are funny characters on the front of variable names -- dollar signs and so forth. That allowed me to add new reserved words without breaking old programs.

DDJ : What is a scripting language? Does Perl fall into the category of a scripting language?

LW: Well, being a linguist, I tend to go back to the etymological meanings of "script" and "program," though, of course, that's fallacious in terms of what they mean nowadays. A script is what you hand to the actors, and a program is what you hand to the audience. Now hopefully, the program is already locked in by the time you hand that out, whereas the script is something you can tinker with. I think of phrases like "following the script," or "breaking from the script." The notion that you can evolve your script ties into the notion of rapid prototyping.

A script is something that is easy to tweak, and a program is something that is locked in. There are all sorts of metaphorical tie-ins that tend to make programs static and scripts dynamic, but of course, it's a continuum. You can write Perl programs, and you can write C scripts. People do talk more about Perl programs than C scripts. Maybe that just means Perl is more versatile.

... ... ...

DDJ : Would that be a better distinction than interpreted versus compiled -- run-time versus compile-time binding?

LW: It's a more useful distinction in many ways because, with late-binding languages like Perl or Java, you cannot make up your mind about what the real meaning of it is until the last moment. But there are different definitions of what the last moment is. Computer scientists would say there are really different "latenesses" of binding.

A good language actually gives you a range, a wide dynamic range, of your level of discipline. We're starting to move in that direction with Perl. The initial Perl was lackadaisical about requiring things to be defined or declared or what have you. Perl 5 has some declarations that you can use if you want to increase your level of discipline. But it's optional. So you can say "use strict," or you can turn on warnings, or you can do various sorts of declarations.

DDJ : Would it be accurate to say that Perl doesn't enforce good design?

LW: No, it does not. It tries to give you some tools to help if you want to do that, but I'm a firm believer that a language -- whether it's a natural language or a computer language -- ought to be an amoral artistic medium.

You can write pretty poems or you can write ugly poems, but that doesn't say whether English is pretty or ugly. So, while I kind of like to see beautiful computer programs, I don't think the chief virtue of a language is beauty. That's like asking an artist whether they use beautiful paints and a beautiful canvas and a beautiful palette. A language should be a medium of expression, which does not restrict your feeling unless you ask it to.

DDJ : Where does the beauty of a program lie? In the underlying algorithms, in the syntax of the description?

LW: Well, there are many different definitions of artistic beauty. It can be argued that it's symmetry, which in a computer language might be considered orthogonality. It's also been argued that broken symmetry is what is considered most beautiful and most artistic and diverse. Symmetry breaking is the root of our whole universe according to physicists, so if God is an artist, then maybe that's his definition of what beauty is.

This actually ties back in with the built-to-evolve concept on the semantic level. A lot of computer languages were defined to be naturally orthogonal, or at least the computer scientists who designed them were giving lip service to orthogonality. And that's all very well if you're trying to define a position in a space. But that's not how people think. It's not how natural languages work. Natural languages are not orthogonal, they're diagonal. They give you hypotenuses.

Suppose you're flying from California to Quebec. You don't fly due east, and take a left turn over Nashville, and then go due north. You fly straight, more or less, from here to there. And it's a network. And it's actually sort of a fractal network, where your big link is straight, and you have little "fractally" things at the end for your taxi and bicycle and whatever the mode of transport you use. Languages work the same way. And they're designed to get you most of the way here, and then have ways of refining the additional shades of meaning.

When they first built the University of California at Irvine campus, they just put the buildings in. They did not put any sidewalks, they just planted grass. The next year, they came back and built the sidewalks where the trails were in the grass. Perl is that kind of a language. It is not designed from first principles. Perl is those sidewalks in the grass. Those trails that were there before were the previous computer languages that Perl has borrowed ideas from. And Perl has unashamedly borrowed ideas from many, many different languages. Those paths can go diagonally. We want shortcuts. Sometimes we want to be able to do the orthogonal thing, so Perl generally allows the orthogonal approach also. But it also allows a certain number of shortcuts, and being able to insert those shortcuts is part of that evolutionary thing.

I don't want to claim that this is the only way to design a computer language, or that everyone is going to actually enjoy a computer language that is designed in this way. Obviously, some people speak other languages. But Perl was an experiment in trying to come up with not a large language -- not as large as English -- but a medium-sized language, and to try to see if, by adding certain kinds of complexity from natural language, the expressiveness of the language grew faster than the pain of using it. And, by and large, I think that experiment has been successful.

DDJ : Give an example of one of the things you think is expressive about Perl that you wouldn't find in other languages.

LW: The fact that regular-expression parsing and the use of regular expressions is built right into the language. If you used the regular expression in a list context, it will pass back a list of the various subexpressions that it matched. A different computer language may add regular expressions, even have a module that's called Perl 5 regular expressions, but it won't be integrated into the language. You'll have to jump through an extra hoop, take that right angle turn, in order to say, "Okay, well here, now apply the regular expression, now let's pull the things out of the regular expression," rather than being able to use the thing in a particular context and have it do something meaningful.

The school of linguistics I happened to come up through is called tagmemics, and it makes a big deal about context. In a real language -- this is a tagmemic idea -- you can distinguish between what the conventional meaning of the "thing" is and how it's being used. You think of "dog" primarily as a noun, but you can use it as a verb. That's the prototypical example, but the "thing" applies at many different levels. You think of a sentence as a sentence. Transformational grammar was built on the notion of analyzing a sentence. And they had all their cute rules, and they eventually ended up throwing most of them back out again.

But in the tagmemic view, you can take a sentence as a unit and use it differently. You can say a sentence like, "I don't like your I-can-use-anything-like-a-sentence attitude." There, I've used the sentence as an adjective. The sentence isn't an adjective if you analyze it, any way you want to analyze it. But this is the way people think. If there's a way to make sense of something in a particular context, they'll do so. And Perl is just trying to make those things make sense. There's the basic distinction in Perl between singular and plural context -- call it list context and scalar context, if you will. But you can use a particular construct in a singular context that has one meaning that sort of makes sense using the list context, and it may have a different meaning that makes sense in the plural context.

That is where the expressiveness comes from. In English, you read essays by people who say, "Well, how does this metaphor thing work?" Owen Barfield talks about this. You say one thing and mean another. That's how metaphors arise. Or you take two things and jam them together. I think it was Owen Barfield, or maybe it was C.S. Lewis, who talked about "a piercing sweetness." And we know what "piercing" is, and we know what "sweetness" is, but you put those two together, and you've created a new meaning. And that's how languages ought to work.

DDJ : Is a more expressive language more difficult to learn?

LW: Yes. It was a conscious tradeoff at the beginning of Perl that it would be more difficult to master the whole language. However, taking another clue from a natural language, we do not require 5-year olds to speak with the same diction as 50-year olds. It is okay for you to use the subset of a language that you are comfortable with, and to learn as you go. This is not true of so many computer-science languages. If you program C++ in a subset that corresponds to C, you get laughed out of the office.

There's a whole subject that we haven't touched here. A language is not a set of syntax rules. It is not just a set of semantics. It's the entire culture surrounding the language itself. So part of the cultural context in which you analyze a language includes all the personalities and people involved -- how everybody sees the language, how they propagate the language to other people, how it gets taught, the attitudes of people who are helping each other learn the language -- all of this goes into the pot of context.

Because I had already put out other freeware projects (rn and patch), I realized before I ever wrote Perl that a great deal of the value of those things was from collaboration. Many of the really good ideas in rn and Perl came from other people.

I think that Perl is in its adolescence right now. There are places where it is grown up, and places where it's still throwing tantrums. I have a couple of teenagers, and the thing you notice about teenagers is that they're always plus or minus ten years from their real age. So if you've got a 15-year old, they're either acting 25 or they're acting 5. Sometimes simultaneously! And Perl is a little that way, but that's okay.

DDJ : What part of Perl isn't quite grown up?

LW: Well, I think that the part of Perl, which has not been realistic up until now has been on the order of how you enable people in certain business situations to actually use it properly. There are a lot of people who cannot use freeware because it is, you know, schlocky. Their bosses won't let them, their government won't let them, or they think their government won't let them. There are a lot of people who, unknown to their bosses or their government, are using Perl.

DDJ : So these aren't technical issues.

LW: I suppose it depends on how you define technology. Some of it is perceptions, some of it is business models, and things like that. I'm trying to generate a new symbiosis between the commercial and the freeware interests. I think there's an artificial dividing line between those groups and that they could be more collaborative.

As a linguist, the generation of a linguistic culture is a technical issue. So, these adjustments we might make in people's attitudes toward commercial operations or in how Perl is being supported, distributed, advertised, and marketed -- not in terms of trying to make bucks, but just how we propagate the culture -- these are technical ideas in the psychological and the linguistic sense. They are, of course, not technical in the computer-science sense. But I think that's where Perl has really excelled -- its growth has not been driven solely by technical merits.

DDJ : What are the things that you do when you set out to create a culture around the software that you write?

LW: In the beginning, I just tried to help everybody. Particularly being on USENET. You know, there are even some sneaky things in there -- like looking for people's Perl questions in many different newsgroups. For a long time, I resisted creating a newsgroup for Perl, specifically because I did not want it to be ghettoized. You know, if someone can say, "Oh, this is a discussion about Perl, take it over to the Perl newsgroup," then they shut off the discussion in the shell newsgroup. If there are only the shell newsgroups, and someone says, "Oh, by the way, in Perl, you can solve it like this," that's free advertising. So, it's fuzzy. We had proposed Perl as a newsgroup probably a year or two before we actually created it. It eventually came to the point where the time was right for it, and we did that.

DDJ : Perl has really been pigeonholed as a language of the Web. One result is that people mistakenly try to compare Perl to Java. Why do you think people make the comparison in the first place? Is there anything to compare?

LW: Well, people always compare everything.

DDJ : Do you agree that Perl has been pigeonholed?

LW: Yes, but I'm not sure that it bothers me. Before it was pigeonholed as a web language, it was pigeonholed as a system-administration language, and I think that -- this goes counter to what I was saying earlier about marketing Perl -- if the abilities are there to do a particular job, there will be somebody there to apply it, generally speaking. So I'm not too worried about Perl moving into new ecological niches, as long as it has the capability of surviving in there.

Perl is actually a scrappy language for surviving in a particular ecological niche. (Can you tell I like biological metaphors?) You've got to understand that it first went up against C and against shell, both of which were much loved in the UNIX community, and it succeeded against them. So that early competition actually makes it quite a fit competitor in many other realms, too.

For most web applications, Perl is severely underutilized. Your typical CGI script says print, print, print, print, print, print, print. But in a sense, it's the dynamic range of Perl that allows for that. You don't have to say a whole lot to write a simple Perl script, whereas your minimal Java program is, you know, eight or ten lines long anyway. Many of the features that made it competitive in the UNIX space will make it competitive in other spaces.

Now, there are things that Perl can't do. One of the things that you can't do with Perl right now is compile it down to Java bytecode. And if that, in the long run, becomes a large ecological niche (and this is not yet a sure thing), then that is a capability I want to be certain that Perl has.

DDJ : There's been a movement to merge the two development paths between the ActiveWare Perl for Windows and the main distribution of Perl. You were talking about ecological niches earlier, and how Perl started off as a text-processing language. The scripting languages that are dominant on the Microsoft platforms -- like VB -- tend to be more visual than textual. Given Perl's UNIX origins -- awk, sed, and C, for that matter -- do you think that Perl, as it currently stands, has the tools to fit into a Windows niche?

LW: Yes and no. It depends on your problem domain and who's trying to solve the problem. There are problems that only need a textual solution or don't need a visual solution. Automation things of certain sorts don't need to interact with the desktop, so for those sorts of things -- and for the programmers who aren't really all that interested in visual programming -- it's already good for that. And people are already using it for that. Certainly, there is a group of people who would be enabled to use Perl if it had more of a visual interface, and one of the things we're talking about doing for the O'Reilly NT Perl Resource Kit is some sort of a visual interface.

A lot of what Windows is designed to do is to get mere mortals from 0 to 60, and there are some people who want to get from 60 to 100. We are not really interested in being in Microsoft's crosshairs. We're not actually interested in competing head-to-head with Visual Basic, and to the extent that we do compete with them, it's going to be kind of subtle. There has to be some way to get people from the slow lane to the fast lane. It's one thing to give them a way to get from 60 to 100, but if they have to spin out to get from the slow lane to the fast lane, then that's not going to work either.

Over the years, much of the work of making Perl work for people has been in designing ways for people to come to Perl. I actually delayed the first version of Perl for a couple of months until I had a sed-to-Perl and an awk-to-Perl translator. One of the benefits of borrowing features from various other languages is that those subsets of Perl that use those features are familiar to people coming from that other culture. What would be best, in my book, is if someone had a way of saying, "Well, I've got this thing in Visual Basic. Now, can I just rewrite some of these things in Perl?"

We're already doing this with Java. On our UNIX Perl Resource Kit, I've got a hybrid language called "jpl" -- that's partly a pun on my old alma mater, Jet Propulsion Laboratory, and partly for Java, Perl...Lingo, there we go! That's good. "Java Perl Lingo." You've heard it first here! jpl lets you take a Java program and magically turn one of the methods into a chunk of Perl right there inline. It turns Perl code into a native method, and automates the linkage so that when you pull in the Java code, it also pulls in the Perl code, and the interpreter, and everything else. It's actually calling out from Java's Virtual Machine into Perl's virtual machine. And we can call in the other direction, too. You can embed Java in Perl, except that there's a bug in JDK having to do with threads that prevents us from doing any I/O. But that's Java's problem.

It's a way of letting somebody evolve from a purely Java solution into, at least partly, a Perl solution. It's important not only to make Perl evolve, but to make it so that people can evolve their own programs. It's how I program, and I think a lot of people program that way. Most of us are too stupid to know what we want at the beginning.

DDJ : Is there hope down the line to present Perl to a standardization body?

LW: Well, I have said in jest that people will be free to standardize Perl when I'm dead. There may come a time when that is the right thing to do, but it doesn't seem appropriate yet.

DDJ : When would that time be?

LW: Oh, maybe when the federal government declares that we can't export Perl unless it's standardized or something.

DDJ : Only when you're forced to, basically.

LW: Yeah. To me, once things get to a standards body, it's not very interesting anymore. The most efficient form of government is a benevolent dictatorship. I remember walking into some BOF that USENIX held six or seven years ago, and John Quarterman was running it, and he saw me sneak in, sit in the back corner, and he said, "Oh, here comes Larry Wall! He's a standards committee all of his own!"

A great deal of the success of Perl so far has been based on some of my own idiosyncrasies. And I recognize that they are idiosyncrasies, and I try to let people argue me out of them whenever appropriate. But there are still ways of looking at things that I seem to do differently than anybody else. It may well be that perl5-porters will one day degenerate into a standards committee. So far, I have not abused my authority to the point that people have written me off, and so I am still allowed to exercise a certain amount of absolute power over the Perl core.

I just think headless standards committees tend to reduce everything to mush. There is a conservatism that committees have that individuals don't, and there are times when you want to have that conservatism and times you don't. I try to exercise my authority where we don't want that conservatism. And I try not to exercise it at other times.

DDJ : How did you get involved in computer science? You're a linguist by background?

LW: Because I talk to computer scientists more than I talk to linguists, I wear the linguistics mantle more than I wear the computer-science mantle, but they actually came along in parallel, and I'm probably a 50/50 hybrid. You know, basically, I'm no good at either linguistics or computer science.

DDJ : So you took computer-science courses in college?

LW: In college, yeah. In college, I had various majors, but what I eventually graduated in -- I'm one of those people that packed four years into eight -- what I eventually graduated in was a self-constructed major, and it was Natural and Artificial Languages, which seems positively prescient considering where I ended up.

DDJ : When did you join O'Reilly as a salaried employee? And how did that come about?

LW: A year-and-a-half ago. It was partly because my previous job was kind of winding down.

DDJ : What was your previous job?

LW: I was working for Seagate Software. They were shutting down that branch of operations there. So, I was just starting to look around a little bit, and Tim noticed me looking around and said, "Well, you know, I've wanted to hire you for a long time," so we talked. And Gina Blaber (O'Reilly's software director) and I met. So, they more or less offered to pay me to mess around with Perl.

So it's sort of my dream job. I get to work from home, and if I feel like taking a nap in the afternoon, I can take a nap in the afternoon and work all night.

DDJ : Do you have any final comments, or tips for aspiring programmers? Or aspiring Perl programmers?

LW: Assume that your first idea is wrong, and try to think through the various options. I think that the biggest mistake people make is latching onto the first idea that comes to them and trying to do that. It really comes to a thing that my folks taught me about money. Don't buy something unless you've wanted it three times. Similarly, don't throw in a feature when you first think of it. Think if there's a way to generalize it, think if it should be generalized. Sometimes you can generalize things too much. I think like the things in Scheme were generalized too much. There is a level of abstraction beyond which people don't want to go. Take a good look at what you want to do, and try to come up with the long-term lazy way, not the short-term lazy way.

[Sep 21, 2019] Half my life with Perl by Randal L. Schwartz

Sep 21, 2019 |

... ... ...

Derailed to an unexpectedly good outcome

Larry Wall

Perl 1

Perl 2

Trolling Usenet

... ... ...

Birth of a camel

Writing the camel

Release the camel!

[Sep 21, 2019] How Did Perl Lose Ground to Bash?

Notable quotes:
"... It baffles me the most because the common objection to Perl is legibility. Even if you assume that the objection is made from ignorance - i.e. not even having looked at some Perl to gauge its legibility - the nonsense you see in a complex bash script is orders of magnitude worse! ..."
"... Maybe it's not reassuring to hear that, but I took an interest in Perl precisely because it's seen as an underdog and "dead" despite having experienced users and a lot of code, kind of like TCL, Prolog, or Ada. ..."
"... There's a long history of bad code written by mediocre developers who became the only one who could maintain the codebase until they no longer worked for the organization. The next poor sap to go in found a mess of a codebase and did their best to not break it further. After a few iterations, the whole thing is ready for /dev/null and Perl gets the blame. ..."
"... All in all, Perl is still my first go-to language, but there are definitely some things I wish it did better. ..."
"... The Perl leadership Osborned itself with Perl6. 20/20 hindsight says the new project should have been given a different name at conception, that way all the "watch this space -- under construction" signage wouldn't have steered people away from perfectly usable Perl5. Again, IMO. ..."
"... I don't observe the premise at all though. Is bash really gaining ground over anything recently? ..."
"... Python again is loved, because "taught by rote" idiots. Now you can give them pretty little packages. And it's no wonder they can do little better than be glorified system admins (which id rather have a real sys admin, since he's likely to understand Perl) ..."
"... Making a new language means lots of new training. Lots of profit in this. Nobody profits from writing new books on old languages. Lots of profit in general from supporting a new language. In the end, owning the language gets you profits. ..."
"... And I still don't get why tab for blocks python is even remotely more readable than Perl. ..."
"... If anything, JavaScript is pretty dang godly at what it does, I understand why that's popular. But I don't get python one bit, except to employ millions of entry level minions who can't think on their own. ..."
"... "Every teacher I know has students using it. We do it because it's an easy language, there's only one way to do it, and with whitespace as syntax it's easy to grade. We don't teach it because it is some powerful or exceptional language. " ..."
Sep 21, 2019 |

How Did Perl Lose Ground to Bash?

Setting aside Perl vs. Python for the moment, how did Perl lose ground to Bash? It used to be that Bash scripts often got replaced by Perl scripts because Perl was more powerful. Even with very modern versions of Bash, Perl is much more powerful.

The Linux Standards Base (LSB) has helped ensure that certain tools are in predictable locations. Bash has gotten a bit more powerful since the release of 4.x, sure. Arrays, handicapped to 2-D arrays, have improved somewhat. There is a native regex engine in Bash 3.x, which admit is a big deal. There is also support for hash maps.

This is all good stuff for Bash. But, none of this is sufficient to explain why Perl isn't the thing you learn after Bash, or, after Bash and Python; take your pick. Thoughts?

28 comments 75% Upvoted What are your thoughts? Log in or Sign up log in sign up Sort by

oldmanwillow21 9 points · 9 days ago

Because Perl has suffered immensely in the popularity arena and is now viewed as undesirable. It's not that Bash is seen as an adequate replacement for Perl, that's where Python has landed.

emilper 8 points · 8 days ago

How did Perl5 lose ground to anything else?


- "thou must use Moose for everything" -> "Perl is too slow" -> rewrite in Python because the architect loves Python -> Python is even slower -> architect shunned by the team and everything new written in Go, nobody dares to complain about speed now because the budget people don't trust them -> Perl is slow

- "globals are bad, singletons are good" -> spaghetti -> Perl is unreadable

- "lets use every single item from the gang of four book" -> insanity -> Perl is bad

- "we must be more OOP" -> everything is a faux object with everything else as attributes -> maintenance team quits and they all take PHP jobs, at least the PHP people know their place in the order of things and do less hype-driven-development -> Perl is not OOP enough

- "CGI is bad" -> app needs 6.54GB of RAM for one worker -> customer refuses to pay for more RAM, fires the team, picks a PHP team to do the next version -> PHP team laughs all the way to the bank, chanting "CGI is king"

recrof 2 points · 8 days ago

"CGI is bad" is real. PSGI or FCGI is much faster for web services, and if there are memory leaks, it's always possible to debug & fix them.

Grinnz 6 points · 8 days ago

CGI is fine, when it's all you need. There are many different use cases out there. Just don't use .

emilper 2 points · 7 days ago

memory leaks

memory leaks ... do huge monoliths count as "memory leaks" ?

Altreus 7 points · 8 days ago

It baffles me the most because the common objection to Perl is legibility. Even if you assume that the objection is made from ignorance - i.e. not even having looked at some Perl to gauge its legibility - the nonsense you see in a complex bash script is orders of magnitude worse!

Not to mention its total lack of common language features like first-class data and... Like, a compiler...

I no longer write bash scripts because it takes about 5 lines to become unmaintainable.

crashorbit 5 points · 9 days ago

Every language that reaches functional equity with Perl is perceived as better than it. Mostly because hey, at least it's not Perl.

oldmanwillow21 15 points · 9 days ago · edited 9 days ago

Jumbled mess of thoughts surely to follow.

When I discuss projects with peers and mention that I chose to develop in Perl, the responses range from passive bemusement, to scorn, to ridicule. The assumption is usually that I'm using a dead language that's crippled in functionality and uses syntax that will surely make everyone's eyes bleed to read. This is the culture everywhere from the casual hackers to the C-suite.

I've proven at work that I can write nontrivial software using Perl. I'm still asked to use Python or Go (edit: or node, ugh) for any project that'll have contributors from other teams, or to containerize apps using Docker to remove the need for Perl knowledge for end-users (no CPAN, carton, etc.). But I'll take what I can get, and now the attitude has gone from "get with the times" or "that's cute", to "ok but I don't expect everyone else to know it".

Perl has got a lot to offer, and I vastly enjoy using it over other languages I work with. I know that all the impassioned figures in the Perl community love it just the same, but the community's got some major fragmentation going on. I understand that everyone's got ideas about the future of the language, but is this really the best time to pull the community apart? I feel like if everyone was able to let go of their ego and put their heads together to bring us to a point of stability, even a place where we're not laughed at for professing our support for the language, it would be a major step in the right direction. I think we're heading to the bottom fast, otherwise.

In that spirit of togetherness, I think the language, particularly the community, needs to be made more accessible to newcomers. Not accessible to one Perl offshoot, but accessible to Perl. It needs to be decided what Perl means in today's day and age. What can it do? Why would I want to use it over another shiny language? What are the definitive places I can go to learn more? Who else will be there? How do I contribute and grow as a Perl developer? There need to be people talking about Perl in places that aren't necessarily hubs for other Perl enthusiasts. It needs to be something business decision-makers can look at and feel confident in using.

I really hope something changes. I'd be pretty sad if I had to spend the rest of my career writing whatever the trendy language of the day is. These are just observations from someone that likes writing Perl and has been watching from the sidelines.

PhloxPaniculata 2 points · 7 days ago

Maybe it's not reassuring to hear that, but I took an interest in Perl precisely because it's seen as an underdog and "dead" despite having experienced users and a lot of code, kind of like TCL, Prolog, or Ada.

Being able to read Modern Perl for free also helped a lot. I'm still lacking experience in Perl and I've yet to write anything of importance in it because I don't see an area in which it's clearly better than anything else, either because of the language, a package, or a framework, and I don't do a lot of text-munging anymore (I'm also a fan of awk so for small tasks it has the priority).

codon011 1 point · 9 days ago

Don't call it Perl. Unfortunately. Also IME multitasking in Perl5 (or the lack thereof and/or severe issues with) has been a detriment to it's standing in a "multithread all the things" world.

crashorbit 4 points · 8 days ago

So often I see people drag themselves down that "thread my app" path. Eventually realize that they are implementing a whole multi-processing operating system inside their app rather than taking advantage of the perfectly good one they are running on.

There are several perfectly good ways to do concurrency, multitasking, async IO and so on in perl. Many work well in the single node case and in the multi-node case. Anyone who tells you that multitasking systems are easy because of some implementation language choice has not made it through the whole Dunning Kruger cycle yet.

codon011 2 points · 8 days ago

Multithreading is never easy. The processors will always manage to do things in a "wrong" order unless you are very careful with your gatekeeping. However, other languages/frameworks have paradigms that make it seem easier such that those race conditions show up much later in your product lifecycle.

codon011 3 points · 9 days ago

There's a long history of bad code written by mediocre developers who became the only one who could maintain the codebase until they no longer worked for the organization. The next poor sap to go in found a mess of a codebase and did their best to not break it further. After a few iterations, the whole thing is ready for /dev/null and Perl gets the blame.

Bash has limitations, but that (usually) means fewer ways to mess it up. There's less domain knowledge to learn, (afaik) no CPAN equivalent, and fewer issues with things like "I need to upgrade this but I can't because this other thing uses this older version which is incompatible with the newer version so now we have to maintain two versions of the library and/or interpreter."

All in all, Perl is still my first go-to language, but there are definitely some things I wish it did better.

crb3 3 points · 9 days ago · edited 9 days ago

*[e:] Consider, not just core here, but CPAN pull-in as well. I had one project clobbered on a smaller-memory machine when I tried to set up a pure-Perl scp transfer -- there wasn't room enough for the full file to transfer if it was larger than about 50k, what with all the CPAN. Shelling to commandline scp worked just fine.

beermad 2 points · 8 days ago

To be fair, wrapping a Perl script around something that's (if I read your comment right) just running SCP is adding a pointless extra layer of complexity anyway.

It's a matter of using the best tool for each particular job, not just sticking with one. My own ~/bin directory has a big mix of Perl and pure shell, depending on the complexity of the job to be done.

crb3 2 points · 8 days ago · edited 7 days ago

Agreed; I brought that example up to illustrate the bulk issue. In it, I was feeling my way, not sure how much finagling I might have to do for the task (backdoor-passing legitimate sparse but possibly quite bulky email from one server to another), which is why I initially went for the pure-Perl approach, so I'd have the mechanics exposed for any needed hackery. The experience taught me to get by more on shelling to precompiled tooling where appropriate... and a healthy respect for CPAN pull-in, [e:] the way that this module depends on that module so it gets pulled in along with its dependencies in turn, and the pileup grows in memory. There was a time or two here and there where I only needed a teeny bit of what a module does, so I went in and studied the code, then implemented it internally as a function without the object's generalities and bulk. The caution learned on ancient x86 boxes now seems appropriate on ARM boards like rPi; what goes around comes around.

minimim 1 point · 4 days ago

wouldn't have steered people away from perfectly usable Perl5

Perl5 development was completely stalled at the time. Perl6 brought not only new blood into it's own effort, it reinvigorated Perl5 in the process.

It's completely backwards to suggest Perl 5 was fine until perl6 came along. It was almost dormant and became a lively language after Perl 6 was announced.

perlancar 2 points · 8 days ago

I don't observe the premise at all though. Is bash really gaining ground over anything recently? l

linearblade 3 points · 8 days ago

Perl is better than pretty much everything g out there at what it does.

But keep in mind,

They say C sharp is loved by everyone, when in reality it's Microsoft pushing their narrative and the army of "learn by rote" engineers In developing countries

Python again is loved, because "taught by rote" idiots. Now you can give them pretty little packages. And it's no wonder they can do little better than be glorified system admins (which id rather have a real sys admin, since he's likely to understand Perl)

Making a new language means lots of new training. Lots of profit in this. Nobody profits from writing new books on old languages. Lots of profit in general from supporting a new language. In the end, owning the language gets you profits.

And I still don't get why tab for blocks python is even remotely more readable than Perl.

If anything, JavaScript is pretty dang godly at what it does, I understand why that's popular. But I don't get python one bit, except to employ millions of entry level minions who can't think on their own.

duo-rotae 6 points · 8 days ago

I know a comp sci professor. I asked why he thought Python was so popular.

"Every teacher I know has students using it. We do it because it's an easy language, there's only one way to do it, and with whitespace as syntax it's easy to grade. We don't teach it because it is some powerful or exceptional language. "

Then he said if he really needs to get something done, it's Perl or C.

linearblade 2 points · 8 days ago

Yep that's pretty much my opinion from using it.

techsnapp 1 point · 2 days ago

So is per harder than python because the lack of everyone else using it?

duo-rotae 1 point · 2 days ago

Perl has a steeper and longer learning with it. curve than Python, and there is more than one way to do anything. And there quite a few that continue coding

[Sep 21, 2019] Perl 5 Regex Cheat sheet by Gabor Szabo

Sep 21, 2019 |

... ... ... Character Classes

Regex Character Classes and Special Character classes .

   [bgh.]      One of the characters listed in the character class b,g,h or . in this case.
   [b-h]       The same as [bcdefgh].
   [a-z]       Lower case Latin letters.
   [bc-]       The characters b, c or - (dash).
   [^bx]       Complementary character class. Anything except b or x.
   \w          Word characters: [a-zA-Z0-9_].
   \d          Digits: [0-9]
   \s          [\f\t\n\r ] form-feed, tab, newline, carriage return and SPACE
   \W          The complementary of \w: [^\w]
   \D          [^\d]
   \S          [^\s]
   [:class:]   POSIX character classes (alpha, alnum...)
   \p{...}     Unicode definitions (IsAlpha, IsLower, IsHebrew, ...)
   \P{...}     Complementary Unicode character classes.
TODO: add examples \w and \d matching unicode letters and numebers. Quantifiers

Regex Quantifiers

   a?          0-1         'a' characters
   a+          1-infinite  'a' characters
   a*          0-infinite  'a' characters
   a{n,m}      n-m         'a' characters
   a{n,}       n-infinite  'a' characters
   a{n}        n           'a' characters
"Quantifier-modifier" aka. Minimal Matching

   |           Alternation
Grouping and capturing
   (...)                Grouping and capturing
   \1, \2, \3, \4 ...   Capture buffers during regex matching
   $1, $2, $3, $4 ...   Capture variables after successful matching

   (?:...)              Group without capturing (don't set \1 nor $1)
   ^           Beginning of string (or beginning of line if /m enabled)
   $           End of string (or end of line if /m enabled)
   \A          Beginning of string
   \Z          End of string (or before new-line)
   \z          End of string
   \b          Word boundary (start-of-word or end-of-word)
   \G          Match only at pos():  at the end-of-match position of prior m//g
  /m           Change ^ and $ to match beginning and end of line respectively
  /s           Change . to match new-line as well
  /i           Case insensitive pattern matching
  /x           Extended pattern (disregard white-space, allow comments starting with #)
  (?#text)             Embedded comment
  (?adlupimsx-imsx)    One or more embedded pattern-match modifiers, to be turned on or off.
  (?:pattern)          Non-capturing group.
  (?|pattern)          Branch test.
  (?=pattern)          A zero-width positive look-ahead assertion.
  (?!pattern)          A zero-width negative look-ahead assertion.
  (?<=pattern)         A zero-width positive look-behind assertion.
  (?<!pattern)         A zero-width negative look-behind assertion.
  (?<NAME>pattern)     A named capture group.
  \k'NAME'             Named backreference.
  (?{ code })          Zero-width assertion with code execution.
  (??{ code })         A "postponed" regular subexpression with code execution.
Other Regex related articles Official documentation

[Sep 21, 2019] Writing PERL Modules - Tutorialspoint

Sep 21, 2019 |

What are Packages?

The Package Statement
$i = 1; print "$i\n"; # Prints "1"
package foo;
$i = 2; print "$i\n"; # Prints "2"
package main;
print "$i\n"; # Prints "1"

For Example:
$i = 1; print "$i\n"; # Prints "1"
package foo;
$i = 2; print "$i\n"; # Prints "2"
package main;
print "$i\n"; # Prints "1"

print "$foo::i\n"; # Prints "2"
BEGIN and END Blocks

You may define any number of code blocks named BEGIN and END which act as constructors and destructors respectively.

BEGIN { ... }
END { ... }
BEGIN { ... }
END { ... }
What are Perl Modules?

A Perl module is a reusable package defined in a library file whose name is the same as the name of the package (with a .pm on the end).

A Perl module file called "" might contain statements like this.


package Foo;
sub bar { 
   print "Hello $_[0]\n" 

sub blat { 
   print "World $_[0]\n" 

Few noteable points about modules

The Require Function

A module can be loaded by calling the require function


require Foo;

Foo::bar( "a" );
Foo::blat( "b" );

Notice above that the subroutine names must be fully qualified (because they are isolated in their own package)

It would be nice to enable the functions bar and blat to be imported into our own namespace so we wouldn't have to use the Foo:: qualifier.

The Use Function

A module can be loaded by calling the use function


use Foo;

bar( "a" );
blat( "b" );

Notice that we didn't have to fully qualify the package's function names?

The use function will export a list of symbols from a module given a few added statements inside a module

require Exporter;
@ISA = qw(Exporter);

Then, provide a list of symbols (scalars, lists, hashes, subroutines, etc) by filling the list variable named @EXPORT : For Example

package Module;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(bar blat);

sub bar { print "Hello $_[0]\n" }
sub blat { print "World $_[0]\n" }
sub splat { print "Not $_[0]\n" }  # Not exported!

Create the Perl Module Tree

When you are ready to ship your PERL module then there is standard way of creating a Perl Module Tree. This is done using h2xs utility. This utility comes alongwith PERL. Here is the syntax to use h2xs

$h2xs -AX -n  Module Name

# For example, if your module is available in file
$h2xs -AX -n Person

This will produce following result
Writing Person/lib/
Writing Person/Makefile.PL
Writing Person/README
Writing Person/t/Person.t
Writing Person/Changes
Writing Person/MANIFEST

Here is the descritpion of these options

So above command creates the following structure inside Person directory. Actual result is shown above.

So finally you tar this directory structure into a file Person.tar and you can ship it. You would have to update README file with the proper instructions. You can provide some test examples files in t directory.

Installing Perl Module

Installing a Perl Module is very easy. Use the following sequence to install any Perl Module.

perl Makefile.PL
make install

The Perl interpreter has a list of directories in which it searches for modules (global array @INC)

[Sep 21, 2019] Namespaces

Sep 21, 2019 |

Coping with Scoping

© Copyright 1998 The Perl Journal. Reprinted with permission.

Cet article est également disponible en Français

Questo articolo è disponibile anche in Italiano

Dieser Artikel ist auch in deutscher Übersetzung verfügbar

Just the FAQs: Coping with Scoping

In the Beginning, some time around 1960, every part of your program had access to all the variables in every other part of the program. That turned out to be a problem, so language designers invented local variables, which were visible in only a small part of the program. That way, programmers who used a variable x could be sure that nobody was able to tamper with the contents of x behind their back. They could also be sure that by using x they weren't tampering with someone else's variable by mistake.

Every programming language has a philosophy, and these days most of these philosophies have to do with the way the names of variables are managed. Details of which variables are visible to which parts of the program, and what names mean what, and when, are of prime importance. The details vary from somewhat baroque, in languages like Lisp, to extremely baroque, in languages like C++. Perl unfortunately, falls somewhere towards the rococo end of this scale.

The problem with Perl isn't that it has no clearly-defined system of name management, but rather that it two systems, both working at once. Here's the Big Secret about Perl variables that most people learn too late: Perl has two completely separate, independent sets of variables. One is left over from Perl 4, and the other is new. The two sets of variables are called `package variables' and `lexical variables', and they have nothing to do with each other.

Package variables came first, so we'll talk about them first. Then we'll see some problems with package variables, and how lexical variables were introduced in Perl 5 to avoid these problems. Finally, we'll see how to get Perl to automatically diagnose places where you might not be getting the variable you meant to get, which can find mistakes before they turn into bugs.

Package Variables
        $x = 1

Here, $x is a package variable . There are two important things to know about package variables:

  1. Package variables are what you get if you don't say otherwise.
  2. Package variables are always global.

Global means that package variables are always visible everywhere in every program. After you do $x = 1 , any other part of the program, even some other subroutine defined in some other file, can inspect and modify the value of $x . There's no exception to this; package variables are always global.

Package variables are divided into families, called packages . Every package variable has a name with two parts. The two parts are analogous to the variable's given name and family name. You can call the Vice-President of the United States `Al', if you want, but that's really short for his full name, which is `Al Gore'. Similarly, $x has a full name, which is something like $main::x . The main part is the package qualifier , analogous to the `Gore' part of `Al Gore'. Al Gore and Al Capone are different people even though they're both named `Al'. In the same way, $Gore::Al and $Capone::Al are different variables, and $main::x and $DBI::x are different variables.

You're always allowed to include the package part of the variable's name, and if you do, Perl will know exactly which variable you mean. But for brevity, you usually like to leave the package qualifier off. What happens if you do?

The Current Package

If you just say $x , perl assumes that you mean the variable $x in the current package. What's the current package? It's normally main , but you can change the current package by writing

        package Mypackage;

in your program; from that point on, the current package is Mypackage . The only thing the current package does is affect the interpretation of package variables that you wrote without package names. If the current package is Mypackage , then $x really means $Mypackage::x . If the current package is main , then $x really means $main::x.

If you were writing a module, let's say the MyModule module, you would probably put a line like this at the top of the module file:

        package MyModule;

From there on, all the package variables you used in the module file would be in package MyModule , and you could be pretty sure that those variables wouldn't conflict with the variables in the rest of the program. It wouldn't matter if both you and the author of DBI were to use a variable named $x , because one of those $x es would be $MyModule::x and the other would be $DBI::x .

Remember that package variables are always global. Even if you're not in package DBI, even if you've never heard of package DBI, nothing can stop you from reading from or writing to $DBI::errstr . You don't have to do anything special. $DBI::errstr , like all package variables, is a global variable, and it's available globally; all you have to do is mention its full name to get it. You could even say

        package DBI;
        $errstr = 'Ha ha Tim!';

and that would modify $DBI::errstr .

Package Variable Trivia

There are only three other things to know about package variables, and you might want to skip them on the first reading:

  1. The package with the empty name is the same as main . So $::x is the same as $main::x for any x .
  2. Some variables are always forced to be in package main. For example, if you mention %ENV , Perl assumes that you mean %main::ENV , even if the current package isn't main . If you want %Fred::ENV , you have to say so explicitly, even if the current package is Fred . Other names that are special this way include INC , all the one-punctuation-character names like $_ and $$ , @ARGV , and STDIN , STDOUT , and STDERR .
  3. Package names, but not variable names, can contain :: . You can have a variable named $DBD::Oracle::x. This means the variable x in the package DBD::Oracle ; it has nothing at all to do with the package DBD which is unrelated. Isaac Newton is not related to Olivia Newton-John, and Newton::Isaac is not related to Newton::John::Olivia . Even though it appears that they both begin with Newton , the appearance is deceptive. Newton::John::Olivia is in package Newton::John , not package Newton.

That's all there is to know about package variables.

Package variables are global, which is dangerous, because you can never be sure that someone else isn't tampering with them behind your back. Up through Perl 4, all variables were package variables, which was worrisome. So Perl 5 added new variables that aren't global.

Lexical Variables

Perl's other set of variables are called lexical variables (we'll see why later) or private variables because they're private. They're also sometimes called my variables because they're always declared with my . It's tempting to call them `local variables', because their effect is confined to a small part of the program, but don't do that, because people might think you're talking about Perl's local operator, which we'll see later. When you want a `local variable', think my , not local .

The declaration

        my $x;

creates a new variable, named x , which is totally inaccessible to most parts of the program---anything outside the block where the variable was declared. This block is called the scope of the variable. If the variable wasn't declared in any block, its scope is from the place it was declared to the end of the file.

You can also declare and initialize a my variable by writing something like

        my $x = 119;

You can declare and initialize several at once:

        my ($x, $y, $z, @args) = (5, 23, @_);

Let's see an example of where some private variables will be useful. Consider this subroutine:

        sub print_report {
          @employee_list = @_;
          foreach $employee (@employee_list) {
            $salary = lookup_salary($employee);
            print_partial_report($employee, $salary);

If lookup_salary happens to also use a variable named $employee , that's going to be the same variable as the one used in print_report , and the works might get gummed up. The two programmers responsible for print_report and lookup_salary will have to coordinate to make sure they don't use the same variables. That's a pain. In fact, in even a medium-sized project, it's an intolerable pain.

The solution: Use my variables:

        sub print_report {
          my @employee_list = @_;
          foreach my $employee (@employee_list) {
            my $salary = lookup_salary($employee);
            print_partial_report($employee, $salary);

my @employee_list creates a new array variable which is totally inaccessible outside the print_report function. for my $employee creates a new scalar variable which is totally inaccessible outside the foreach loop, as does my $salary . You don't have to worry that the other functions in the program are tampering with these variables, because they can't; they don't know where to find them, because the names have different meanings outside the scope of the my declarations. These `my variables' are sometimes called `lexical' because their scope depends only on the program text itself, and not on details of execution, such as what gets executed in what order. You can determine the scope by inspecting the source code without knowing what it does. Whenever you see a variable, look for a my declaration higher up in the same block. If you find one, you can be sure that the variable is inaccessible outside that block. If you don't find a declaration in the smallest block, look at the next larger block that contains it, and so on, until you do find one. If there is no my declaration anywhere, then the variable is a package variable.

my variables are not package variables. They're not part of a package, and they don't have package qualifiers. The current package has no effect on the way they're interpreted. Here's an example:

        my $x = 17;

        package A;
        $x = 12;

        package B;
        $x = 20;

        # $x is now 20.
        # $A::x and $B::x are still undefined

The declaration my $x = 17 at the top creates a new lexical variable named x whose scope continues to the end of the file. This new meaning of $x overrides the default meaning, which was that $x meant the package variable $x in the current package.

package A changes the current package, but because $x refers to the lexical variable, not to the package variable, $x=12 doesn't have any effect on $A::x . Similarly, after package B , $x=20 modifies the lexical variable, and not any of the package variables.

At the end of the file, the lexical variable $x holds 20, and the package variables $main::x , $A::x , and $B::x are still undefined. If you had wanted them, you could still have accessed them by using their full names.

The maxim you must remember is:

Package variables are global variables.
For private variables, you must use my .

local and my

Almost everyone already knows that there's a local function that has something to do with local variables. What is it, and how does it related to my ? The answer is simple, but bizarre:

my creates a local variable. local doesn't.

First, here's what local $x really does: It saves the current value of the package variable $x in a safe place, and replaces it with a new value, or with undef if no new value was specified. It also arranges for the old value to be restored when control leaves the current block. The variables that it affects are package variables, which get local values. But package variables are always global, and a local package variable is no exception. To see the difference, try this:

        $lo = 'global';
        $m  = 'global';

        sub A {
          local $lo = 'AAA';
          my    $m  = 'AAA';

        sub B {
          print "B ", ($lo eq 'AAA' ? 'can' : 'cannot') ,
                " see the value of lo set by A.\n";

          print "B ", ($m  eq 'AAA' ? 'can' : 'cannot') ,
                " see the value of m  set by A.\n";

This prints

        B can see the value of lo set by A.
        B cannot see the value of m  set by A.

What happened here? The local declaration in A saved a new temporary value, AAA , in the package variable $lo . The old value, global , will be restored when A returns, but before that happens, A calls B . B has no problem accessing the contents of $lo , because $lo is a package variable and package variables are always available everywhere, and so it sees the value AAA set by A .

In contrast, the my declaration created a new, lexically scoped variable named $m , which is only visible inside of function A . Outside of A , $m retains its old meaning: It refers the the package variable $m ; which is still set to global . This is the variable that B sees. It doesn't see the AAA because the variable with that value is a lexical variable, and only exists inside of A .

What Good is local ?

Because local does not actually create local variables, it is not very much use. If, in the example above, B happened to modify the value of $lo , then the value set by A would be overwritten. That is exactly what we don't want to happen. We want each function to have its own variables that are untouchable by the others. This is what my does.

Why have local at all? The answer is 90% history. Early versions of Perl only had global variables. local was very easy to implement, and was added to Perl 4 as a partial solution to the local variable problem. Later, in Perl 5, more work was done, and real local variables were put into the language. But the name local was already taken, so the new feature was invoked with the word my . my was chosen because it suggests privacy, and also because it's very short; the shortness is supposed to encourage you to use it instead of local . my is also faster than local .

When to Use my and When to Use local

Always use my ; never use local .

Wasn't that easy?

Other Properties of my Variables

Every time control reaches a my declaration, Perl creates a new, fresh variable. For example, this code prints x=1 fifty times:

        for (1 .. 50) {
          my $x;
          print "x=$x\n";

You get a new $x , initialized to undef , every time through the loop.

If the declaration were outside the loop, control would only pass by it once, so there would only be one variable:

        { my $x;
          for (1 .. 50) {
            print "x=$x\n";

This prints x=1 , x=2 , x=3 , ... x=50 .

You can use this to play a useful trick. Suppose you have a function that needs to remember a value from one call to the next. For example, consider a random number generator. A typical random number generator (like Perl's rand function) has a seed in it. The seed is just a number. When you ask the random number generator for a random number, the function performs some arithmetic operation that scrambles the seed, and it returns the result. It also saves the result and uses it as the seed for the next time it is called.

Here's typical code: (I stole it from the ANSI C standard, but it behaves poorly, so don't use it for anything important.)

        $seed = 1;
        sub my_rand {
          $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768;
          return $seed;

And typical output:


There's a problem here, which is that $seed is a global variable, and that means we have to worry that someone might inadvertently tamper with it. Or they might tamper with it on purpose, which could affect the rest of the program. What if the function were used in a gambling program, and someone tampered with the random number generator?

But we can't declare $seed as a my variable in the function:

        sub my_rand {
          my $seed;
          $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768;
          return $seed;

If we did, it would be initialized to undef every time we called my_rand . We need it to retain its value between calls to my_rand .

Here's the solution:

        { my $seed = 1;
          sub my_rand {
            $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768;
            return $seed;

The declaration is outside the function, so it only happens once, at the time the program is compiled, not every time the function is called. But it's a my variable, and it's in a block, so it's only accessible to code inside the block. my_rand is the only other thing in the block, so the $seed variable is only accessible to the my_rand function.

$seed here is sometimes called a `static' variable, because it stays the same in between calls to the function. (And because there's a similar feature in the C language that is activated by the static keyword.)

my Variable Trivia
  1. You can't declare a variable my if its name is a punctuation character, like $_ , @_ , or $$ . You can't declare the backreference variables $1 , $2 , ... as my . The authors of my thought that that would be too confusing.
  2. Obviously, you can't say my $DBI::errstr , because that's contradictory---it says that the package variable $DBI::errstr is now a lexical variable. But you can say local $DBI::errstr ; it saves the current value of $DBI::errstr and arranges for it to be restored at the end of the block.
  3. New in Perl 5.004, you can write
            foreach my $i (@list) {

    instead, to confine the $i to the scope of the loop instead. Similarly,

            for (my $i=0; $i<100; $i++) {

    confines the scope of $i to the for loop.


If you're writing a function, and you want it to have private variables, you need to declare the variables with my . What happens if you forget?

        sub function {
          $x = 42;        # Oops, should have been my $x = 42.

In this case, your function modifies the global package variable $x . If you were using that variable for something else, it could be a disaster for your program.

Recent versions of Perl have an optional protection against this that you can enable if you want. If you put

        use strict 'vars';

at the top of your program, Perl will require that package variables have an explicit package qualifier. The $x in $x=42 has no such qualifier, so the program won't even compile; instead, the compiler will abort and deliver this error message:

        Global symbol "$x" requires explicit package name at ...

If you wanted $x to be a private my variable, you can go back and add the my . If you really wanted to use the global package variable, you could go back and change it to

        $main::x = 42;

or whatever would be appropriate.

Just saying use strict turns on strict vars , and several other checks besides. See perldoc strict for more details.

Now suppose you're writing the Algorithms::KnuthBendix modules, and you want the protections of strict vars But you're afraid that you won't be able to finish the module because your fingers are starting to fall off from typing $Algorithms::KnuthBendix::Error all the time.

You can save your fingers and tell strict vars to make an exception:

        package Algorithms::KnuthBendix;
        use vars '$Error';

This exempts the package variable $Algorithms::KnuthBendix::Error from causing a strict vars failure if you refer to it by its short name, $Error .

You can also turn strict vars off for the scope of one block by writing

        { no strict 'vars';

          # strict vars is off for the rest of the block.


Package variables are always global. They have a name and a package qualifier. You can omit the package qualifier, in which case Perl uses a default, which you can set with the package declaration. For private variables, use my . Don't use local ; it's obsolete.

You should avoid using global variables because it can be hard to be sure that no two parts of the program are using one another's variables by mistake.

To avoid using global variables by accident, add use strict 'vars' to your program. It checks to make sure that all variables are either declared private, are explicitly qualified with package qualifiers, or are explicitly declared with use vars .

  1. The tech editors complained about my maxim `Never use local .' But 97% of the time, the maxim is exactly right. local has a few uses, but only a few, and they don't come up too often, so I left them out, because the whole point of a tutorial article is to present 97% of the utility in 50% of the space.

    I was still afraid I'd get a lot of tiresome email from people saying ``You forgot to mention that local can be used for such-and-so, you know.'' So in the colophon at the end of the article, I threatened to deliver Seven Useful Uses for local in three months. I mostly said it to get people off my back about local . But it turned out that I did write it, and it was published some time later.

    The Seven Useful Uses of local is now available on the web site. It appeared in The Perl Journal issue #14.

  2. Here's another potentially interesting matter that I left out for space and clarity. I got email from Robert Watkins with a program he was writing that didn't work. The essence of the bug looked like this:
            my $x;
            for $x (1..5) {
            sub s { print "$x, " }

    Robert wanted this to print 1, 2, 3, 4, 5, but it did not. Instead, it printed , , , , , . Where did the values of $x go?

    The deal here is that normally, when you write something like this:

                        for $x (...) { }

    Perl wants to confine the value of the index variable to inside the loop. If $x is a package variable, it pretends that you wrote this instead:

            { local $x; for $x (...) { } }

    But if $x is a lexical variable, it pretends you wrote this instead, instead:

            { my $x;    for $x (...) { } }

    This means that the loop index variable won't get propagated to subroutines, even if they're in the scope of the original declaration.

    I probably shouldn't have gone on at such length, because the perlsyn manual page describes it pretty well:

    ...the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my , it uses that variable instead of the global one, but it's still localized to the loop. (Note that a lexically scoped variable can cause problems if you have subroutine or format declarations within the loop which refer to it.)

    In my opinion, lexically scoping the index variable was probably a mistake. If you had wanted that, you would have written for my $x ... in the first place. What I would have liked it to do was to localize the lexical variable: It could save the value of the lexical variable before the loop, and restore it again afterwards. But there may be technical reasons why that couldn't be done, because this doesn't work either:

       my $m;
            { local $m = 12;

    The local fails with this error message:

       Can't localize lexical variable $m...

    There's been talk on P5P about making this work, but I gather it's not trivial.

  3. Added 2000-01-05: Perl 5.6.0 introduced a new our(...) declaration. Its syntax is the same as for my() , and it is a replacement for use vars .

    Without getting into the details, our() is just like use vars ; its only effect is to declare variables so that they are exempt from the strict 'vars' checking. It has two possible advantages over use vars , however: Its syntax is less weird, and its effect is lexical. That is, the exception that it creates to the strict checking continues only to the end of the current block:

            use strict 'vars';
              $x = 1;   # Use of global variable $x here is OK
            $x = 2;     # Use of $x here is a compile-time error as usual

    So whereas use vars '$x' declares that it is OK to use the global variable $x everywhere, our($x) allows you to say that global $x should be permitted only in certain parts of your program, and should still be flagged as an error if you accidentally use it elsewhere.

  4. Added 2000-01-05: Here's a little wart that takes people by surprise. Consider the following program:
            use strict 'vars';
            my @lines = <>;
            my @sorted = sort backwards @lines;
            print @sorted;
            sub backwards { $b cmp $a }

    Here we have not declared $a or $b , so they are global variables. In fact, they have to be global, because the sort operator must to be able to set them up for the backwards function. Why doesn't strict produce a failure?

    The variables $a and $b are exempted from strict vars checking, for exactly this reason.

[Sep 19, 2019] Min and max functions in Perl by Tim

Feb 01, 2012 |

Posted: 1st February 2012 by Tim in Perl

Tags: list , math , max , min , Perl , script 3

Min and max functions are available in perl, but you need to load them first. To do this, add

use List::Util qw[min max];

to the top of the script. These functions take a list of numbers and return the min/max of that list. The list can have 2 numbers or 100 – it doesn't matter:

use List::Util qw[min max];

print min(1,3) . "\n";
print max(1,2,3,4,5) . "\n";
print min(1) . "\n";

[Sep 19, 2019] Luke's Thought Dump Cute Perl Gem to Get the Minimum-Maximum Value

Notable quotes:
"... the comparison operators return 1 or 0 for true and false, respectively, which are then used by this code to index the array ref. ..."
Sep 19, 2019 |

Sunday, August 2, 2009 Cute Perl Gem to Get the Minimum/Maximum Value Saw this little nugget on the other night. It determines the minimum of two values:

[$b, $a]->[$a <= $b]
It takes advantage of the fact that Perl doesn't have a Boolean return type for true or false, so the comparison operators return 1 or 0 for true and false, respectively, which are then used by this code to index the array ref.

To get the maximum of the two values, just flip the operator to >= Posted by Luke at

Labels: hacks , perl

[Sep 19, 2019] List::MoreUtils's minmax is more efficient when you need both the min and the max (because it does fewer comparisons).

Notable quotes:
"... List::MoreUtils's minmax is more efficient when you need both the min and the max (because it does fewer comparisons). ..."
Sep 19, 2019 |

List::Util's min and max are fine,

use List::Util qw( min max );
my $min = min @numbers;
my $max = max @numbers;

But List::MoreUtils's minmax is more efficient when you need both the min and the max (because it does fewer comparisons).

use List::MoreUtils qw( minmax );
my ($min, $max) = minmax @numbers;

List::Util is part of core, but List::MoreUtils isn't.


[Sep 17, 2019] How can a Perl regex re-use part of the previous match for the next match?

Sep 17, 2019 |

Ask Question Asked 10 years, 1 month ago Active 10 years, 1 month ago Viewed 2k times 2

dlw ,Aug 16, 2009 at 3:52

I need some Perl regular expression help. The following snippet of code:
use strict; 
use warnings; 
my $str = "In this example, A plus B equals C, D plus E plus F equals G and H plus I plus J plus K equals L"; 
my $word = "plus"; 
my @results = ();
1 while $str =~ s/(.{2}\b$word\b.{2})/push(@results,"$1\n")/e;
print @results;

Produces the following output:

A plus B
D plus E
2 plus F
H plus I
4 plus J
5 plus K

What I want to see is this, where a character already matched can appear in a new match in a different context:

A plus B
D plus E
E plus F
H plus I
I plus J
J plus K

How do I change the regular expression to get this result? Thanks --- Dan

Michael Carman ,Aug 16, 2009 at 4:11

General advice: Don't use s/// when you want m// . Be specific in what you match.

The answer is pos :

#!/usr/bin/perl -l

use strict;
use warnings;

my $str = 'In this example, ' . 'A plus B equals C, ' .
          'D plus E plus F equals G ' .
          'and H plus I plus J plus K equals L';

my $word = "plus";

my @results;

while ( $str =~ /([A-Z] $word [A-Z])/g ) {
    push @results, $1;
    pos($str) -= 1;

print "'$_'" for @results;


C:\Temp> b
'A plus B'
'D plus E'
'E plus F'
'H plus I'
'I plus J'
'J plus K'

Michael Carman ,Aug 16, 2009 at 2:56

You can use a m//g instead of s/// and assign to the pos function to rewind the match location before the second term:
use strict;
use warnings;

my $str  = 'In this example, A plus B equals C, D plus E plus F equals G and H plus I plus J plus K equals L';
my $word = 'plus';
my @results;

while ($str =~ /(.{2}\b$word\b(.{2}))/g) {
    push @results, "$1\n";
    pos $str -= length $2;
print @results;

dlw ,Aug 18, 2009 at 13:00

Another option is to use a lookahead:
use strict; 
use warnings; 
my $str = "In this example, A plus B equals C, D plus E "
        . "plus F equals G and H plus I plus J plus K equals L"; 
my $word = "plus"; 
my $chars = 2;
my @results = ();

push @results, $1 
  while $str =~ /(?=((.{0,$chars}?\b$word\b).{0,$chars}))\2/g;

print "'$_'\n" for @results;

Within the lookahead, capturing group 1 matches the word along with a variable number of leading and trailing context characters, up to whatever maximum you've set. When the lookahead finishes, the backreference \2 matches "for real" whatever was captured by group 2, which is the same as group 1 except that it stops at the end of the word. That sets pos where you want it, without requiring you to calculate how many characters you actually matched after the word.

ysth ,Aug 16, 2009 at 9:01

Given the "Full Disclosure" comment (but assuming .{0,35} , not .{35} ), I'd do
use List::Util qw/max min/;
my $context = 35;
while ( $str =~ /\b$word\b/g ) {
    my $pre = substr( $str, max(0, $-[0] - $context), min( $-[0], $context ) );
    my $post = substr( $str, $+[0], $context );
    my $match = substr( $str, $-[0], $+[0] - $-[0] );
    $pre =~ s/.*\n//s;
    $post =~ s/\n.*//s;
    push @results, "$pre$match$post";
print for @results;

You'd skip the substitutions if you really meant (?s:.{0,35}) .

Greg Hewgill ,Aug 16, 2009 at 2:29

Here's one way to do it:
use strict; 
use warnings; 
my $str = "In this example, A plus B equals C, D plus E plus F equals G and H plus I plus J plus K equals L"; 
my $word = "plus"; 
my @results = ();
my $i = 0;
while (substr($str, $i) =~ /(.{2}\b$word\b.{2})/) {
    push @results, "$1\n";
    $i += $-[0] + 1;
print @results;

It's not terribly Perl-ish, but it works and it doesn't use too many obscure regular expression tricks. However, you might have to look up the function of the special variable @- in perlvar .

ghostdog74 ,Aug 16, 2009 at 3:44

don't have to use regex. basically, just split up the string, use a loop to go over each items, check for "plus" , then get the word from before and after.
my $str = "In this example, A plus B equals C, D plus E plus F equals G and H plus I plus J plus K equals L"; 
@s = split /\s+/,$str;
for($i=0;$i<=scalar @s;$i++){
    if ( "$s[$i]"  eq "plus" ){
        print "$s[$i-1] plus $s[$i+1]\n";

[Sep 17, 2019] Using Look-ahead and Look-behind

Sep 16, 2019 |

Using Look-ahead and Look-behind by Roy Johnson (Monsignor)

on Dec 21, 2005 at 21:57 UTC ( # 518444 = perltutorial : print w/replies , xml ) Need Help??

If you are familiar with Perl's regular expressions, you are probably already familiar with zero-width assertions: the ^ indicating the beginning of string and the \b indicating a word boundary are examples. They do not match any characters, but "look around" to see what comes before and/or after the current position.

With the look-ahead and look-behind constructs documented in perlre.html#Extended-Patterns , you can "roll your own" zero-width assertions to fit your needs. You can look forward or backward in the string being processed, and you can require that a pattern match succeed (positive assertion) or fail (negative assertion) there.

Syntax Every extended pattern is written as a parenthetical group with a question mark as the first character. The notation for the look-arounds is fairly mnemonic, but there are some other, experimental patterns that are similar, so it is important to get all the characters in the right order.
(?= pattern )
is a positive look-ahead assertion
(?! pattern )
is a negative look-ahead assertion
(?<= pattern )
is a positive look-behind assertion
(?<! pattern )
is a negative look-behind assertion
Notice that the = or ! is always last. The directional indicator is only present in the look-behind, and comes before the positive-or-negative indicator. Common tasks Finding the last occurrence There are actually a number of ways to get the last occurrence that don't involve look-around, but if you think of "the last foo" as "foo that isn't followed by a string containing foo", you can express that notion like this: /foo(?!.*foo)/ [download] The regular expression engine will do its best to match .*foo , starting at the end of the string "foo". If it is able to match that, then the negative look-ahead will fail, which will force the engine to progress through the string to try the next foo. Substituting before, after, or between characters Many substitutions match a chunk of text and then replace part or all of it. You can often avoid that by using look-arounds. For example, if you want to put a comma after every foo: s/(?<=foo)/,/g; # Without lookbehind: s/foo/foo,/g or s/(foo)/$1,/g [download] or to put the hyphen in look-ahead: s/(?<=look)(?=ahead)/-/g; [download] This kind of thing is likely to be the bulk of what you use look-arounds for. It is important to remember that look-behind expressions cannot be of variable length . That means you cannot use quantifiers ( ?, *, +, or {1,5} ) or alternation of different-length items inside them. Matching a pattern that doesn't include another pattern You might want to capture everything between foo and bar that doesn't include baz. The technique is to have the regex engine look-ahead at every character to ensure that it isn't the beginning of the undesired pattern: /foo # Match starting at foo ( # Capture (?: # Complex expression: (?!baz) # make sure we're not at the beginning of baz . # accept any character )* # any number of times ) # End capture bar # and ending at bar /x; [download] Nesting You can put look-arounds inside of other look-arounds. This has been known to induce a flight response in certain readers (me, for example, the first time I saw it), but it's really not such a hard concept. A look-around sub-expression inherits a starting position from the enclosing expression, and can walk all around relative to that position without affecting the position of the enclosing expression. They all have independent (though initially inherited) bookkeeping for where they are in the string.

The concept is pretty simple, but the notation becomes hairy very quickly, so commented regular expressions are recommended. Let's look at the real example of Regex to add space after punctuation sign . The poster wants to put a space after any comma (punctuation, actually, but for simplicity, let's say comma) that is not nestled between two digits. Building up the s/// expression:

s/(?<=, # after a comma, (?! # but not matching (?<=\d,) # digit-comma before, AND (?=\d) # digit afterward ) )/ /gx; # substitute a space [download] Note that multiple lookarounds can be used to enforce multiple conditions at the same place, like an AND condition that complements the alternation (vertical bar)'s OR. In fact, you can use Boolean algebra ( NOT (a AND b) === (NOT a OR NOT b) ) to convert the expression to use OR: s/(?<=, # after a comma, but either (?: (?<!\d,) # not matching digit-comma before | # OR (?!\d) # not matching digit afterward ) )/ /gx; # substitute a space [download] Capturing It is sometimes useful to use capturing parentheses within a look-around. You might think that you wouldn't be able to do that, since you're just browsing, but you can . But remember: the capturing parentheses must be within the look-around expression; from the enclosing expression's point of view, no actual matching was done by the zero-width look-around.

This is most useful for finding overlapping matches in a global pattern match. You can capture substrings without consuming them, so they are available for further matching later. Probably the simplest example is to get all right-substrings of a string:

print "$1\n" while /(?=(.*))/g; [download] Note that the pattern technically consumes no characters at all, but Perl knows to advance a character on an empty match, to prevent infinite looping.

jds17 (Pilgrim) on May 07, 2009 at 16:13 UTC

Re: Using Look-ahead and Look-behind

Thank you for your very nice article, I certainly learned some new tricks!

Just one little comment: The code in the last paragraph did not work because by default regular expressions are greedy. (Did this change with the Perl versions in between?) The only right-substring that comes out is the full string:

$_ = "Hello"; print "$1\n" while /(?=(.*))/g; [download] Output: Hello [download] Making the "(.*)" part non-greedy fixes it (in Perl 5.10): $_ = "Hello"; print "$1\n" while /(?=(.*)?)/g; [download] Output: Hello ello llo lo o [download]

Roy Johnson (Monsignor) on May 08, 2009 at 14:39 UTC

Regex bug in 5.10 (was: Using Look-ahead and Look-behind)

by Roy Johnson (Monsignor) on May 08, 2009 at 14:39 UTC

I think you have found a bug in 5.10's regex handling. The lookahead's greediness or non-greediness should not matter, because it does not consume any characters. When used in a global match, patterns that do not consume characters should advance one character on each match. At least that's how I read the documentation .

The really interesting thing about your version is that you didn't make the capture non-greedy, you made it optional. You probably meant (.*?) , which (in pre-5.10) will output empty strings every time. I haven't installed 5.10 myself, so I can't play with it right now.

Caution: Contents may have been coded under pressure.

almut (Canon) on May 08, 2009 at 15:06 UTC

Re: Regex bug in 5.10 (was: Using Look-ahead and Look-behind)
by almut (Canon) on May 08, 2009 at 15:06 UTC
...which (in pre-5.10) will output empty strings every time.

With 5.10.0, /(?=(.*?))/g; outputs one empty string. And I can confirm the behavior reported by jds17 with /(?=(.*))/g .

jds17 (Pilgrim) on May 08, 2009 at 19:47 UTC

Re: Regex bug in 5.10 (was: Using Look-ahead and Look-behind)
by jds17 (Pilgrim) on May 08, 2009 at 19:47 UTC You are right, my change did not affect greediness. The bad thing is: now I don't understand why my proposed solution worked at all. Maybe someone can explain? I don't think the question is too important, but I like to use regular expressions and it bugs me a little if I cannot understand one (especially such a tiny one).

I have read the documentation you have cited and it helped, so I played around some more and tried out the following, which only exchanges "+" for "*" in your original expression, really works as one would think and therefore would be my preferred solution, at least for Perl 5.10:

$_ = "Hello"; print "$1\n" while /(?=(.+))/g; [download] Output: Hello ello llo lo o [download]

Anonymous Monk on Jun 25, 2011 at 07:49 UTC

Re: Using Look-ahead and Look-behind

The following is just not working. Basically, i want to match a value that has "equity",but NOT "private equity". The result must be items 1, 2, 4, 5. Please check this out:

my %hash = ( 1 => 'equity, private equity', 2 => 'equity', 3 => 'private equity', 4 => 'private equity,equity', 5 => 'private equity, equity', 6 => 'equity,private equity', 7 => 'private equity', 8 => 'mutual funds', 9 => 'cds' ); while (my ($k, $v) = each %hash) { next unless $v =~ m/(?!private\s+)equity/; printf("%d -> %s\n", $k, $v); } [download]

Anonymous Monk on Jun 25, 2011 at 08:41 UTC

Re^2: Using Look-ahead and Look-behind

by Anonymous Monk on Jun 25, 2011 at 08:41 UTC

Hi, new questions go in Seekers Of Perl Wisdom because

Roy Johnson , whom you asked a question, hasn't been here in 6 weeks.

You used code tags and put your code in between, that is awesome :)

Welcome, see How do I post a question effectively? , Where should I post X?

The regex which is not working for you, contains A zero-width negative look-ahead assertion , and like perlre # (?!pattern) says

A zero-width negative look-ahead assertion. For example /foo(?!bar)/ matches any occurrence of "foo" that isn't followed by "bar". Note however that look-ahead and look-behind are NOT the same thing. You cannot use this for look-behind.

If you are looking for a "bar" that isn't preceded by a "foo", /(?!foo)bar/ will not do what you want. That's because the (?!foo) is just saying that the next thing cannot be "foo"--and it's not, it's a "bar", so "foobar" will match. Use look-behind instead (see below).

So, use a look-behind

But, that probably won't work either, because you can't have variable length length lookbehind , so you need to use a fixed width lookbehind.

#!/usr/bin/perl -- use strict; use warnings; use Test::More qw' no_plan '; Main(@ARGV); exit(0); sub Main { my @yesWant = ( 'equity, private equity', 'equity', 'private equity,equity', 'private equity, equity', 'equity,private equity', ); my @notWant = ( 'private equity', 'private equity', 'mutual funds', 'cds', ); for my $not ( @notWant ){ ok( (not TestEquity($not)), "not '$not'" ); } for my $yes ( @yesWant ){ ok( TestEquity($yes), "yes '$yes'" ); } } sub TestEquity { return 1 if $_[0] =~ m/(?<!private\s)equity/; return 0; } __END__ $ prove -v .. ok 1 - not 'private equity' ok 2 - not 'private equity' ok 3 - not 'mutual funds' ok 4 - not 'cds' ok 5 - yes 'equity, private equity' ok 6 - yes 'equity' ok 7 - yes 'private equity,equity' ok 8 - yes 'private equity, equity' ok 9 - yes 'equity,private equity' 1..9 ok All tests successful. Files=1, Tests=9, 0 wallclock secs ( 0.06 usr + 0.01 sys = 0.08 CPU + ) Result: PASS [download]

If fixed width lookbehind doesn't work for you, simply do TWO tests

AnomalousMonk (Bishop) on Jun 25, 2011 at 19:51 UTC

Re^3: Using Look-ahead and Look-behind
by AnomalousMonk (Bishop) on Jun 25, 2011 at 19:51 UTC

Here's a solution that exactly matches the phrases specified in AnonyMonk's Re: Using Look-ahead and Look-behind post (which the code of Re^2: Using Look-ahead and Look-behind does not quite do), and also shows how to use the newfangled backtracking control verbs of 5.10 to emulate variable-width negative look-behind. Variable-width positive look-behind is emulated by 5.10's \K assertion.


>perl -wMstrict -le "use Test::More 'no_plan'; ;; for my $ar_vector ( [ YES => 'equity, private equity', ], [ YES => 'equity', ], [ no => 'private equity', ], [ YES => 'private equity,equity', ], [ YES => 'private equity, equity', ], [ no => 'equity,private equity', ], [ no => 'private equity', ], [ no => 'mutual funds', ], [ no => 'cds' ], ) { my ($expected, $string) = @$ar_vector; is match($string), $expected, qq{'$string'}; } ;; sub match { my ($string) = @_; ;; my $char_not_comma_or_space = qr{ [^,\s] }xms; my $private = qr{ private \s+ }xms; return 'YES' if $string =~ m{ (?: $char_not_comma_or_space | $private) equity (*SKIP)(*FAIL) | equity (?! , \S) }xms; return 'no', } " ok 1 - 'equity, private equity' ok 2 - 'equity' ok 3 - 'private equity' ok 4 - 'private equity,equity' ok 5 - 'private equity, equity' ok 6 - 'equity,private equity' ok 7 - 'private equity' ok 8 - 'mutual funds' ok 9 - 'cds' 1..9 [download]

JohnN (Initiate) on Oct 15, 2012 at 15:09 UTC

Re^4: Using Look-ahead and Look-behind
by JohnN (Initiate) on Oct 15, 2012 at 15:09 UTC

choroba (Bishop) on Oct 15, 2012 at 15:25 UTC

Re^5: Using Look-ahead and Look-behind
by choroba (Bishop) on Oct 15, 2012 at 15:25 UTC

Anonymous Monk on Oct 15, 2012 at 15:28 UTC

Re^5: Using Look-ahead and Look-behind
by Anonymous Monk on Oct 15, 2012 at 15:28 UTC

Anonymous Monk on Jun 25, 2011 at 10:31 UTC

Re^3: Using Look-ahead and Look-behind
by Anonymous Monk on Jun 25, 2011 at 10:31 UTC Nice. Very nice! You nailed. It's working. Thanks a bunch!

heyjoec (Initiate) on Jun 19, 2014 at 11:18 UTC

Re^3: Using Look-ahead and Look-behind
by heyjoec (Initiate) on Jun 19, 2014 at 11:18 UTC

I changed the sub TestEquity to allow for any text between Private and Equity, but I can't get it to work. What have I done wrong?

sub TestEquity { return 1 if $_[0] =~ m/(?<!private).*equity/; return 0; } [download]

AnomalousMonk (Bishop) on Jun 19, 2014 at 12:09 UTC

Re^4: Using Look-ahead and Look-behind
by AnomalousMonk (Bishop) on Jun 19, 2014 at 12:09 UTC

Anonymous Monk on Jun 19, 2014 at 23:13 UTC

Re^4: Using Look-ahead and Look-behind
by Anonymous Monk on Jun 19, 2014 at 23:13 UTC

Anonymous Monk on Apr 11, 2007 at 07:25 UTC

Re: Using Look-ahead and Look-behind

Great! This is exactly what I was looking for. Thank you very much!

narainhere (Monk) on Oct 17, 2007 at 12:51 UTC

Re: Using Look-ahead and Look-behind

Thanks a lot DUDEEEEEEE........ Solved my problems ++ Roy Johnson

The world is so big for any individual to conquer

joewong (Initiate) on Nov 12, 2007 at 03:34 UTC

Re: Using Look-ahead and Look-behind

Referring to the paragraph "Matching a pattern that doesn't include another pattern", I wonder why ?: is necessary. It seems to be working for me even without ?:. Please explain. thanks.

Roy Johnson (Monsignor) on Nov 12, 2007 at 17:54 UTC

Re^2: Using Look-ahead and Look-behind

by Roy Johnson (Monsignor) on Nov 12, 2007 at 17:54 UTC

Generally, the decision about using ?: is not about whether it's necessary, but that capturing whatever you're grouping isn't necessary. The ?: modifier makes parentheses not capture, which is somewhat more efficient and might make the task of counting left parentheses less onerous.

By the way, it's not a lookaround feature.

Caution: Contents may have been coded under pressure.

greengaroo (Hermit) on Feb 05, 2013 at 15:08 UTC

Re: Using Look-ahead and Look-behind

Thank you!

Testing never proves the absence of faults, it only shows their presence.
-- greengaroo

aaaone (Initiate) on Jul 18, 2008 at 13:12 UTC

Re: Using Look-ahead and Look-behind

Great article :) Thank you!

[Sep 16, 2019] How can I find the location of a regex match in Perl?

Notable quotes:
"... The built-in variables @- and @+ hold the start and end positions, respectively, of the last successful match. $-[0] and $+[0] correspond to entire pattern, while $-[N] and $+[N] correspond to the $N ( $1 , $2 , etc.) submatches. ..."
"... Edited to add: to quote from perlvar on $1..$9. "These variables are all read-only and dynamically scoped to the current BLOCK." In other words, if you want to use $1..$9, you cannot use a subroutine to do the matching. ..."
Sep 17, 2008 |

Michael Carman ,Sep 17, 2008 at 20:58

I need to write a function that receives a string and a regex. I need to check if there is a match and return the start and end location of a match. (The regex was already compiled by qr// .)

The function might also receive a "global" flag and then I need to return the (start,end) pairs of all the matches.

I cannot change the regex, not even add () around it as the user might use () and \1 . Maybe I can use (?:) .

Example: given "ababab" and the regex qr/ab/ , in the global case I need to get back 3 pairs of (start, end).

Nick T ,Sep 8, 2015 at 19:58

The built-in variables @- and @+ hold the start and end positions, respectively, of the last successful match. $-[0] and $+[0] correspond to entire pattern, while $-[N] and $+[N] correspond to the $N ( $1 , $2 , etc.) submatches.

szabgab ,Sep 17, 2008 at 23:51

Forget my previous post, I've got a better idea.
sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /$regex/;
    return ($-[0], $+[0]);
sub match_all_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /$regex/g) {
        push @ret, [ $-[0], $+[0] ];
    return @ret

This technique doesn't change the the regex in any way.

Edited to add: to quote from perlvar on $1..$9. "These variables are all read-only and dynamically scoped to the current BLOCK." In other words, if you want to use $1..$9, you cannot use a subroutine to do the matching.

Aftershock ,Dec 23, 2012 at 12:13

The pos function gives you the position of the match. If you put your regex in parentheses you can get the length (and thus the end) using length $1 . Like this
sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /($regex)/;
    return (pos($string), pos($string) + length $1);
sub all_match_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /($regex)/g) {
        push @ret, [pos($string), pos($string) + length $1];
    return @ret

zigdon ,Sep 17, 2008 at 20:43

You can also use the deprecated $` variable, if you're willing to have all the REs in your program execute slower. From perlvar:
   $'      The string preceding whatever was matched by the last successful pattern match (not
           counting any matches hidden within a BLOCK or eval enclosed by the current BLOCK).
           (Mnemonic: "`" often precedes a quoted string.)  This variable is read-only.

           The use of this variable anywhere in a program imposes a considerable performance penalty
           on all regular expression matches.  See "BUGS".

Shicheng Guo ,Jan 22, 2016 at 0:16


# search the postions for the CpGs in human genome

sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /($regex)/;
    return (pos($string), pos($string) + length $1);
sub all_match_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /($regex)/g) {
        push @ret, [(pos($string)-length $1),pos($string)-1];
    return @ret

my $regex='CG';
my $string="ACGACGCGCGCG";
my $cgap=3;    
my @pos=all_match_positions($regex,$string);

my @hgcg;

foreach my $pos(@pos){
    push @hgcg,@$pos[1];

foreach my $i(0..($#hgcg-$cgap+1)){
my $len=$hgcg[$i+$cgap-1]-$hgcg[$i]+2;
print "$len\n"; 

[Sep 16, 2019] perlre - Capture groups

Sep 16, 2019 |

Capture groups

The grouping construct ( ... ) creates capture groups (also referred to as capture buffers). To refer to the current contents of a group later on, within the same pattern, use \ g1 (or \ g { 1 } ) for the first, \ g2 (or \ g { 2 } ) for the second, and so on. This is called a backreference . There is no limit to the number of captured substrings that you may use. Groups are numbered with the leftmost open parenthesis being number 1, etc . If a group did not match, the associated backreference won't match either. (This can happen if the group is optional, or in a different branch of an alternation.) You can omit the "g" , and write "\1" , etc , but there are some issues with this form, described below.

You can also refer to capture groups relatively, by using a negative number, so that \ g - 1 and \ g { -1 } both refer to the immediately preceding capture group, and \ g - 2 and \ g { -2 } both refer to the group before it. For example:

  1. /
  2. (Y) # group 1
  3. ( # group 2
  4. (X) # group 3
  5. \g{-1} # backref to group 3
  6. \g{-3} # backref to group 1
  7. )
  8. /x

would match the same as /(Y) ( (X) \g3 \g1 )/x . This allows you to interpolate regexes into larger regexes and not have to worry about the capture groups being renumbered.

You can dispense with numbers altogether and create named capture groups. The notation is (?< name >...) to declare and \g{ name } to reference. (To be compatible with .Net regular expressions, \g{ name } may also be written as \k{ name } , \k< name > or \k' name ' .) name must not begin with a number, nor contain hyphens. When different groups within the same pattern have the same name, any reference to that name assumes the leftmost defined group. Named groups count in absolute and relative numbering, and so can also be referred to by those numbers. (It's possible to do things with named capture groups that would otherwise require ( ?? {}) .)

Capture group contents are dynamically scoped and available to you outside the pattern until the end of the enclosing block or until the next successful match, whichever comes first. (See Compound Statements in perlsyn .) You can refer to them by absolute number (using "$1" instead of "\g1" , etc ); or by name via the %+ hash, using "$+{ name }" .

Braces are required in referring to named capture groups, but are optional for absolute or relative numbered ones. Braces are safer when creating a regex by concatenating smaller strings. For example if you have qr/$a$b/ , and $a contained "\g1" , and $b contained "37" , you would get /\g137/ which is probably not what you intended.

The \ g and \ k notations were introduced in Perl 5.10.0. Prior to that there were no named nor relative numbered capture groups. Absolute numbered groups were referred to using \ 1 , \ 2 , etc ., and this notation is still accepted (and likely always will be). But it leads to some ambiguities if there are more than 9 capture groups, as \ 10 could mean either the tenth capture group, or the character whose ordinal in octal is 010 (a backspace in ASCII). Perl resolves this ambiguity by interpreting \ 10 as a backreference only if at least 10 left parentheses have opened before it. Likewise \ 11 is a backreference only if at least 11 left parentheses have opened before it. And so on. \ 1 through \ 9 are always interpreted as backreferences. There are several examples below that illustrate these perils. You can avoid the ambiguity by always using \ g {} or \ g if you mean capturing groups; and for octal constants always using \ o {} , or for \ 077 and below, using 3 digits padded with leading zeros, since a leading zero implies an octal constant.

The \ digit notation also works in certain circumstances outside the pattern. See Warning on \1 Instead of $1 below for details.


  1. s/^([^ ]*) *([^ ]*)/$2 $1/ ; # swap first two words
  2. /(.)\g1/ # find first doubled char
  3. and print "'$1' is the first doubled character\n" ;
  4. /(?<char>.)\k<char>/ # ... a different way
  5. and print "'$+{char}' is the first doubled character\n" ;
  6. /(?'char'.)\g1/ # ... mix and match
  7. and print "'$1' is the first doubled character\n" ;
  8. if ( /Time: (..):(..):(..)/ ) { # parse out values
  9. $hours = $1 ;
  10. $minutes = $2 ;
  11. $seconds = $3 ;
  12. }
  13. /(.)(.)(.)(.)(.)(.)(.)(.)(.)\g10/ # \g10 is a backreference
  14. / ( . )( . )( . )( . )( . )( . )( . )( . )( . ) \ 10 / # \10 is octal
  15. /((.)(.)(.)(.)(.)(.)(.)(.)(.))\10/ # \10 is a backreference
  16. / (( . )( . )( . )( . )( . )( . )( . )( . )( . )) \ 010 / # \010 is octal
  17. $a = '(.)\1' ; # Creates problems when concatenated.
  18. $b = '(.)\g{1}' ; # Avoids the problems.
  19. "aa" =~ /${a}/ ; # True
  20. "aa" =~ /${b}/ ; # True
  21. "aa0" =~ /${a}0/ ; # False!
  22. "aa0" =~ /${b}0/ ; # True
  23. "aa\x08" =~ /${a}0/ ; # True!
  24. "aa\x08" =~ /${b}0/ ; # False

Several special variables also refer back to portions of the previous match. $+ returns whatever the last bracket match matched. $& returns the entire matched string. (At one point $0 did also, but now it returns the name of the program.) $` returns everything before the matched string. $' returns everything after the matched string. And $^N contains whatever was matched by the most-recently closed group (submatch). $^N can be used in extended patterns (see below), for example to assign a submatch to a variable.

These special variables, like the %+ hash and the numbered match variables ( $1 , $2 , $3 , etc .) are dynamically scoped until the end of the enclosing block or until the next successful match, whichever comes first. (See Compound Statements in perlsyn .)

NOTE : Failed matches in Perl do not reset the match variables, which makes it easier to write code that tests for a series of more specific cases and remembers the best match.

WARNING : If your code is to run on Perl 5.16 or earlier, beware that once Perl sees that you need one of $& , $` , or $' anywhere in the program, it has to provide them for every pattern match. This may substantially slow your program.

Perl uses the same mechanism to produce $1 , $2 , etc , so you also pay a price for each pattern that contains capturing parentheses. (To avoid this cost while retaining the grouping behaviour, use the extended regular expression ( ?: ... ) instead.) But if you never use $& , $` or $' , then patterns without capturing parentheses will not be penalized. So avoid $& , $' , and $` if you can, but if you can't (and some algorithms really appreciate them), once you've used them once, use them at will, because you've already paid the price.

Perl 5.16 introduced a slightly more efficient mechanism that notes separately whether each of $` , $& , and $' have been seen, and thus may only need to copy part of the string. Perl 5.20 introduced a much more efficient copy-on-write mechanism which eliminates any slowdown.

As another workaround for this problem, Perl 5.10.0 introduced $ { ^PREMATCH } , $ { ^MATCH } and $ { ^POSTMATCH } , which are equivalent to $` , $& and $' , except that they are only guaranteed to be defined after a successful match that was executed with the /p (preserve) modifier. The use of these variables incurs no global performance penalty, unlike their punctuation character equivalents, however at the trade-off that you have to tell perl when you want to use them. As of Perl 5.20, these three variables are equivalent to $` , $& and $' , and /p is ignored.

[Sep 16, 2019] Perl For Dummies Cheat Sheet

Sep 16, 2019 |

From Perl For Dummies, 4th Edition

By Paul Hoffman

Perl enables you to write powerful programs right from the start, whether you're a programming novice or expert. Perl offers the standard programming tools -- comparison operators, pattern-matching quantifiers, list functions -- and has shortcuts for inputting character ranges. Perl also offers file tests so you can find what you want fast.

The Most Useful File Tests in Perl

Programming with Perl is fairly straightforward, which runs to the letters you use for file tests. For example, r tests whether a file can be r ead, and T looks for a t ext file. Here are most useful file tests in Perl:

Test Description
-e File exists.
-r File can be read.
-w File can be written to.
-z File is exactly zero bytes long.
-d Named item is a directory, not a file.
-T File is a text file. (The first chunk of a file is examined,
and it's a text file if fewer than 30 percent or so of the
characters are nonprintable.)
-B File is a binary file. (This is the exact opposite of the -T
test -- it's a binary file if more than 30 percent or so
of the characters are nonprintable.)
-s Size of the file in bytes.
-C Creation age of file.
-A Access age of file.
-M Modification age of file.
Special Characters in Perl

Like any programming language, Perl uses special commands for special characters, such as backspaces or vertical tabs. So, if you need to program in a bell or a beep or just a carriage return, check the following table for the character that will produce it:

Character Meaning
n Newline
r Carriage return
t Tab character
f Formfeed character
b Backspace character
v Vertical tab
a Bell or beep
e Escape character
Perl True-False Comparison Operators

When you're programming with Perl -- or any other language -- you use comparison operators all the time. The following table shows the common comparisons for Perl in both math and string form:

Comparison Math String
Equal to == eq
Not equal to != ne
Less than < lt
Greater than > gt
Less than or equal to <= le
Greater than or equal to >= ge
Common List Functions in Perl

Perl was originally designed to help process reports more easily. Reports often contain lists, and you may want to use Perl to perform certain functions within a list. The following table shows you common list functions, their splice equivalents, and explains what the function does:

Function splice Equivalent What It Does
push (@r, @s) splice(@r, $#r+1,0, @s) Adds to the right of the list
pop (@r) splice(@r, $#r, 1) Removes from the right of the list
shift (@r) splice(@r, 0, 1) Removes from the left of the list
unshift (@r, @s) splice(@r, 0, 0,@s) Adds to the left of the list
Shortcuts for Character Ranges in Perl

You're programming along in Perl and want to use a code shortcut to represent anything from a number to a non-number to any letter or number. You're in luck, because the following table gives you the code, shows you what it's a shortcut for, and describes it.

Code Replaces Description
d [0..9] Any digit
w [a-zA-Z_0-9] Any alphanumeric character
s [ tnrf] A whitespace character
D ^[0..9] Any non-digit
W ^[a-zA-Z_0-9] Any non-alphanumeric character
S ^[ tnrf] A non-whitespace character
Perl Pattern-Matching Quantifiers

Perl enables you to use common symbols to instruct the program you're writing to match data once, never, or up to a certain number of times. The following table shows you which symbol to use to get the match you want:

Symbol Meaning
+ Match 1 or more times
* Match 0 or more times
? Match 0 or 1 time
{n} Match exactly n times
{n,} Match at least n times
{n,m} Match at least n, but not more than m, times (these values must
be less than 65,536)

[Sep 16, 2019] How can I capture multiple matches from the same Perl regex - Stack Overflow

Sep 16, 2019 |

How can I capture multiple matches from the same Perl regex? Ask Question Asked 9 years, 4 months ago Active 7 years, 4 months ago Viewed 35k times 24 1

brian d foy ,May 22, 2010 at 15:42

I'm trying to parse a single string and get multiple chunks of data out from the same string with the same regex conditions. I'm parsing a single HTML doc that is static (For an undisclosed reason, I can't use an HTML parser to do the job.) I have an expression that looks like:
$string =~ /\<img\ssrc\="(.*)"/;

and I want to get the value of $1. However, in the one string, there are many img tags like this, so I need something like an array returned (@1?) is this possible?

VolatileRig ,Jan 14, 2014 at 19:41

As Jim's answer, use the /g modifier (in list context or in a loop).

But beware of greediness, you dont want the .* to match more than necessary (and dont escape < = , they are not special).

while($string =~ /<img\s+src="(.*?)"/g ) {

Robert Wohlfarth ,May 21, 2010 at 18:44

@list = ($string =~ m/\<img\ssrc\="(.*)"/g);

The g modifier matches all occurences in the string. List context returns all of the matches. See the m// operator in perlop .

dalton ,May 21, 2010 at 18:42

You just need the global modifier /g at the end of the match. Then loop through until there are no matches remaining
my @matches;
while ($string =~ /\<img\ssrc\="(.*)"/g) {
        push(@matches, $1);

VolatileRig ,May 24, 2010 at 16:37

Use the /g modifier and list context on the left, as in
@result = $string =~ /\<img\ssrc\="(.*)"/g;

[Sep 16, 2019]

Sep 16, 2019 |

Avoiding Common Oversights in Perl

Related Book

Perl For Dummies, 4th Edition

By Paul Hoffman

Entering a typo or two during the course of writing a Perl program is not uncommon. But when you attempt to run a program containing a text-entry slip-up, Perl usually becomes confused and tells you so by reporting an error. The natural reaction for most people, even those with years of programming experience, is to get worried or angry or both when an error message pops up.

Don't panic. Take a deep breath. Take another slow, deep breath. Seriously, you can't get to the root of the problem if you're all tense and bothered. No matter how many years you program, you always end up finding some errors in the code you're written.

So, now that you are (hopefully!) a bit calmer, you can start to appreciate the fact that Perl has more helpful error messages than almost any other programming language. The messages aren't always right on the money, but they can get you pretty close to the spot where the problem lies with minimal searching on your part.

Perl has myriad error messages, but a few definitely crop up more than others owing to some common typos that everyone seems to make. The following errors result from minor text-entry goofs that you can easily avoid.

Forgetting a semicolon

Probably the most common error message you see when programming in Perl looks something like this:

# syntax error, near "open"
File ''; Line 10
# Execution aborted due to compilation errors.

You can look and look at Line 10, the one with the open statement, and you won't see anything wrong with it. The trick here is to examine the statement that comes before the open statement and see whether it ends with a semicolon. (Perl knows that a statement ends only when it encounters a semicolon.) In this case, the error is caused by a missing semicolon at the end of Line 7 of the program:

$TheFile = "sample.txt"

Forgetting a quotation mark

The following sort of error message can be extremely frustrating if you don't know of a quick fix:

# Bare word found where operator expected, near
# "open(INFILE, $TheFile) or die "The"
# (Might be a runaway multi-line " string starting on
# line 7)
File ''; Line 10

This error is similar to forgetting a semicolon; instead, it's a quotation mark that's accidentally omitted:

$TheFile = "sample.txt;

In this case, Perl did a good job of guessing what is wrong, suggesting that a runaway multi-line " string on Line 7 is the problem, which is precisely right.

Entering one parenthesis too many or too few

When you have loads of opening and closing parentheses in a program, it's easy to slip an extra one in by accident. If that's the case, you may see a message from Perl that reads something like this:

# syntax error, near ") eq"
File ''; Line 38
# syntax error, near "}"
File ''; Line 42

Here, Perl can't determine where the error is exactly, but it actually got it right on the first guess: Line 38 contains an extra right parenthesis:

if(substr($TheLine, $CharPos, 1)) eq " ")

Having one parenthesis too few in a Perl program can cause harder-to-find problems:

# Can't use constant item as left arg of implicit -- >,
# near "1 }"
File ''; Line 39
# Scalar found where operator expected, near "$CharPos"
File ''; Line 40
# (Missing semicolon on previous line?)
# syntax error, near "$CharPos "
File ''; Line 40

Yarp! All this was produced because the last parenthesis on Line 38 is missing:

if(substr($TheLine, $CharPos, 1) eq " "

Here is another good lesson in hunting down typing errors: Start where Perl says it found an error. If you don't find the error there, go up a line or two and see if the problem started earlier.

A final word of advice: Trust Perl to find the simple typos for you (where it can), and remember that it's giving you all the help it can, which is more than you can say for many programming languages.

[Sep 16, 2019] Switch Statements

Sep 16, 2019 |

Starting from Perl 5.10.1 (well, 5.10.0, but it didn't work right), you can say

  1. use feature "switch" ;

to enable an experimental switch feature. This is loosely based on an old version of a Perl 6 proposal, but it no longer resembles the Perl 6 construct. You also get the switch feature whenever you declare that your code prefers to run under a version of Perl that is 5.10 or later. For example:

  1. use v5.14 ;

Under the "switch" feature, Perl gains the experimental keywords given , when , default , continue , and break . Starting from Perl 5.16, one can prefix the switch keywords with CORE:: to access the feature without a use feature statement. The keywords given and when are analogous to switch and case in other languages -- though continue is not -- so the code in the previous section could be rewritten as

  1. use v5.10.1 ;
  2. for ( $var ) {
  3. when ( /^abc/ ) { $abc = 1 }
  4. when ( /^def/ ) { $def = 1 }
  5. when ( /^xyz/ ) { $xyz = 1 }
  6. default { $nothing = 1 }
  7. }

The foreach is the non-experimental way to set a topicalizer. If you wish to use the highly experimental given , that could be written like this:

  1. use v5.10.1 ;
  2. given ( $var ) {
  3. when ( /^abc/ ) { $abc = 1 }
  4. when ( /^def/ ) { $def = 1 }
  5. when ( /^xyz/ ) { $xyz = 1 }
  6. default { $nothing = 1 }
  7. }

As of 5.14, that can also be written this way:

  1. use v5.14 ;
  2. for ( $var ) {
  3. $abc = 1 when /^abc/ ;
  4. $def = 1 when /^def/ ;
  5. $xyz = 1 when /^xyz/ ;
  6. default { $nothing = 1 }
  7. }

Or if you don't care to play it safe, like this:

  1. use v5.14 ;
  2. given ( $var ) {
  3. $abc = 1 when /^abc/ ;
  4. $def = 1 when /^def/ ;
  5. $xyz = 1 when /^xyz/ ;
  6. default { $nothing = 1 }
  7. }

The arguments to given and when are in scalar context, and given assigns the $_ variable its topic value.

Exactly what the EXPR argument to when does is hard to describe precisely, but in general, it tries to guess what you want done. Sometimes it is interpreted as $_ ~~ EXPR , and sometimes it is not. It also behaves differently when lexically enclosed by a given block than it does when dynamically enclosed by a foreach loop. The rules are far too difficult to understand to be described here. See Experimental Details on given and when later on.

Due to an unfortunate bug in how given was implemented between Perl 5.10 and 5.16, under those implementations the version of $_ governed by given is merely a lexically scoped copy of the original, not a dynamically scoped alias to the original, as it would be if it were a foreach or under both the original and the current Perl 6 language specification. This bug was fixed in Perl 5.18 (and lexicalized $_ itself was removed in Perl 5.24).

If your code still needs to run on older versions, stick to foreach for your topicalizer and you will be less unhappy.

[Sep 12, 2019] Why is Perl no longer a popular programming language - Quora

May 19, 2019 |
  1. die " Reports of my death are greatly exaggerated . \n "

Perl is alive and well, but it has steadily been losing promise over the past 20 years.

It's still heavily used for the tasks it was used for when I learnt it, in 1994–1995, but at that time, it looked set for an even brighter future: it was developing into one of the top-5 languages, a universal scripting language, a language you expect to find wherever scripting or dynamically typed languages are appropriate.

You can still find evidence of that today: some software has an extension API in Perl, some web applications are written in Perl, some larger system administration software is written in Perl, etcetera. But these systems are typically 20 years old. If you do this today, be prepared to justify yourself.

This is not because Perl has become any less suitable for doing these things. On the contrary, it has continued to improve. Yet, people have turned away from Perl, towards newer scripting languages such as Python, PHP, Ruby, and Lua, for tasks that in 1995 they would probably have used Perl for.


I believe the reason is simple: Perl is very free, syntactically and semantically. This makes it very good at what it was designed to do (scripting) but less suited for larger-scale programming.

Perl's syntactic freedom mostly originates from its mimicking idioms from other languages. It was designed to be a suitable replacement for other scripting languages, most notably the Bourne shell ( /bin/ sh ) and awk , so it adopts some of their idioms. This is perfect if you like these idioms for their compactness.

For instance, in the Bourne shell, we can write

  1. if mkdir $directory
  2. then
  3. echo successfully created directory : $directory
  4. elif test - d $directory
  5. then
  6. echo pre - existing directory : $directory
  7. else
  8. echo cannot create directory : $directory
  9. fi

In the Bourne shell, every statement is a Unix command invocation; in this case, test and mkdir . (Some commands, such as test , were built into the shell later.) Every command will succeed or fail, so we can use it in the condition of an if statement.

Now what if we only want to print a warning when something went wrong? We can write this:

  1. if mkdir $directory
  2. then
  3. : # nothing
  4. elif test - d $directory
  5. then
  6. : # nothing
  7. else
  8. echo cannot create directory : $directory
  9. fi

or we can combine the two conditions:

  1. if mkdir $directory || test - d $directory
  2. then
  3. : # nothing
  4. else
  5. echo cannot create directory : $directory
  6. fi

or we can combine them even further:

  1. mkdir $directory ||
  2. test - d $directory ||
  3. echo cannot create directory : $directory

These all do the same exact thing; clearly, the last version is the most compact. In a shell script with a lot of tests like this, writing things this way can save a considerable amount of space. Especially in throwaway scripts of a few lines, it's a lot easier to use more compact syntax.

Most programmers are familiar with seeing some special syntax for conditions in if statements. For this reason, Unix has the [ command, which scans its arguments for a matching ], and then invokes test with the arguments up to that point. So we can always replace

  1. test - d $directory


  1. [ - d $directory ]

in the pieces of code above. It means the same thing.

Now, Perl comes onto the scene. It is designed to be easy to replace Bourne shell scripts with. This is a very frequent use case for Perl, even today: I regularly find myself rewriting my Bourne shell scripts into Perl by going through them line by line.

So what do the Perl replacements of the above look like?

Here we go:

  1. if ( mkdir $directory )
  2. {
  3. # nothing
  4. } elsif (- d $directory )
  5. {
  6. # nothing
  7. } else {
  8. say "cannot create directory: $directory"
  9. }

or we can combine the two conditions:

  1. if ( mkdir $directory || - d $directory )
  2. {
  3. # nothing
  4. } else {
  5. say "cannot create directory: $directory"
  6. }

or we can combine them even further:

  1. mkdir $directory or
  2. - d $directory or
  3. say "cannot create directory: $directory"

As you can see, these are literal transliterations of the corresponding Bourne shell fragments.

In a language such as Java, you can use the first two forms, but not the third one. In such languages, there is a syntactic separation between expressions , which yield a value, and must be used in a context that demands such a value, and statements , which do not yield a value, and must be used in contexts that do not demand one. The third form is syntactically an expression, used in a context that demands a statement, which is invalid in such a language.

No such distinction is made in Perl, a trait it inherited from the Bourne shell, which in turn took it from Algol 68.

So here we have an example of syntactic freedom in Perl that many other languages lack, and in this case, Perl took it from the Bourne shell.

Allowing more compactness isn't the only reason for this freedom. The direct reason the Bourne shell doesn't make the distinction is that it relies on Unix commands, which do not make the distinction, either. Every Unix command can return a value (a return code) to indicate whether it failed and how. Therefore, it acts both as a statement and as a condition. There is a deeper reason behind this: concurrency.

For instance, when we want to create a directory, we can't separate doing it from testing whether it can/could be done. We could try and write something like

  1. if ( some test to see if we can mkdir $directory )
  2. then
  3. mkdir directory
  4. fi
  5. if ( some test to see if we managed to mkdir directory )
  6. then
  7. [...]
  8. fi

but that logic isn't correct. Unix is a multiprogramming environment, so anything could happen between our first test and our mkdir command, and before our mkdir command and the second test. Someone else might create that directory or remove it, or do something else that causes problems. Therefore, the only correct way to write code that tries to create a directory and determines whether it succeeds is to actually issue the mkdir command and check the value it returned. Which is what the constructs above do.

A shortcut like

  1. mkdir $directory or
  2. - d $directory or
  3. say "cannot create directory: $directory"

is just a consequence. Of course, you can still object to using it for stylistic reasons, but at least the construct makes sense once you know its origins.

Programmers who are unfamiliar with the paradigm of mixing statements and expressions, who have never seen any but the simplest of Bourne shell scripts, who have only been given programming tasks in which their program calls all the shots and nothing else can interfere, have never encountered a reason to treat statements and expressions as the same thing. They will be taken aback by a construct like this. I can't read this , they will mutter, it's incomprehensible gibberish . And if Perl is the first language they've seen that allows it, they will blame Perl. Only because they were never subjected to a large amount of Bourne shell scripting. Once you can read that, you can read anything ; Perl will look pretty tame in comparison.

Similar reasons can be given for most of the other syntactical freedom in Perl. I must say, Perl sometimes seems to make a point of being quirky, and I find some of the resulting oddities hard to justify, but they do make sense in context. The overall motivation is compactness. In scripting, where you type a lot and throw away a lot, the ability to write compact code is a great virtue.

Due to these syntactic quirks, Perl got a reputation for being a write-only language - meaning that when programmer A is faced with programmer B 's code, B may have used all kinds of idioms that A is unfamiliar with, causing delays for A . There is some truth to this, but the problem is exaggerated: syntax is the first thing you notice about a program, which is why it sticks out, but it's pretty superficial: new syntax really isn't so hard to learn.

So I'm not really convinced Perl's syntactic freedom is such a bad thing, except that people tend to blow it out of proportion.

However, Perl is also very free semantically : it is a truly dynamic language, allowing programmers to do all kinds of things that stricter languages forbid. For instance, I can monkey-patch functions and methods in arbitrary code that I'm using. This can make it very hard for programmers to understand how a piece of code is working, or whether it is working as intended.

This becomes more important when a software system grows larger or when others than the original author start to rely on it. The code doesn't just need to work, but it must be understandable to others. Consequently, in large, stable code bases, compactness and freedom of expression are less important than consistency, a smooth learning curve for beginners, and protection against routine errors. Therefore, many software development teams prefer languages such as Java, with its very limited syntactic freedom and strict compile-time type checking. Perl is at the opposite end of the spectrum, with its extreme syntactic and semantic freedom.

This wouldn't be a problem if there were ways to straitjacket Perl if you wanted to; if there was a way to say: for this project, be as rigid as Java syntactically or semantically; I want as few surprises as possible in code that I didn't write. Sure enough, Perl has support for compile-time checking ( use strict ; use warnings , and the perlcritic utility) and consistent code formatting (the perltidy utility), but they were added as afterthoughts and cannot come anywhere near the level of strictness a Java programmer would expect.

To support that, the language needed to be redesigned from scratch, and the result would be incompatible with the original. This effort has been made, producing Perl 6, but in the meantime, many other languages sprung up and became popular for the cases Perl programmers wanted to use Perl for, and if you're going to switch to an incompatible language anyway, why not use one of those instead?

[Sep 12, 2019] CMOS #12- Randal Schwartz the host of FLOSS Weekly

The fate of Perl 6 is unclear but Perl 5.10 is here to stay. Some thing were screwed after Perl 5.10, but they might be eventually corrected. OO-enthusiasts did a every bad service to Perl trying to enforce unsuitable for programming, say, utilities paradigm on everybody. That led to huge inefficiencies and bloated difficult to maintain code. That also somewhat devalued Perl standard library as the conversion to OO spoiled the broth.
Notable quotes:
"... I'm keeping up with Perl, but not really, I still see a feature, like in Perl 5.16, and I go, Oh, that's in relatively modern Perl, no wonder I don't know about it. I think of Perl as whatever was back in 5.10 and 5.12, that's the latest that I was writing my books for, my trainings for. ..."
"... So the stuff that's coming out in 5.18 and 5.20 and 5.22 now, is sort of beyond me, I just can't keep up with Perl-delta, and that's a scary thing for the number one prolific author about Perl, to not be able to keep up with what's happening in the Perl community, this is clearly an indication that Perl is alive and well, and I've kind of missed the boat, now. ..."
"... And every time I go to YAPC or some other place where they're talking about Perl 6, I get excited about it, for all of a month, and then I come back and then I go, How am I going to use this practically? None of my current clients are demanding that. ..."
Sep 12, 2019 |

09:24 Randal Schwartz

Yeah, I think a few years ago, it was all about cloud stuff. So it was all about running your application in cloud. Starting probably a couple years ago, with the Docker revolution, it's all about containers now.

But we're also seeing a revolution in smart, JavaScript-based ultimately, front-ends, that are doing things like single-page applications and stuff, and I'm really pretty excited about that. Not that I ever really wanted to spend a lot of time playing with JavaScript, but unfortunately I guess that that's a requirement, so I'm continuing to hone my JavaScript skills.

I'm also honing my Dart skills, because that language out of Google, is really gaining some traction, in terms of being able to do server-side stuff, essentially replacing Node.JS with a reasonable language. And also client-side stuff for all the modern browsers, and it translating down into JavaScript, so as long as there's a reasonable ECMA 5 or something available in the browser, Dart works really nicely. But Dart looks closer, as a language, to something like Java, with optional typing, so if you add types to variables, you can actually get hints from your development environment and that's pretty slick. So I'm learning Dart in the background, I actually have a couple applications for it already, that as I learn more, I'll be able to deploy. I'm also learning things like Angular , so I can have reactive front-ends, and again, it's like there's not enough hours in the day for me to learn everything I want to learn.

I'm keeping up with Perl, but not really, I still see a feature, like in Perl 5.16, and I go, Oh, that's in relatively modern Perl, no wonder I don't know about it. I think of Perl as whatever was back in 5.10 and 5.12, that's the latest that I was writing my books for, my trainings for.

So the stuff that's coming out in 5.18 and 5.20 and 5.22 now, is sort of beyond me, I just can't keep up with Perl-delta, and that's a scary thing for the number one prolific author about Perl, to not be able to keep up with what's happening in the Perl community, this is clearly an indication that Perl is alive and well, and I've kind of missed the boat, now.

17:53 Gabor Szabo Yeah, so as a closing question, I would like to go back a little bit to the languages and the things you do with open source, and ask you, where are you heading? Are you going to go back to Perl and learn what the new things in Perl are, or are you more interested in other languages, and which ones?

18:16 Randal Schwartz

Well, I download and compile Perl 6 every day. And every time I go to YAPC or some other place where they're talking about Perl 6, I get excited about it, for all of a month, and then I come back and then I go, How am I going to use this practically? None of my current clients are demanding that.

Clearly if I were to write training materials for that, I'd have to present it at least to 200 people, whether that's 10 classes of 20, or a giant 200 person week-end event, that's sort of the minimum for amortizing the inception cost for any class that I've ever written. So I use the 200 number as kind of a rule of thumb.

And I just don't see that happening, I don't see getting enough people together in the right places, to be able to do that. So I continue to watch what people are doing with Perl 6, I continue compiling it every day, and I'd love for it to become extremely popular so I could go back to that, and say I could continue my Perl heritage.

But, as I mentioned earlier, I think Dart has legs. Given that Google's behind it, given that Google and a number of other companies are already deploying public-facing projects in it. Given that it does compile down and work in all modern browsers, I easily see the need for like rent a hotel room for a weekend and have 20, 50, 100 people show up to learn about it, because single-page applications are all the rage right now, and Dart is a really solid language for that, and Google is betting on that.

You may say, Where is Go in that equation? Go is great for server-side stuff, and great for the kind of things they're doing on back-ends, and although Dart can also do back-end stuff, essentially replacing Node.JS for that sort of thing, and have a single language for both back-end and front-end. Dart's real win is in the front-end, being able to be transpiled over to JavaScript and being able to scale to hundreds of thousands of lines of code for some of their larger applications. I think that's got legs, I'm in on the groundfloor, like I was on Perl, I'm already recognized among the Dart people as being someone who can put things together. I did a one-hour long intro to Dart talk that was reviewed by some of the key people in the Dart community, and they really like what I did with it, so I seem to have, again, that knack for finding something complex and finding the simplest ends of it, and I'm already there with Dart.

And also, the whole Fuchsia announcement a few weeks ago, where Google's coming out with this language for real-time operating systems, and it has a strong Dart component in it. I think that's another thing that says, say if they start putting that in Google Glass , or if they even put that as a replacement for the Android operating system, or for Google Chrome, which some people are suspecting that this is all amalgamation of it.

Especially when somebody's looking at the source code the other day, and it has a lot of files, not only from Android, but also from the old Be OS , which was sort of the predecessor of what eventually became OS X, kind of interesting that that's part of that project as well.

So with Fuchsia on the horizon, with Dart already being deployed by numbers of people, with me having a knack for understanding how Dart actually works, given that it was also built by some of the key players in Smalltalk, which I go back 16 years with, I think this is probably the right place for me to look at my future.

22:02 Gabor Szabo And I guess, FLOSS Weekly?

22:05 Randal Schwartz

FLOSS Weekly will continue.

In fact I just had a converstaion recently with Leo, we're one of the smaller shows on the network, but he's absolutely committed to this show. He likes what I'm doing with it, he likes the directions I'm taking it, he likes the team I've put together, who were able to pick up the show, even when I was absent for six weeks, in the hospital recently, without notice unfortunately, I guess that's always the way you end up in the hospital.

So my team picked up, and Aaron Newcomb did a great job of hosting while I was gone, but Leo likes the team I've built and Leo likes the kinds of guests I'm getting on, the variety especially. I've had a lot of people write in and say, I don't always want or understand the thing you're talking about, but I listen to the way you interview them, and I listen to the things you're able to pull out, like what's the governance model, how are you making money with this, what got you started? These sorts of things are really sort of cross-project. You know, you can learn that sort of stuff about anything you want to start, and like I said, I learned a lot already by doing this show and so a lot of the audience is picking that up. And we have a fun time.

I tell jokes sometimes and I have a bad way of making really bad puns. And that's kind of the way it works but I really enjoy the show, I'm going to keep doing it. And I told Leo I would just keep doing this as long as he let's me, and he goes, Well then, that makes two of us. So we'll still be doing this in 20 years, if they let us. And I said, That sounds like a great promise, Leo, thank you. So yeah, I'll be doing FLOSS Weekly for at least awhile longer.

23:45 Gabor Szabo I'm happy to hear that and I hope to see a lot more of that. And I hope to see you somewhere, I don't know, maybe at a Dart conference?

23:56 Randal Schwartz

Yeah, that'd be awesome!

And I think you come to OSCon , occasionally, or maybe, well I've got to get out to a YAPC::Europe or a YAPC::Israel or something at some point, but just haven't made those yet. I think it's partially because I need to figure out what to pitch to the Perl conference.

Oh wait, I could just be press again! That's the other thing, is that FLOSS Weekly has allowed me to apply as press for OSCon for the last few years, even though I don't have an actual talk to give. And Red Hat actually invited me to their conference, as press. And I thought, Well, that's the first time that's happened. That really says I've made it. That really says that FLOSS Weekly is recognized as legitimate press. So I'm wearing a whole 'nother hat, so my hat tree of all my hats, hanging up in the corner, has gotten a whole 'nother rung.

[Sep 12, 2019] prename -- rename files using any perl expressior (regex, tr, etc)

Sep 12, 2019 |
#!/usr/bin/perl -w
#  This script was developed by Robin Barker (,
#  from Larry Wall's original script eg/rename from the perl source.
#  This script is free software; you can redistribute it and/or modify it
#  under the same terms as Perl itself.
# Larry(?)'s RCS header:
#  RCSfile: rename,v   Revision: 4.1   Date: 92/08/07 17:20:30 
# $RCSfile: rename,v $$Revision: 1.5 $$Date: 1998/12/18 16:16:31 $
# $Log: rename,v $
# Revision 1.5  1998/12/18 16:16:31  rmb1
# moved to perl/source
# changed man documentation to POD
# Revision 1.4  1997/02/27  17:19:26  rmb1
# corrected usage string
# Revision 1.3  1997/02/27  16:39:07  rmb1
# added -v
# Revision 1.2  1997/02/27  16:15:40  rmb1
# *** empty log message ***
# Revision 1.1  1997/02/27  15:48:51  rmb1
# Initial revision

use strict;

use Getopt::Long;

my ($verbose, $no_act, $force, $op);

die "Usage: rename [-v] [-n] [-f] perlexpr [filenames]\n"
    unless GetOptions(
        'v|verbose' => \$verbose,
        'n|no-act'  => \$no_act,
        'f|force'   => \$force,
    ) and $op = shift;

$verbose++ if $no_act;

if (!@ARGV) {
    print "reading filenames from STDIN\n" if $verbose;
    @ARGV = ;

for (@ARGV) {
    my $was = $_;
    eval $op;
    die $@ if $@;
    next if $was eq $_; # ignore quietly
    if (-e $_ and !$force)
        warn  "$was not renamed: $_ already exists\n";
    elsif ($no_act or rename $was, $_)
        print "$was renamed as $_\n" if $verbose;
        warn  "Can't rename $was $_: $!\n";


=head1 NAME

rename - renames multiple files


B S ]> S ]> S ]> I S ]>


renames the filenames supplied according to the rule specified as the
first argument.
The I 
argument is a Perl expression which is expected to modify the C
string in Perl for at least some of the filenames specified.
If a given filename is not modified by the expression, it will not be
If no filenames are given on the command line, filenames will be read
via standard input.

For example, to rename all files matching C to strip the extension,
you might say

        rename 's/\.bak$//' *.bak

To translate uppercase names to lower, you'd use

        rename 'y/A-Z/a-z/' *

=head1 OPTIONS

=over 8

=item B, B

Verbose: print names of files successfully renamed.

=item B, B

No Action: show what files would have been renamed.

=item B, B

Force: overwrite existing files.



No environment variables are used.

=head1 AUTHOR

Larry Wall

=head1 SEE ALSO

mv(1), perl(1)


If you give an invalid Perl expression you'll get a syntax error.

=head1 BUGS

The original C did not check for the existence of target filenames,
so had to be used with care.  I hope I've fixed that (Robin Barker).


[Sep 10, 2019] How do I avoid an uninitialized value

Sep 10, 2019 |

marto ,Jul 15, 2011 at 16:52

I use this scrub function to clean up output from other functions.
use warnings;
use strict;
use Data::Dumper;

my %h = (
    a => 1,
    b => 1

print scrub($h{c});

sub scrub {
    my $a = shift;

    return ($a eq '' or $a eq '~' or not defined $a) ? -1 : $a;

The problem occurs when I also would like to handle the case, where the key in a hash doesn't exist, which is shown in the example with scrub($h{c}) .

What change should be make to scrub so it can handle this case?

Sandra Schlichting ,Jun 22, 2017 at 19:00

You're checking whether $a eq '' before checking whether it's defined, hence the warning "Use of uninitialized value in string eq". Simply change the order of things in the conditional:
return (!defined($a) or $a eq '' or $a eq '~') ? -1 : $a;

As soon as anything in the chain of 'or's matches, Perl will stop processing the conditional, thus avoiding the erroneous attempt to compare undef to a string.

Sandra Schlichting ,Jul 14, 2011 at 14:34

In scrub it is too late to check, if the hash has an entry for key key . scrub() only sees a scalar, which is undef , if the hash key does not exist. But a hash could have an entry with the value undef also, like this:
my %h = (
 a => 1,
 b => 1,
 c => undef

So I suggest to check for hash entries with the exists function.

[Sep 10, 2019] Use of uninitialized value

Sep 10, 2019 |

Prev Next This is one of the most common warning you will encounter while running Perl code.

It is a warning, it won't stop your script from running and it is only generated if warnings were turned on. Which is recommended.

The most common way to turn on warnings is by including a use warnings; statement at the beginning of your script or module.

Are you serious about Perl? Check out my Beginner Perl Maven book .
I have written it for you!

The older way is adding a -w flag on the sh-bang line. Usually looks like this as the first line of your script:

#!/usr/bin/perl -w

There are certain differences, but as use warnings is available for 12 years now, there is no reason to avoid it. In other words:

Always use warnings; !

Let's go back to the actual warning I wanted to explain.

A quick explanation
Use of uninitialized value $x in say at line 6.

This means the variable $x has no value (its value is the special value undef ). Either it never got a value, or at some point undef was assigned to it.

You should look for the places where the variable got the last assignment, or you should try to understand why that piece of code has never been executed.

A simple example

The following example will generate such warning.

  1. use warnings ;
  2. use strict ;
  3. use 5.010 ;
  4. my $x ;
  5. say $x ;

Perl is very nice, tells us which file generated the warning and on which line.

Only a warning

As I mentioned this is only a warning. If the script has more statements after that say statement, they will be executed:

  1. use warnings ;
  2. use strict ;
  3. use 5.010 ;
  4. my $x ;
  5. say $x ;
  6. $x = 42 ;
  7. say $x ;

This will print

Use of uninitialized value $x in say at line 6.

Confusing output order

Beware though, if your code has print statements before the line generating the warning, like in this example:

  1. use warnings ;
  2. use strict ;
  3. use 5.010 ;
  4. print 'OK' ;
  5. my $x ;
  6. say $x ;
  7. $x = 42 ;
  8. say $x ;

the result might be confusing.

Use of uninitialized value $x in say at line 7.

Here, 'OK', the result of the print is seen after the warning, even though it was called before the code that generated the warning.

This strangeness is the result of IO buffering . By default Perl buffers STDOUT, the standard output channel, while it does not buffer STDERR, the standard error channel.

So while the word 'OK' is waiting for the buffer to be flushed, the warning message already arrives to the screen.

Turning off buffering

In order to avoid this you can turn off the buffering of STDOUT.

This is done by the following code: $| = 1; at the beginning of the script.

  1. use warnings ;
  2. use strict ;
  3. use 5.010 ;
  4. $ | = 1 ;
  5. print 'OK' ;
  6. my $x ;
  7. say $x ;
  8. $x = 42 ;
  9. say $x ;
OKUse of uninitialized value $x in say at line 7.

(The warning is on the same line as the OK because we have not printed a newline \n after the OK.)

The unwanted scope
  1. use warnings ;
  2. use strict ;
  3. use 5.010 ;
  4. my $x ;
  5. my $y = 1 ;
  6. if ( $y ) {
  7. my $x = 42 ;
  8. }
  9. say $x ;

This code too produces Use of uninitialized value $x in say at line 11.

I have managed to make this mistake several times. Not paying attention I used my $x inside the if block, which meant I have created another $x variable, assigned 42 to it just to let it go out of the scope at the end of the block. (The $y = 1 is just a placeholder for some real code and some real condition. It is there only to make this example a bit more realistic.)

There are of course cases when I need to declare a variable inside an if block, but not always. When I do that by mistake it is painful to find the bug.

[Sep 10, 2019] How do I check if a Perl scalar variable has been initialized - Stack Overflow

Sep 10, 2019 |

How do I check if a Perl scalar variable has been initialized? Ask Question Asked 8 years, 11 months ago Active 3 years ago Viewed 49k times 33 10

brian d foy ,Sep 18, 2010 at 13:53

Is the following the best way to check if a scalar variable is initialized in Perl, using defined ?
my $var;

if (cond) {
    $var = "string1";

# Is this the correct way?
if (defined $var) {

mob ,Sep 25, 2010 at 21:35

Perl doesn't offer a way to check whether or not a variable has been initialized.

However, scalar variables that haven't been explicitly initialized with some value happen to have the value of undef by default. You are right about defined being the right way to check whether or not a variable has a value of undef .

There's several other ways tho. If you want to assign to the variable if it's undef , which your example code seems to indicate, you could, for example, use perl's defined-or operator:

$var //= 'a default value';

vol7ron ,Sep 17, 2010 at 23:17

It depends on what you're trying to do. The proper C way to do things is to initialize variables when they are declared; however, Perl is not C , so one of the following may be what you want:
  1)   $var = "foo" unless defined $var;      # set default after the fact
  2)   $var = defined $var? $var : {...};     # ternary operation
  3)   {...} if !(defined $var);              # another way to write 1)
  4)   $var = $var || "foo";                  # set to $var unless it's falsy, in which case set to 'foo'
  5)   $var ||= "foo";                        # retain value of $var unless it's falsy, in which case set to 'foo' (same as previous line)
  6)   $var = $var // "foo";                  # set to $var unless it's undefined, in which case set to 'foo'
  7)   $var //= "foo";                        # 5.10+ ; retain value of $var unless it's undefined, in which case set to 'foo' (same as previous line)

C way of doing things ( not recommended ):

# initialize the variable to a default value during declaration
#   then test against that value when you want to see if it's been changed
my $var = "foo";
if ($var eq "foo"){
   ... # do something
} else {
   ... # do something else

Another long-winded way of doing this is to create a class and a flag when the variable's been changed, which is unnecessary.

Axeman ,Sep 17, 2010 at 20:39

If you don't care whether or not it's empty, it is. Otherwise you can check
if ( length( $str || '' )) {}

swilliams ,Sep 17, 2010 at 20:53

It depends on what you plan on doing with the variable whether or not it is defined; as of Perl 5.10, you can do this (from perl51000delta ):

A new operator // (defined-or) has been implemented. The following expression:

 $a // $b

is merely equivalent to

defined $a ? $a : $b

and the statement

$c //= $d;

can now be used instead of

$c = $d unless defined $c;

rafl ,Jun 24, 2012 at 7:53

'defined' will return true if a variable has a real value.

As an aside, in a hash, this can be true:

if(exists $h{$e} && !defined $h{$e})

[Sep 10, 2019] Perl Multidimensional Array

Sep 10, 2019 |

The multi dimensional array is represented in the form of rows and columns, also called Matrix.

They can not hold arrays or hashes, they can only hold scalar values. They can contain references to another arrays or hashes.

Perl Multidimensional Array Matrix Example

Here, we are printing a 3 dimensional matrix by combining three different arrays arr1 , arr2 and arr3 . These three arrays are merged to make a matrix array final .

Two for loops are used with two control variables $i and $j .

  1. ## Declaring arrays
  2. my @arr1 = qw(0 10 0);
  3. my @arr2 = qw(0 0 20);
  4. my@arr3 = qw(30 0 0);
  5. ## Merging all the single dimensional arrays
  6. my @final = (\@arr1, \@arr2, \@arr3);
  7. print "Print Using Array Index\n" ;
  8. for (my $i = 0; $i <= $#final; $i ++){
  9. # $#final gives highest index from the array
  10. for (my $j = 0; $j <= $#final ; $j ++){
  11. print "$final[$i][$j] " ;
  12. }
  13. print "\n" ;
  14. }


Print Using Array Index
0 10 0
0 0 20 
30 0 0

Perl Multidimensional Array Initialization and Declaration Example

In this example we are initializing and declaring a three dimensional Perl array .

  1. @ array = (
  2. [1, 2, 3],
  3. [4, 5, 6],
  4. [7, 8, 9]
  5. );
  6. for ( $i = 0; $i < 3; $i ++) {
  7. for ( $j = 0; $j < 3; $j ++) {
  8. print "$array[$i][$j] " ;
  9. }
  10. print "\n" ;
  11. }


1 2 3
4 5 6 
7 8 9

[Sep 10, 2019] Perl Modules and namespaces - javatpoint

Sep 10, 2019 |,56,38,173,174,175,132,178,157,4,148,10000,80,70,9,109,51,97,77

Perl Modules and namespaces

A module is a container which holds a group of variables and subroutines which can be used in a program. Every module has a public interface, a set of functions and variables.

To use a module into your program, require or use statement can be used, although their semantics are slightly different.

The 'require' statement loads module at runtime to avoid redundant loading of module. The 'use' statement is like require with two added properties, compile time loading and automatic importing.

Namespace is a container of a distinct set of identifiers (variables, functions). A namespace would be like name::variable .

Every piece of Perl code is in a namespace.

In the following code,

  1. use strict;
  2. use warnings;
  3. my $x = "Hello" ;
  4. $main ::x = "Bye" ;
  5. print "$main::x\n" ; # Bye
  6. print "$x\n" ; # Hello

Here are two different variables defined as x . the $main::x is a package variable and $x is a lexical variable. Mostly we use lexical variable declared with my keyword and use namespace to separate functions.

In the above code, if we won't use use strict , we'll get a warning message as

  1. Name "main::x" used only once: possible typo at line..

The main is the namespace of the current script and of current variable. We have not written anything and yet we are already in the 'main' namespace.

By adding 'use strict', now we got the following error,

  1. Global symbol "$x" requires explicit package name

In this error, we got a new word 'package'. It indicates that we forgot to use 'my' keyword before declaring variable but actually it indicates that we should provide name of the package the variable resides in.

Perl Switching namespace using package keyword

Look at the following code,

  1. use strict;
  2. use warnings;
  3. use 5.010;
  4. sub hii {
  5. return "main" ;
  6. }
  7. package two;
  8. sub hii {
  9. return "two" ;
  10. }
  11. say main::hii(); # main
  12. say two::hii(); # two
  13. say hii(); # two
  14. package main;
  15. say main::hii(); # main
  16. say two::hii(); # two
  17. say hii(); # main

Here we are using package keyword to switch from 'main' namespace to 'two' namespace.

Calling hii() with namespaces returns respective namespaces. Like , say main::hii(); returns 'main' and say two::hii(); returns 'two'.

Calling hii() without namespace prefix, returns the function that was local to the current namespace. In first time, we were in 'two' namespace. Hence it returned 'two'. In second time, we switched the namespace using package main. Hence it returns 'main'.

[Sep 10, 2019] Perl Hashes - javatpoint

Sep 10, 2019 |

The hashes is the most essential and influential part of the perl language. A hash is a group of key-value pairs. The keys are unique strings and values are scalar values.

Hashes are declared using my keyword. The variable name starts with a (%) sign.

Hashes are like arrays but there are two differences between them. First arrays are ordered but hashes are unordered. Second, hash elements are accessed using its value while array elements are accessed using its index value.

No repeating keys are allowed in hashes which makes the key values unique inside a hash. Every key has its single value.


  1. my %hashName = (
  2. "key" => "value" ;
  3. )

Perl Hash Accessing

To access single element of hash, ($) sign is used before the variable name. And then key element is written inside {} braces.

  1. my %capitals = (
  2. "India" => "New Delhi" ,
  3. "South Korea" => "Seoul" ,
  4. "USA" => "Washington, D.C." ,
  5. "Australia" => "Canberra"
  6. );
  7. print "$capitals{'India'}\n" ;
  8. print "$capitals{'South Korea'}\n" ;
  9. print "$capitals{'USA'}\n" ;
  10. print "$capitals{'Australia'}\n" ;


New Delhi
Washington, D.C.

Perl Hash Indexing

Hashes are indexed using $key and $value variables. All the hash values will be printed using a while loop. As the while loop runs, values of each of these variables will be printed.

  1. my %capitals = (
  2. "India" => "New Delhi" ,
  3. "South Korea" => "Seoul" ,
  4. "USA" => "Washington, D.C." ,
  5. "Australia" => "Canberra"
  6. );
  8. while (( $key , $value ) = each(%capitals)){
  9. print $key . ", " . $value . "\n" ;
  10. }


Australia, Canberra
India, New Delhi
USA, Washington, D.C.
South Korea, Seoul

Perl sorting Hash by key

You can sort a hash using either its key element or value element. Perl provides a sort() function for this. In this example, we'll sort the hash by its key elements.

  1. my %capitals = (
  2. "India" => "New Delhi" ,
  3. "South Korea" => "Seoul" ,
  4. "USA" => "Washington, D.C." ,
  5. "Australia" => "Canberra"
  6. );
  7. # Foreach loop
  8. foreach $key (sort keys %capitals) {
  9. print "$key: $capitals{$key}\n" ;
  10. }


Australia: Canberra
India: New Delhi
South Korea: Seoul
USA: Washington: D.C.

Look at the output, all the key elements are sorted alphabetically.

Perl sorting Hash by its value

Here we'll sort hash by its value elements.

  1. my %capitals = (
  2. "India" => "New Delhi" ,
  3. "South Korea" => "Seoul" ,
  4. "USA" => "Washington, D.C." ,
  5. "UK" => "London"
  6. );
  7. # Foreach loop
  8. foreach $value (sort { $capitals { $a } cmp $capitals { $b } }
  9. keys %capitals)
  10. {
  11. print "$value $capitals{$value}\n" ;
  12. }


UK London
India New Delhi
South Korea Seoul
USA Washington D.C.

Look at the output, all the value elements are sorted alphabetically.

... ... ...

Perl Removing Hash Elements

To remove a hash element, use delete() function.

Here, we have removed both the key-value pairs which were added in the last example.

  1. my %capitals = (
  2. "India" => "New Delhi" ,
  3. "South Korea" => "Seoul" ,
  4. "USA" => "Washington, D.C." ,
  5. "Australia" => "Canberra"
  6. "Germany " => " Berlin"
  7. " UK " => "London"
  8. );
  9. while (( $key , $value ) = each(%apitals)){
  10. print $key . ", " . $value . "\n" ;
  11. }
  12. #removing element
  13. delete ( $capitals {Germany});
  14. delete ( $capitals {UK});
  15. # Printing new hash
  16. print "\n" ;
  17. while (( $key , $value ) = each(%capitals)){
  18. print $key . ", " . $value . "\n" ;
  19. }


Australia, Canberra
India, New Delhi
USA, Washington D.C.
South Korea, Seoul

Perl deleting Vs Undefining Hash Elements

deleting: In deleting, key-value pair will be deleted from the hash.


  1. delete ( $hash { $key });

undef: In undef, the value will be undefined but key will remain in the hash.


  1. undef $hash { $key };

[Sep 10, 2019] Pro Perl Debugging

May 12, 2012 | Slashdot

This title was published in hardcover in March 2005 by Apress, a relatively new member of the technical publishing world. The publisher has a Web page for the book that includes links to all of the source code in a Zip file, the table of contents in PDF format, and a form for submitting errata. The book comprises 269 pages, the majority of which are organized into 16 chapters:

Introduction (not to be confused with the true Introduction immediately preceding it),

Inspecting Variables and Getting Help, Controlling Program Execution, Debugging a Simple Command Line Program, Tracing Execution, Debugging Modules, Debugging Object-Oriented Perl, Using the Debugger As a Shell, Debugging a CGI Program, Perl Threads and Forked Processes, Debugging Regular Expressions, Debugger Customization, Optimization and Performance Hints and Tips, Command Line and GUI Debuggers, Comprehensive Command Reference, Book References and URLs.

hattmoward ( 695554 ) , Monday December 12, 2005 @02:11PM ( #14240507 )

Re:In defense of print statements ( Score: 5 , Insightful)

How many times is that conditional checked at runtime? They can add up. In perl, you could have it optimized away at compile time...

sub DEBUG() { return 1; }


DEBUG and print "value of blah:", $blah, $/;

but... TIMTOWTDI ;)
Mark_Uplanguage ( 444809 ) , Monday December 12, 2005 @03:13PM ( #14241006 )
Re:In defense of print statements ( Score: 4 , Informative)

When debugging I emphasize the use of "warn" over "print". It's the same syntax, but the warn statements don't get spooled and therefore their timing is quicker.

This is vital when you code just plain blows up. Using "print" means that a statement which got executed before the disaster may not make it to console, thus leading you to believe that it never got executed. "warn" avoids this problem and thus leads you to the problem more accurately. It also makes it easy to globally comment out the warn statements before going releasing the code.

codyk ( 857932 ) , Monday December 12, 2005 @03:20PM ( #14241071 )
Re:In defense of print statements ( Score: 1 )

Or you could just . . .

use Smart::Comments;
### Expected: "a bunch o stuff" Got: $stuff

. . . and have debugging statements that are easier to write, can be turned off in one place, and don't waste efficiency checking a bunch of conditionals.
see 0 .1/lib/Smart/ []

licamell ( 778753 ) * , Monday December 12, 2005 @01:47PM ( #14240302 )
use strict and Data::Dumper! ( Score: 5 , Insightful)

#! /usr/local/bin/perl
# Two things that make debugging perl easy:

use strict;
use Data::Dumper; ›

Baron von Leezard ( 675918 ) , Monday December 12, 2005 @03:22PM ( #14241092 )
Re:use strict and Data::Dumper! ( Score: 1 )

[That's one freelance Perl programmer I'll have to remember never to hire.]

Seriously, I'm one of those people who use a debugger every day. Actually, when I write new code in Perl, often the first thing I do is step through it in the debugger to make sure it does what I think it should. Especially in Perl, it is very easy to accidentally do something that's a little off. With the "wait until something goes wrong before I investigate" attitude demonstrated here, you'll never know anything is amiss until some nasty bug crops up as a result. Using the debugger to sanity check my code means that I catch most bugs before they ever cause problems.

I'm sure I'm going to get some snide remarks about this approach, but really, I've been a serious Perl programmer for about eight years now, and often write moderately complex Perl programs that work perfectly the first time--run through the debugger or not. I can't say that about any other language, and it's something most people can't say about any language, let alone Perl ;)

[Sep 10, 2019] logging - Perl - Output the log files - Stack Overflow

Aug 27, 2015 |

Perl - Output the log files Ask Question Asked 4 years ago Active 4 years ago Viewed 3k times 1 2

Arunesh Singh ,Aug 27, 2015 at 8:53

I have created a perl that telnet to multiple switches. I would like to check if telnet functions properly by telneting the switch.

This is my code to telnet to the switches:

use warnings;
use Net::Cisco;

open( OUTPUT, ">log.txt" );
open( SWITCHIP, "ip.txt" ) or die "couldn't open ip.txt";

my $count = 0;

while (<SWITCHIP>) {
    my $switch = $_;
    my $tl     = 0;
    my $t      = Net::Telnet::Cisco->new(
        Host => $switch,
        Prompt =>
        Timeout => 5,
        Errmode => 'return'
    ) or $tl = 1;

    my @output = ();
    if ( $tl != 1 ) {
        print "$switch Telnet success\n";
    else {
        my $telnetstat = "Telnet Failed";
        print "$switch $telnetstat\n";

This is my output status after I was testing 7 switches: Telnet success Telnet success Telnet success Telnet success Telnet Failed Telnet success

I would like to convert the telnet result as log file.
How to separate successful and failed telnet results by using perl?

Danny Luk ,Aug 28, 2015 at 8:40

Please Try the following
use warnings;
use Net::Cisco;
################################### S
open( OUTPUTS, ">log_Success.txt" );
open( OUTPUTF, ">log_Fail.txt" );
################################### E
open( SWITCHIP, "ip.txt" ) or die "couldn't open ip.txt";

my $count = 0;

while (<SWITCHIP>) {
    my $switch = $_;
    my $tl     = 0;
    my $t      = Net::Telnet::Cisco->new(
        Host => $switch,
        Prompt =>
        Timeout => 5,
        Errmode => 'return'
    ) or $tl = 1;

    my @output = ();
################################### S
    if ( $tl != 1 ) {
        print "$switch Telnet success\n"; # for printing it in screen
        print OUTPUTS "$switch Telnet success\n"; # it will print it in the log_Success.txt
    else {
        my $telnetstat = "Telnet Failed";
        print "$switch $telnetstat\n"; # for printing it in screen
        print OUTPUTF "$switch $telnetstat\n"; # it will print it in the log_Fail.txt
################################### E
################################### S
################################### E

Danny Luk ,Aug 28, 2015 at 8:39

In print statement after print just write the filehandle name which is OUTPUT in your code:
print OUTPUT "$switch Telnet success\n";


print OUTPUT "$switch $telnetstat\n";

A side note: always use a lexical filehandle and three arguments with error handling to open a file. This line open(OUTPUT, ">log.txt"); you can write like this:

open my $fhout, ">", "log.txt" or die $!;

Sobrique ,Aug 28, 2015 at 8:39

Use Sys::Syslog to write log messages.

But since you're opening a log.txt file with the handle OUTPUT , just change your two print statements to have OUTPUT as the first argument and the string as the next (without a comma).

my $telnetstat;
if($tl != 1) {
  $telnetstat = "Telnet success";
} else {
  $telnetstat = "Telnet Failed";
print OUTPUT "$switch $telnetstat\n";

# Or the shorter ternary operator line for all the above:
print OUTPUT $swtich . (!$tl ? " Telnet success\n" : " Telnet failed\n");

You might consider moving close to an END block:


Not only because it's in your while loop.

[Sep 06, 2019] Did CIA Director William Casey really say, "We'll know our disinformation program is complete when everything the American public believes is false"?

Sep 06, 2019 |

Matt Egan , former US Intelligence Officer (1967-2006) Answered Sep 8, 2017 · Author has 4.8k answers and 2.3m answer views

It does appear he said something very much along those lines, though I doubt it meant what it appears to mean absent the context. He made the statement not long after he became the Director of Central Intelligence, during a discussion of the fact that, to his amazement, about 80 percent of the contents of typical CIA intelligence publications was based on information from open, unclassified sources, such as newspapers and magazines.

Apparently, and reasonably, he judged that about the same proportion of Soviet intelligence products was probably based on open sources, as well. That meant that CIA disinformation programs directed at the USSR wouldn't work unless what was being disseminated by US magazines and newspapers on the same subjects comported with what the CIA was trying to sell the Soviets.

Given that the CIA could not possibly control the access to open sources of all US publications, the subjects of CIA disinformation operations had to be limited to topics not being covered by US public media. To be sure, some items of disinformation planted by the CIA in foreign publications might subsequently be discovered and republished by US media. I'm guessing the CIA would not leap to correct those items.

But that is a far cry from concluding that the CIA would (or even could) arrange that "everything the American public believes is false."

[Sep 06, 2019] The fact that our "leaders" continue to put our brave young men and women in harm's way, as we also kill millions of "others", and the American people stand idly by, is a proof of Casey quote . "So and so is evil and he oppresses his people, so we need to remove him and bring democracy to such and such country!"

Notable quotes:
"... You've heard of the "Manchurian Candidate"? We are the "Manchurian Populace". They spout the aforementioned mantra, and we all turn into mindless followers ..."
"... Assume that CIA launched disinformation in a hostile country to impact them. Then international news agencies picked it up and it got published by media in the US. If the disinformation were harmless to the US, then our Federal Government would not comment and would let the disinformation stand. To repudiate it might have bad effects on national security. Would this be a case of the CIA lying to the American people? No. ..."
"... The CIA once had influence in a number of English language publications abroad, some of which stories were reprinted in the US media. This was known as "blowback", and unintended in most cases. ..."
"... The CIA fabricated a story that the Russians in Afghanistan made plastic bombs in the shape of toys, to blow up children. Casey repeated this story, knowing it to be disinformation, as fact to US journalists and politicians. ..."
"... He doesn't need to have said it. CIA has run many disinformation campaigns against American public. Operation Mockingbird ..."
Sep 06, 2019 |

Thommy Berlin

Not that it matters. No conservative I know retains the ability to think off script, let alone rise above his indoctrination, and neither the script or their indoctrination allows this to be real.

So as far as they're concerned, it simply isn't possible.

Neither was David Stockman's admission that the idea of 'trickle down' was to bankrupt the federal government so they could finally do away with social security, while making themselves filthy rich...

Or Reagan being a traitor for negotiating with the Iranians BEFORE he was elected....

Or Bush II stealing the 2000 election....'s a LONG list....

Rael Sackey Answered Mar 16, 2019

The fact that our "leaders" continue to put our brave young men and women in harm's way, as we also kill millions of "others", and the American people stand idly by, is proof enough for me. "So and so is evil and he oppresses his people, so we need to remove him and bring democracy to such and such country!" This has been the game plan for decades. In the info age we know all this.

A convicted war criminal like Eliot Abrams is hired by a president the media and the Democrats hate and call a liar, and we suddenly suspend our disbelief, and follow blindly into another regime change war while we are buddies with many dictators around the world.

You've heard of the "Manchurian Candidate"? We are the "Manchurian Populace". They spout the aforementioned mantra, and we all turn into mindless followers of these MONSTERS! 806 views · View 3 Upvoters

Don Harmon, former intell analyst, former coll. poli sci professor. (1999-2013) Answered Jan 21, 2017 ·

About two years ago, one Barbara Honneger said in Quora that she was there. But I can find no credible news source that affirms this.

It is possible that Director Casey said it without any negative significance for the American people. How?

Assume that CIA launched disinformation in a hostile country to impact them. Then international news agencies picked it up and it got published by media in the US. If the disinformation were harmless to the US, then our Federal Government would not comment and would let the disinformation stand. To repudiate it might have bad effects on national security. Would this be a case of the CIA lying to the American people? No.

Fred Landis, Investigative Reporter Answered Sep 10, 2013 ·

The CIA once had influence in a number of English language publications abroad, some of which stories were reprinted in the US media. This was known as "blowback", and unintended in most cases.

The CIA fabricated a story that the Russians in Afghanistan made plastic bombs in the shape of toys, to blow up children. Casey repeated this story, knowing it to be disinformation, as fact to US journalists and politicians.

Ozgur Zeren , Author at Answered Oct 22, 2014

He doesn't need to have said it. CIA has run many disinformation campaigns against American public. Operation Mockingbird

[Sep 02, 2019] perlcperl - a perl5 with classes, types, compilable, company friendly

Sep 02, 2019 |

Compile-time optimizations

cperl adds many more traditional compile-time optimizations: more and earlier constant folding, type promotions, shaped arrays, usage of literal and typed constants, loop unrolling, omit unnecessary array bounds checks, function inlining and conversion of static method calls to functions.

Perl 5 only inlines constant function bodies with an explicit empty () prototype.

    sub x() {1+2} # inlined in perl5
    sub x   {1+2} # inlined in cperl only

cperl inlines constant function bodies even without empty prototype declaration, has type declarations for most internal ops, and optimizes these ops depending on the argument types; currently for all arithmetic unops and binops, and the data-accessing ops padsv, svop, and sassign. opnames.h stores PL_op_type_variants , all possible type promotions for each op. opcode.h stores PL_op_type with the type declarations of all ops.

[Sep 02, 2019] This Perl Goes To 11

Sep 02, 2019 |

Perl 11 is not (yet) an actual version of Perl; rather, Perl 11 is currently a philosophy with 3 primary tenets:

Perl 11 promotes ideas which will make Perl 5 pluggable at the following levels:

This will open up the doors to many kinds of language / technology experimentation, without endangering the existing Perl 5 / CPAN code bases that we depend on every day.

Pluggable VMs would be parrot, p2, JVM or .NET running Perl5 and Perl 6 code. 5 + 6 == 11!

Perl 11 Projects

The following projects are important in reaching the vision of Perl 11:


A Restricted Perl by Will Braswell which translates a medium-magic subset of Perl 5 into C/C++ using Inline::C and Inline::CPP


cperl is an improved variant of perl5, running all of perl5 and CPAN code. With many perl6 features, just faster.
Faster than perl5 and perl6. It is stable and usable, but still in development with many more features being added soon.

... ... ...

Perl 11 Links

[Sep 02, 2019] Negative regex for Perl string pattern match

Sep 02, 2019 |

mirod ,Jun 15, 2011 at 17:21

I have this regex:
if($string =~ m/^(Clinton|[^Bush]|Reagan)/i)
  {print "$string\n"};

I want to match with Clinton and Reagan, but not Bush.

It's not working.

Calvin Taylor ,Jul 14, 2017 at 21:03

Sample text:

Clinton said
Bush used crayons
Reagan forgot

Just omitting a Bush match:

$ perl -ne 'print if /^(Clinton|Reagan)/' textfile
Clinton said
Reagan forgot

Or if you really want to specify:

$ perl -ne 'print if /^(?!Bush)(Clinton|Reagan)/' textfile
Clinton said
Reagan forgot

GuruM ,Oct 27, 2012 at 12:54

Your regex does not work because [] defines a character class, but what you want is a lookahead:
(?=) - Positive look ahead assertion foo(?=bar) matches foo when followed by bar
(?!) - Negative look ahead assertion foo(?!bar) matches foo when not followed by bar
(?<=) - Positive look behind assertion (?<=foo)bar matches bar when preceded by foo
(?<!) - Negative look behind assertion (?<!foo)bar matches bar when NOT preceded by foo
(?>) - Once-only subpatterns (?>\d+)bar Performance enhancing when bar not present
(?(x)) - Conditional subpatterns
(?(3)foo|fu)bar - Matches foo if 3rd subpattern has matched, fu if not
(?#) - Comment (?# Pattern does x y or z)

So try: (?!bush)

[Sep 02, 2019] How to get the current line number of a file open using Perl

Sep 02, 2019 |

How to get the current line number of a file open using Perl? Ask Question Asked 8 years, 3 months ago Active 6 months ago Viewed 33k times 25 1

tadmc ,May 8, 2011 at 17:08

open my $fp, '<', $file or die $!;

while (<$fp>) {
    my $line = $_;
    if ($line =~ /$regex/) {
        # How do I find out which line number this match happened at?

close $fp;

tchrist ,Apr 22, 2015 at 21:16

Use $. (see perldoc perlvar ).

tchrist ,May 7, 2011 at 16:48

You can also do it through OO interface:
use IO::Handle;
# later on ...
my $n = $fp->input_line_number();

This is in perldoc perlvar , too.

> ,

Don't use $. , nor $_ or any global variable. Use this instead:
while(my $line = <FILE>) {
  print $line unless ${\*FILE}->input_line_number == 1;

To avoid this and a lot of others Perl gotchas you can use on Atom or VSCode packages like linter-perl . Stop making Perl a write-only language !

[Aug 28, 2019] LogProgramInfo A Perl module to collect and log data for bioinformatics pipelines

Aug 28, 2019 |
Find articles by John M. Macdonald Paul C. Boutros

Informatics and Biocomputing Program, Ontario Institute for Cancer Research, Suite 510, MaRS Centre, 661 University Ave, Toronto, Ontario Canada

Departments of Medical Biophysics and Pharmacology & Toxicology, University of Toronto, Toronto, Ontario Canada

Find articles by Paul C. Boutros Author information Article notes Copyright and License information Disclaimer Informatics and Biocomputing Program, Ontario Institute for Cancer Research, Suite 510, MaRS Centre, 661 University Ave, Toronto, Ontario Canada Departments of Medical Biophysics and Pharmacology & Toxicology, University of Toronto, Toronto, Ontario Canada John M. Macdonald, Email: . Contributor Information . corresponding author Corresponding author. # Contributed equally. Received 2015 Nov 26; Accepted 2016 Jun 1. Copyright © The Author(s) 2016

Open Access This article is distributed under the terms of the Creative Commons Attribution 4.0 International License ( ), which permits unrestricted use, distribution, and reproduction in any medium, provided you give appropriate credit to the original author(s) and the source, provide a link to the Creative Commons license, and indicate if changes were made. The Creative Commons Public Domain Dedication waiver ( ) applies to the data made available in this article, unless otherwise stated. Go to:

Abstract Background

To reproduce and report a bioinformatics analysis, it is important to be able to determine the environment in which a program was run. It can also be valuable when trying to debug why different executions are giving unexpectedly different results.


Log::ProgramInfo is a Perl module that writes a log file at the termination of execution of the enclosing program, to document useful execution characteristics. This log file can be used to re-create the environment in order to reproduce an earlier execution. It can also be used to compare the environments of two executions to determine whether there were any differences that might affect (or explain) their operation.


The source is available on CPAN (Macdonald and Boutros, Log-ProgramInfo. ).


Using Log::ProgramInfo in programs creating result data for publishable research, and including the Log::ProgramInfo output log as part of the publication of that research is a valuable method to assist others to duplicate the programming environment as a precursor to validating and/or extending that research. Keywords: Reproducibility, Log, Environment Go to: Background

Reproducibility is a major concern in science as a whole, and computational biology in particular. For reproducibility, it is not sufficient to provide access to the raw data -- it is ever more critical to also provide access to the program code used to analyse those data [ 2 ]. But the program code is a dynamic mixture of program text, command line arguments, libraries, and various other environmental aspects -- all of which may need to be exactly reproduced to achieve the same results. So, simply providing access to the code used is not a complete solution. It is necessary, but not sufficient.

The need for reproducibility is growing because our pipelines are getting increasingly complex: a typical sequencing pipeline might involve a chain of a dozen unique tools [ 3 ]. But reproducing these pipelines is fundamentally very difficult, in part because it requires duplicating the versions of all dependent tools and libraries used in an analysis. Given the rapid rate of release of updates to common tools (e.g. BWA had 7 updates during the course of 2014 [ 4 ], this can be a significant challenge.

Among the best practices for scientific computing (e.g. [ 5 ]) is listed the need to collect and publish:

A large fraction of pipelines for bioinformatics are written in the Perl programming language (e.g. BioPerl [ 6 ]). However, for logging the precise state of a program at run-time, and capturing all the dependency versions and other key information, there are no automated choices available.

To resolve this issue, we introduce here the module Log::ProgramInfo to facilitate run-time logging of Perl-based pipelines, thereby directly improving the reproducibility of modern bioinformatic analyses.

A further advantage to such tracking information is the ability to test an analsis using later versions of the component tools to determine whether they provide different results (possibly more accurate if the later releases provide better resolution; possibly identifying erroneous results in the original analysis if the tools have been updated with critical fixes to their operation). Go to:

Related work

A search found some programs for related processes but nothing that served the same purposes.

There are some programs available to collect and document the computing process - by recording the steps invoved, including command lines and arguments during the actual data processing. Such a program could work well together with the described module but addresses a different aspect of the reproducibility issue. In our lab, when the workflow of the data analysis was sufficiently complex to require such a description, we instead write a program to encapsulate that process, so there is no long list of manual processing steps to document.

In particular, the program (ReproZip) [ 7 ] was capable of discovering and bundling together all of the programs used during the execution of a process. That seems to have different trade-offs. Such a bundle is only useful on similar hardware and it provides no possibility for assisting with script library version info, or in allowing a later run to use selected variations on the programming environment (such as allowing updated versions of programs that still have the same function but have had security problems fixed). Go to: Implementation

The Log::ProgramInfo module Macdonald and Boutros, Log-ProgramInfo. is available as open source, and has been distributed on CPAN (the Comprehansive Perl Archive Network - used as the standard distribution mechanism for the vast majority of open source Perl modules, and described in the Perl documentation with the command "perldoc perlmodinstall").

Log::ProgramInfo is enabled simply by being included with a Perl use statement. Since its effect is global to the program, it should be enabled directly from the main program, or from a utility module that contains global configuration settings for a suite of programs.

Any desired setting of non-default values for the options can be provided either through environment variables, or as "import" list options.

When the module is used for the first time, the loading process carries out a number of actions for its operation:

Every time the Log::ProgramInfo module is used, the import list is processed and any values in it are used to update the option values. (The first time it is used, this processing happens after the initialization steps described above.)

That permits a common group of option settings be processed first, and then specific exceptions to that list over-ridden.

Any option settings provided in environent variables will over-ride the corresponding setting (whether a default or specified by the program import lists). This allows changing the option settings for individual runs so that the log can be suppressed, enabled, or redirected for a single run of the program.

The code that prints the log information ensures that it only executes once (in case multiple signals, or a signal during program termination, would cause it to be called additional times).

If the main body of the program changes a signal handler after Log::ProgramInfo has set it up, that will usually not interfere with Log::ProgramInfo. Usually, the program will catch signals and handle them in a way that allows it continue to operate, or to terminate with an exception. It is only if the program resets a signal handler to its default (abort without normal termination processing) that Log::ProgramInfo's log will not be written. That is not a problem for publication - if the program is being killed by some signal then it is not yet running successfully, and thus not yet ready for publication. However, it does mean that the log might not be available as a diagnostic aid in such situations.

For most cases, that is the only interaction between the program and Log::ProgramInfo.

The one additional interaction that might occur is if there is information unique to the program that is desired to be logged. The function

Log::ProgramInfo::add_extra_logger can be called by the program to specify a callable function that will write additional information to the log. (See the program documentation for precise details.) Go to: Results and discussion

Parameters are available to control the logging process: whether (and if so, where) a log is to be written. Choosing the location where the log is written allows collecting and managing this important information in a way that co-ordinates with the entire set of computational activity carried out for a research project (or an entire organisation's collection of research projects). The default name used for the log file includes the name of the program that is being reported upon as well as a time-stamp to distinguish separate runs -- you might choose to override the name or directory path to provide more complete organisation of logged results. Suppressing log output can be useful for runs that are not intended to generate reproducible results, such as while the software is being developed. However, even in such cases, it might turn out to be useful to have this log output to assist diagnosing problems with system configuration changes -- to confirm that the environment being used is the one that was intended and that updates have actually occurred, etc.

There is an additional parameter that permits the logged information to be sent to a separate logging mechanism, such as a Log4Perl log. This would allow the information to be collected with the other logged information from the program. The output to such logs is mixed with the other logged output from the program, and is also usually reformatted to some extent. Such logs cannot be processed by the Log::ProgramInfo parser provided with the package; hence the normal action for Log::ProgramInfo is to still write its own log file as well. Go to: Log output

The output created by Log::ProgramInfo contains the following information:

The format of the log file is designed to be easily parsed. A parsing subroutine is provided in the package. You could call that subroutine from a program that analyses logs according to your needs. See the program documentation for details. If you have written the log info using a logging module such as Log4Perl, you will have to separately extract the bare ProgramInfo log information out of that log, separating it from any other logging by the program, and removing any line decorations added by the log module. Go to: Example

Here is an example of using Log::ProgramInfo. Assume a simple program, called

An external file that holds a picture, illustration, etc. Object name is 13029_2016_55_Figa_HTML.gif Open in a separate window

When you run it, you get two lines of output.

An external file that holds a picture, illustration, etc. Object name is 13029_2016_55_Figb_HTML.gif Open in a separate window

The first line is the expected output from the program, the second line comes from Log::ProgramInfo to tell you that a log file was created, and where.

Now, take a look at the log file:

An external file that holds a picture, illustration, etc. Object name is 13029_2016_55_Figc_HTML.gif Open in a separate window

Now that you have a log file, you still have to make use of it. Typically, you would treat this log file as one of the output files of your processing activities. So, if you normally discard the output files (e.g. for a test run while developing the pipeline), you will likely also discard the log. On the other hand, for significant runs, you would collect the log file along with the other output files, labelling and storing them as appropriate for reference. The log file would be available as a synopsis of how the output data was created, ready to be used for publication, or reproducing the process (either to validate the results, or to apply the same process to additional data for subsequent research). Go to: Limitations

The C environment is not well built for program introspection activities such as determining which static and/or dynamic libraries have been linked into the program's executable image. This module lists the version of libc that was build into the perl binary - but that information can be out of date. A future release may try to get info about other libraries beyond libc.

Another major problem is that even if a perl module is downloaded from CPAN (which would be one way of ensuring that other people could get the same version), the install process that puts it into the library path for perl programs can be done in may ways, and often is not even done on the same computer as the one that is running the perl program. So, it is not easy to do any sort of detailed validation - the downloaded package bundle is not accessible in any determinable way (and possibly not at all) to the program itself (and thus to Log::ProgramInfo). While it would be possible to compute checksums for every library module that has been loaded, that would take a significant amount of time and is not currently being done. It may be added as an option that could request it explicitly. Go to: Conclusion

Module Log::ProgramInfo provides a convenient way of logging information about the way a program is run. Adding it to existing programs is as easy as adding one line to the program or any module the program already includes.

Log::ProgramInfo's output file can be easily included in the published results along with the actual source code (or references to where it can be found). With this log output, other researchers have information necessary to any meaningful attempt to reproduce the original research, either in the process of validating or extending that research.

Log::ProgramInfo is a good candidate for inclusion in modules intended to mandate standards, and may find use well beyond the field of bioinformatics. Go to: Availability and requirements

Go to: Acknowledgements

Special thanks to Julie Livingstone and Renasha Small-O'Connor for editorial assistance. Go to: Footnotes

cc Bug Reports To:


This study was conducted with the support of the Ontario Institute for Cancer Research to PCB through funding provided by the Government of Ontario. This work was supported by Prostate Cancer Canada and is proudly funded by the Movember Foundation – Grant #RS2014-01. Dr. Boutros was supported by a Terry Fox Research Institute New Investigator Award and a CIHR New Investigator Award. This project was supported by Genome Canada through a Large-Scale Applied Project contract to PCB, Dr. Sohrab Shah and Dr. Ryan Morin.

Authors' contributions

The module was written by the authors. Both authors read and approved the final manuscript.

Competing interests

The authors declare that they have no competing interests.

Go to: Contributor Information

John M. Macdonald, Email: .

Paul C. Boutros, Email: . Go to: References 1. Macdonald J, Boutros P. Log-ProgramInfo. module available from CPAN. . 2. Nature-editorial. Code share. Nature. 2014;514. doi:10.1038/514536a. 3. Ewing A, Houlahan K, Hu Y, Ellrott K, Caloian C, Yamaguchi T, Bare J, P'ng C, Waggott D, Sabelnykova V, ICGC-TCGA DREAM Somatic Mutation Calling Challenge participants. Kellen M, Norman T, Haussler D, Friend S, Stolovitzky G, Margolin A, Stuart J, Boutros P. Combining accurate tumour genome simulation with crowd-sourcing to benchmark somatic single nucleotide variant detection. Nat Methods. 2015; 514 :623–30. doi: 10.1038/nmeth.3407. [ PMC free article ] [ PubMed ] [ CrossRef ] [ Google Scholar ] 4. sourceforge-BWA-files. Sourceforge File Listing for BWA on 30 Apr 2015. hand counted from web page. . 5. Wilson G, Aruliah DA, Brown CT, Hong NPC, Davis M, Guy RT, Haddock SHD, Huff KD, Mitchell IM, Plumbley MD, Waugh B, White EP, Wilson P. Best practices for scientific computing. PLoS Biol. 2014;12(1). doi:10.1371/journal.pbio.1001745. [ PMC free article ] [ PubMed ] 6. Stajich J, Block D, Boulez K, Brenner SE, Dagdigian C, Fuellen G, Gilbert JGR, Korf I, Lapp H, Lehväslaiho H, Matsalla C, Mungall CJ, Osborne BI, Popock MR, Schattner P, Senger M, Stein L, Stupka E, Wilkinson MD, Birney E. The bioperl toolkit: Perl modules for the life sciences. Genome Res. 2002; 12 (10):1611–8. doi: 10.1101/gr.361602. [ PMC free article ] [ PubMed ] [ CrossRef ] [ Google Scholar ] 7. Chirigati F, Shasha D, Freire J. Presented as Part of the 5th USENIX Workshop on the Theory and Practice of Provenance. Berkeley: USENIX; 2013. Reprozip: Using provenance to support computational reproducibility. [ Google Scholar ]

Articles from Source Code for Biology and Medicine are provided here courtesy of BioMed Central

[Aug 28, 2019] Echo Command in Linux with Examples

Notable quotes:
"... The -e parameter is used for the interpretation of backslashes ..."
"... The -n option is used for omitting trailing newline. ..."
Aug 28, 2019 |

The -e parameter is used for the interpretation of backslashes

... ... ...

To create a new line after each word in a string use the -e operator with the \n option as shown
$ echo -e "Linux \nis \nan \nopensource \noperating \nsystem"

... ... ...

Omit echoing trailing newline

The -n option is used for omitting trailing newline. This is shown in the example below

$ echo -n "Linux is an opensource operating system"

Sample Output

Linux is an opensource operating systemjames@buster:/$

[Aug 28, 2019] How do I import a perl module outside of @INC that does not end in .pm - Stack Overflow

Aug 22, 2019 |

mob ,Aug 22 at 19:47


I am attempting to import a perl module that does not end in .pm with a method similar to this answer :

use lib "/hard/coded/directory"; use scripting;

However, when I attempt to import a module in this way, I get the following error when running perl -c :

Can't locate in @INC (@INC contains: ... ... ... /hard/coded/directory) at name of script line 47.

BEGIN failed--compilation aborted at name of script line 47.


How do I import a perl module outside of @INC that does not have .pm at the end of the file?

ikegami ,Aug 22 at 20:04

If the file has a package directive, the file name and the package directive need to match, so simply fix the file name.

If the file doesn't have a package directive, you don't have a module , and you shouldn't use use or require . This can cause problems.

What you have is sometimes called a library, and you should use do .

   or die $@ || $!;

(For proper error checking, the file needs to result in a true value.)

That said, you are probably trying to do something really awful. I'm guessing you're either have a configuration file written in Perl or a poorly written module. Perl is not a suitable choice of language for a configuration file, and avoiding namespaces is just bad programming with no benefit.

ikegami ,Aug 22 at 20:10

If the source file does not define new namespaces or classes and you just want to read the function definitions or data from a file, Perl provides the do and require functions.
do "scripting";
require "scripting";

The difference between them is that require will look for the file to evaluate to a true value (it expects the last statement in the file to resolve to a non-zero, non-empty value), and will emit a fatal error if this does not happen. (You will often see naked 1; statements at the end of modules to satisfy this requirement).

If scripting really contains class code and you do need all the functionality that the use function provides, remember that

use Foo::Bar qw(stuff);

is just syntactic sugar for

    $file = <find Foo/ on @INC>;
    require "$file";
    Foo::Bar->import( qw(stuff) )

and suggests how you can workaround your inability to use use :

    require "scripting";

In theory, the file scripting might define some other package and begin with a line like package Something::Else; . Then you would load the package in this module with

    require "scripting";

[Aug 27, 2019] How do I get the filename and line number in Perl - Stack Overflow

Aug 27, 2019 |

How do I get the filename and line number in Perl? Ask Question Asked 8 years, 10 months ago Active 8 years, 9 months ago Viewed 6k times 6

Elijah ,Nov 1, 2010 at 17:35

I would like to get the current filename and line number within a Perl script. How do I do this?

For example, in a file call :

my $foo = 'bar';
print 'Hello World';
print functionForFilename() . ':' . functionForLineNo();

It would output:

Hello World

tchrist ,Nov 2, 2010 at 19:13

These are available with the __LINE__ and __FILE__ tokens, as documented in perldoc perldata under "Special Literals":

The special literals __FILE__, __LINE__, and __PACKAGE__ represent the current filename, line number, and package name at that point in your program. They may be used only as separate tokens; they will not be interpolated into strings. If there is no current package (due to an empty package; directive), __PACKAGE__ is the undefined value.

Eric Strom ,Nov 1, 2010 at 17:41

The caller function will do what you are looking for:
sub print_info {
   my ($package, $filename, $line) = caller;

print_info(); # prints info about this line

This will get the information from where the sub is called, which is probably what you are looking for. The __FILE__ and __LINE__ directives only apply to where they are written, so you can not encapsulate their effect in a subroutine. (unless you wanted a sub that only prints info about where it is defined)


You can use:
print __FILE__. " " . __LINE__;

[Aug 26, 2019] Static and state variables in Perl

Aug 26, 2019 |

In most of the cases we either want a variable to be accessible only from inside a small scope, inside a function or even inside a loop. These variables get created when we enter the function (or the scope created by a a block) and destroyed when we leave the scope.

In some cases, especially when we don't want to pay attention to our code, we want variables to be global, to be accessible from anywhere in our script and be destroyed only when the script ends. In General having such global variables is not a good practice.

In some cases we want a variable to stay alive between function calls, but still to be private to that function. We want it to retain its value between calls.

Are you serious about Perl? Check out my Beginner Perl Maven book .
I have written it for you!

In the C programming language one can designate a variable to be a static variable . This means it gets initialized only once and it sticks around retaining its old value between function calls.

In Perl, the same can be achieved using the state variable which is available starting from version 5.10, but there is a construct that will work in every version of Perl 5. In a way it is even more powerful.

Let's create a counter as an example:

state variable
  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. sub count {
  5. state $counter = 0 ;
  6. $counter ++;
  7. return $counter ;
  8. }
  9. say count ();
  10. say count ();
  11. say count ();
  12. #say $counter;

In this example, instead of using my to declare the internal variable , we used the state keyword.

$counter is initialized to 0 only once, the first time we call counter() . In subsequent calls, the line state $counter = 0; does not get executed and $counter has the same value as it had when we left the function the last time.

Thus the output will be:


If we removed the # from last line, it would generate a Global symbol "$counter" requires explicit package name at ... line ... error when trying to compile the script. This just shows that the variable $counter is not accessible outside the function.

state is executed in the first call

Check out this strange example:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. sub count {
  5. state $counter = say "world" ;
  6. $counter ++;
  7. return $counter ;
  8. }
  9. say "hello" ;
  10. say count ();
  11. say count ();
  12. say count ();

This will print out


showing that the state $counter = say "world"; line only gets executed once. In the first call to count() say , which was also added in version 5.10 , will return 1 upon success.

static variables in the "traditional" way
  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. {
  5. my $counter = 0 ;
  6. sub count {
  7. $counter ++;
  8. return $counter ;
  9. }
  10. }
  11. say count ();
  12. say count ();
  13. say count ();

This provides the same result as the above version using state , except that this could work in older versions of perl as well. (Especially if I did not want to use the say keyword, that was also introduced in 5.10.)

This version works because functions declarations are global in perl - so count() is accessible in the main body of the script even though it was declared inside a block. On the other hand the variable $counter is not accessible from the outside world because it was declared inside the block. Lastly, but probably most importantly, it does not get destroyed when we leave the count() function (or when the execution is outside the block), because the existing count() function still references it.

Thus $count is effectively a static variable.

First assignment time
  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. say "hi" ;
  5. {
  6. my $counter = say "world" ;
  7. sub count {
  8. $counter ++;
  9. return $counter ;
  10. }
  11. }
  12. say "hello" ;
  13. say count ();
  14. say count ();
  15. say count ();

This shows that in this case too, the declaration and the initial assignment my $counter = say "world"; happens only once, but we can also see that the assignment happens before the first call to count() as if the my $counter = say "world"; statement was part of the control flow of the code outside of the block.

Shared static variable

This "traditional" or "home made" static variable has an extra feature. Because it does not belong to the the count() subroutine, but to the block surrounding it, we can declare more than one functions in that block and we can share this static variable between two or even more functions.

For example we could add a reset_counter() function:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. {
  5. my $counter = 0 ;
  6. sub count {
  7. $counter ++;
  8. return $counter ;
  9. }
  10. sub reset_counter {
  11. $counter = 0 ;
  12. }
  13. }
  14. say count ();
  15. say count ();
  16. say count ();
  17. reset_counter ();
  18. say count ();
  19. say count ();

Now both functions can access the $counter variable, but still nothing outside the enclosing block can access it.

Static arrays and hashes

As of now, you cannot use the state declaration in list context. This means you cannot write state @y = (1, 1); . This limitation could be overcome by some extra coding. For example in this implementation of the Fibonacci series, we checked if the array is empty and set the default values:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. sub fib {
  5. state @y ;
  6. @y = ( 1 , 1 ) if not @y ; # workaround initialization
  7. push @y , $y [ 0 ]+ $y [ 1 ];
  8. return shift @y ;
  9. }
  10. say fib ();
  11. say fib ();
  12. say fib ();
  13. say fib ();
  14. say fib ();

Alternatively we could use the "old-style" static variable with the enclosing block.

Here is the example generating the Fibonacci series:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. {
  5. my @y = ( 1 , 1 );
  6. sub fib {
  7. push @y , $y [ 0 ]+ $y [ 1 ];
  8. return shift @y ;
  9. }
  10. }
  11. say fib ();
  12. say fib ();
  13. say fib ();
  14. say fib ();

[Aug 26, 2019] Beginning Perl Programming From Novice to Professional

Aug 26, 2019 |

Debugger Commands The debugger has many built-in commands. The most common are as follows.



!! cmd

Runs the command (cmd) in a separate process (this is typically a shell command)


Interactive help

H -num

Prints last "num" commands (excludes single character commands)


Lists the next line of code to be executed


Steps through a statement (if subroutines are called, executes over the subroutine)


Quits the debugger


Steps through a statement (if subroutines are called, executes one subroutine statement at a time)


Displays all of the variables in package (defaults to main)

[Aug 26, 2019] debugging - How can I debug a Perl script - Stack Overflow

Jun 27, 2014 |

Matthew Lock ,Jun 27, 2014 at 1:01

To run your script under perl debugger you should use -d switch:
perl -d

But perl is flexible. It supply some hooks and you may force debugger to work as you want

So to use different debuggers you may do:

perl -d:DebugHooks::Terminal
# OR
perl -d:Trepan

Look these modules here and here

There are several most interesting perl modules that hook into perl debugger internals: Devel::NYTProf , Devel::Cover

And many others


If you want to do remote debug (for cgi or if you don't want to mess output with debug command line) use this:

given test:

use v5.14;
say 1;
say 2;
say 3;

Start a listener on whatever host and port on terminal 1 (here localhost:12345):

$ nc -v -l localhost -p 12345

for readline support use rlwrap (you can use on perl -d too):

$ rlwrap nc -v -l localhost -p 12345

And start the test on another terminal (say terminal 2):

$ PERLDB_OPTS="RemotePort=localhost:12345" perl -d test

Input/Output on terminal 1:

Connection from

Loading DB routines from version 1.49
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(test:2): say 1;
  DB<1> n
main::(test:3): say 2;
  DB<1> select $DB::OUT

  DB<2> n
main::(test:4): say 3;
  DB<2> n
Debugged program terminated.  Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.  

Output on terminal 2:


Note the sentence if you want output on debug terminal

select $DB::OUT

If you are vim user, install this plugin: dbg.vim which provides basic support for perl

[Aug 26, 2019] D>ebugging - How to use the Perl debugger

Aug 26, 2019 |
This is like "please can you give me an example how to drive a car" .

I have explained the basic commands that you will use most often. Beyond this you must read the debugger's inline help and reread the perldebug documentation

The debugger will do a lot more than this, but these are the basic commands that you need to know. You should experiment with them and look at the contents of the help text to get more proficient with the Perl debugger

[Aug 03, 2019] Was future President George H. W. Bush at Dealey Plaza during JFK's assassination - Quora

Notable quotes:
"... There is a photo of someone who looks like him standing in front of the School Book Depository. Bush is one of the few people in America who can't remember where he was that day. ..."
Aug 03, 2019 |

Kevin Stewart , Writer Answered Nov 4 2018 · Author has 370 answers and 39.7k answer views

There is some flimsy photo evidence of someone who looked like him in Dealey Plaza, so my answer would be, "not sure." But anecdotally, there sure seems to be a large number of "coincidences" around a guy who could apparently walk across a snow covered field without leaving foot prints , so maybe.

Since the beginning, the rumored driving motive for JFK's assassination, (from both sides really) was the cluster-fuck known as "The Bay of Pigs invasion," so we'll start there. At the end of Mark Lane's book "Plausible Denial," (the account of E. Howard Hunt's ill-fated lawsuit against The Liberty Lobby) some interesting facts about the Bay of Pigs invasion were tossed out that leaves one scratching his or her head and wondering if 41 had anything to do with it. The operation was ostensibly to deliver small arms and ordnance to a (turns out to be fictional) 25,000 man rebel army that was in the Cuban hills waiting for help to depose Castro.

The US Navy supplied a couple of ships, but they were decommissioned, had their numbers scraped off, and were renamed the "Houston" and the "Barbara," (or the Spanish spelling of Barbara.) This is while 41 was living in Houston with his wife Barbara. Also, the CIA code name for the invasion was "Operation Zapata."

This while the name of 41's business was "Zapata Offshore." (Or something like that. 41 had business' using Zapata's name since his days as an oilman in Midland Texas.) The day after Kennedy's killing, a George Bush met with Army Intel. What went on in that meeting is a mystery, and the CIA unconvincingly claims that they had another guy working for them named George Bush, only he wasn't hired until 1964 and his expertise was meteorology so it's difficult to understand why they wanted to talk with him on that day. Then there's the fact that Oswald's CIA handler, a guy name Georges DeMorinshilt (sp?) had the name George (Poppy) Bush in his address book along with 41's Houston address and phone number.

Of course this is all coincidental, but consider: 41 was a failed two-term congressman who couldn't hold his seat, (in Houston Texas of all places) and yet was made by Nixon the ambassador to the UN, then Ford named him ambassador to China and the Director of the CIA. Wow! What a lucky guy.

So was he involved with the Kennedy assassination and photographed in Dealey Plaza? Don't know. I was 13 at the time, but in the intervening years, the politics in this country, especially relating to the Republican Party, have become shall we say, "Kalfkaesque."

Steven Hager , Author of "Killing Kennedy." Updated Dec 31, 2018 · Author has 1.2k answers and 1.4m answer views

There is a photo of someone who looks like him standing in front of the School Book Depository. Bush is one of the few people in America who can't remember where he was that day.

There is also a memo by J.Edgar Hoover referencing a "George Bush of the CIA" reporting on "misguided Cubans" in Dallas that day. The CIA had a safe house stuffed with Cuban agents in the Oak Cliff neighborhood, and Lee Harvey Oswald rented a room nearby shortly before the assassination took place.

Michael Tarnpoll , We came so goddamn close Answered Feb 2, 2017 · Author has 3.7k answers and 1.5m answer views

The George Bush connections to JFK's assassination

Astoundingly, Bush, the elder, claims that he does not remember where he was when Kennedy was assassinated. I do. I'll bet a dollar that you do (if old enough). Everyone above the age of fifty-five does except George H. W. Bush. He does however, remember that he was not at Dealey Plaza at the time.

It is interesting to note that photographs and videos exist showing a man who looks very much like Bush, at the site, at the time. It was not difficult to find them on line in the past. Now, they seem to have been expunged somehow, though a few blurry photos can still be found.

[Apr 27, 2019] What are the main differences between religion and ideology - Quora

Apr 27, 2019 |

a rQU d JV lm b cJr y s TObs M Mr a sqQCs n J a Ryv g Fb e G E aNWBB n k g wuli i Pu n LN e MI cLaG A GkdE D KPJJd S ZHmQO e ny l JACzT f gvhU S hoqBB e QsBBn r NqGDf v z i m c aXQ e zSU Fc P A u Txrqy s pVS Free Active Directory password expiration notification tool. Free tool to automatically remind users about password expiration via email, SMS, and push notifications. L wjx e Lpor a zsMV r WmU n nfoVQ eftBn M UtIUC o i r oi e Zej Y a sk t gkK TOD m mT a JbQx n rIFL a De g luOwd e GKdRL e x n xIIq g uKmA i I n IPuF e QvFM . xLEY c cMetZ o Gtv m qNSFZ You dismissed this ad. The feedback you provide will help us show you more relevant content in the future. Undo Answer Wiki 12 Answers Christopher Story

Christopher Story Lives in Hawai'i 25.3k answer views 788 this month Christopher Story Christopher Story Answered Sep 1 2015 · Author has 64 answers and 25.3k answer views One could say that an ideology is a religion if and only if it is theocratic, but I find Yuval Harari's understanding of religion less arbitrary and more compelling.

"Religion is any system of human norms and values that is founded on a belief in superhuman laws. Religion tells us that we must obey certain laws that were not invented by humans, and that humans cannot change at will. Some religions, such as Islam, Christianity and Hinduism, believe that these super-human laws were created by the gods. Other religions, such as Buddhism, Communism and Nazism, believe that these super-human laws are natural laws. Thus Buddhists believe in the natural laws of karma, Nazis argued that their ideology reflected the laws of natural selection, and Communists believe that they follow the natural laws of economics. No matter whether they believe in divine laws or in natural laws, all religions have exactly the same function: to give legitimacy to human norms and values, and to give stability to human institutions such as states and corporations. Without some kind of religion, it is simply impossible to maintain social order. During the modern era religions that believe in divine laws went into eclipse. But religions that believe in natural laws became ever more powerful. In the future, they are likely to become more powerful yet. Silicon Valley, for example, is today a hot-house of new techno-religions, that promise humankind paradise here on earth with the help of new technology."

[Apr 06, 2019] Would you fly Boeing 737 Max 8 ever again - Quora

Notable quotes:
"... No. Possibly Boeing & the FAA will solve the immediate issue, but they have destroyed Trust. ..."
"... It has emerged on the 737MAX that larger LEAP-1B engines were unsuited to the airframe and there is no way now to alter the airframe to balance the aircraft. ..."
"... Boeing failed to provide training or training material to pilots or even advise them the existence of MCAS. There was a complex two step process required of pilots in ET302 and JT610 crashes and their QRH handbook did not explain this: ..."
Apr 06, 2019 |

Would you fly Boeing 737 Max 8 ever again? Update Cancel

Simon Gunson , PPL aviation enthusiast Answered Mar 25, 2019 · Author has 141 answers and 981.7k answer views

No. Possibly Boeing & the FAA will solve the immediate issue, but they have destroyed Trust.

Other brands of aircraft like Airbus with AF447 established trust after their A330 aircraft plunged into the Atlantic in a mysterious accident.

With Airbus everyone saw transparency & integrity in how their accidents were investigated. How Boeing & FAA approached accident investigation destroyed public Trust.

By direct contrast in the mysterious disappearance of MH370, Boeing contributed nothing to the search effort and tried to blame the pilot or hijackers.

With the 737MAX in Lion Air and Ethiopian crashes Boeing again tried to blame pilots, poor training, poor maintenance and then when mechanical defect was proven, Boeing tried to downplay how serious the issue was and gave false assurances after Lion Air that the plane was still safe. ET302 proved otherwise.

It is no longer possible to trust the aircraft's certification. It is no longer possible to trust that safety was the overriding principle in design of the Boeing 737 MAX nor several other Boeing designs for that matter.

The Public have yet to realize that the Boeing 777 is an all electric design where in certain scenarios like electrical fire in the avionics bay, an MEC override vent opens allowing cabin air pressure to push out smoke. This silences the cabin depressurization alarms.

As an electrical failure worsens, in that scenario another system called ELMS turns off electrical power to the Air Cycle Machine which pumps pressurized air into the cabin. The result of ELMS cutting power means the override vent fails to close again and no new pressurized air maintains pressure in the cabin. Pilots get no warning.

An incident in 2007 is cited as AD 2007–07–05 by the FAA in which part but not all of this scenario played out in a B777 at altitude.

MH370 may have been the incident in which the full scenario played out, but of course Boeing is not keen for MH370 to be found and unlike Airbus which funded the search for AF447, Boeing contributed nothing to finding MH370.

It has emerged on the 737MAX that larger LEAP-1B engines were unsuited to the airframe and there is no way now to alter the airframe to balance the aircraft.

It also emerged that the choice to fit engines to this airframe have origins in a commercial decision to please Southwest Airlines and cancel the Boeing 757.

Boeing failed to provide training or training material to pilots or even advise them the existence of MCAS. There was a complex two step process required of pilots in ET302 and JT610 crashes and their QRH handbook did not explain this:

Boeing pilots had less than 40 SECONDS to over-ride automated system

The MAX is an aerodynamically unbalanced aircraft vulnerable to any sort of disruption, ranging from electrical failure, out of phase generator, faulty AOA sensor, faulty PCU failure alert, digital encoding error in the DFDAU.

Jason Eaton Former Service Manager Studied at University of Life Lives in Sydney, Australia 564k answer views 50.7k this month Answered Mar 24, 2019 ·

No I wouldn't. I'm not a pilot or an aerospace technician but I am a mechanical engineer, so I know a little bit about physics and stuff.

The 737–8 is carrying engines it was never designed for, that cause it to become inherently unstable. So unstable in fact, that it can't be controlled by humans and instead relies on computer aided control to maintain the correct attitude, particularly during ascent and descent.

The MCAS system is, effectively, a band aid to fix a problem brought about by poor design philosophy. Boeing should have designed a new airframe that complements the new engines, instead of ruining a perfectly good aircraft by bolting on power units it's not designed to carry, and then trying to solve the resulting instability with software. And if that isn't bad enough, the system relies on data from just the one sensor which if it doesn't agree with, it'll force the aircraft nose down regardless of the pilots' better judgement.

That might be ok for the Eurofighter Typhoon but it's definitely not ok for fare paying passengers on a commercial jetliner.

So, no. I won't be flying on a 737–8 until it's been redesigned to fly safely. You know, like a properly designed aeroplane should. 4.8k Views · View 36 Upvoters

[Mar 25, 2019] What do you think of Jared Kushner getting ready to unveil his economic plan for peace in the Middle East

Notable quotes:
"... He and the rest of his family are all crooks as are most politicians. Deals are made between thieves. Wealth serves as a mask. ..."
Mar 25, 2019 |

What do you think of Jared Kushner getting ready to unveil his economic plan for peace in the Middle East?

Christina Fabian , lives in San Francisco Answered Feb 8

He and the rest of his family are all crooks as are most politicians. Deals are made between thieves. Wealth serves as a mask.

I wonder how much he will make! Am so sick at the lack of morals among officials all over the world. Do good because it is the right thing to do not because of the accolades. Let thereby real judge!

[Mar 25, 2019] Is Jared Kushner, Trump's son-in-law, the man to bring peace to the Middle East- - Quora

Jan 21, 2017 |

John-Paul Wilson Answered Jan 21 2017

No! Of course not. Why does anyone believe this nonsense!

First off, I think by "bring peace to the Middle East" you must be referring to "solve the Israeli-Palestinian dilemma". There are numerous conflicts in the broader Middle East that make broader peace impossible.

Jared Kushner has no diplomatic experience. He doesn't seem to have any special knowledge about the conflict between Israel and the Palestinians. Being raised an Orthodox Jew, I think it will be impossible for the Palestinians to see him as a neutral party.

Here's something that people should have learned before the election: p... (more)

[Mar 20, 2019] How to I print to STDERR only if STDOUT is a different destination?

Mar 14, 2013 |

squiguy, Mar 14, 2013 at 19:06

I would like Perl to write to STDERR only if STDOUT is not the same. For example, if both STDOUT and STDERR would redirect output to the Terminal, then I don't want STDERR to be printed.

Consider the following example (


use strict;
use warnings;

print STDOUT "Hello standard output!\n";
print STDERR "Hello standard error\n" if ($someMagicalFlag);
exit 0

Now consider this (this is what I would like to achieve):

bash $
Hello standard output!

However, if I redirect out to a file, I'd like to get:

bash $ > /dev/null
Hello standard error

and similary the other way round:

bash $ 2> /dev/null
Hello standard output!

If I re-direct both out/err to the same file, then only stdout should be displayed:

bash $ > foo.txt 2>&1
bash $ cat foo.txt
Hello standard output!

So is there a way to evaluate / determine whether OUT and ERR and are pointing to the same "thing" (descriptor?)?

tchrist ,Mar 15, 2013 at 5:07

On Unix-style systems, you should be able to do:
my @stat_err = stat STDERR;
my @stat_out = stat STDOUT;

my $stderr_is_not_stdout = (($stat_err[0] != $stat_out[0]) ||
                            ($stat_err[1] != $stat_out[1]));

But that won't work on Windows, which doesn't have real inode numbers. It gives both false positives (thinks they're different when they aren't) and false negatives (thinks they're the same when they aren't).

Jim Stewart ,Mar 14, 2013 at 20:59

You can do that (almost) with -t:

will be true if it is a terminal, and likewise for STDOUT.

This still would not tell you what terminal, and if you redirect to the same file, you may stilll get both.

Hence, if

-t STDERR && ! (-t STDOUT) || -t STDOUT && !(-t STDERR)

or shorter

-t STDOUT ^ -t STDERR  # thanks to @mob

you know you're okay.

EDIT: Solutions for the case that both STDERR and STDOUT are regular files:

Tom Christianson suggested to stat and compare the dev and ino fields. This will work in UNIX, but, as @cjm pointed out, not in Windows.

If you can guarantee that no other program will write to the file, you could do the following both in Windows and UNIX:

  1. check the position the file descriptors for STDOUT and STDERR are at, if they are not equal, you redirected one of them with >> to a nonempty file.
  2. Otherwise, write 42 bytes to file descriptor 2
  3. Seek to the end of file descriptor 1. If it is 42 more than before, chances are high that both are redirected to the same file. If it is unchanged, files are different. If it is changed, but not by 42, someone else is writing there, all bets are off (but then, you're not in Windows, so the stat method will work).

[Mar 06, 2019] Who will win the 2020 United States presidential election - Quora

Mar 06, 2019 |

Emmanuel Gautier

Emmanuel Gautier I know some stuff, still trying to figure out all the rest. MSc Industrial Engineering & Management, École Centrale Paris Graduated 2017 Lives in France 2.4m answer views 11.9k this month Top Writer 2018 fr Active in French 6 Answers Emmanuel Gautier , Assiduous foreign observer of US Politics Updated Jun 1, 2018 · Author has 350 answers and 2.4m answer views

As much as I hate to say this, I think that as things stand right now, it's going to be Trump.

I'm sorry, what? You mean the most unpopular President in modern US political history? Donald 'both sides' Trump? Donald 'muslim ban' Trump? Donald 'covfefe' Trump? Donald 'golf at Mar-a-Lago every weekend while the country's trying to keep it together' Trump?

Yup, that Trump.

Now, this is the part when you pull out some pen and paper, and start proving to me, using political theorems, why a President with such low approval ratings eight months into his first term is pretty much doomed for reelection.

And that's when I point out that we've been over this kind of math, a million times, remember? That was the entire 2016 election in a nutshell. If I had a dollar every time I heard 'Trump has no path to 270 Electoral votes', 'Trump is the most unpopular candidate in an election ever', 'Trump is spending less money on grassroots operations than Clinton' last year, I could've formed a Super PAC. Election Day should've made it pretty clear, by now, that the usual political math does not apply to Trump.

Still, a 39% approval rating ? That's extremely low so early into his term.

Is it? He's at 40% on polls of likely or registered voters. There are 200 million registered voters in the US. So Trump has a base of 80 million registered voters . He won with less than 63 million in 2016. I'd say that's more than enough.

Of course, I'm not saying all 80 million will turn up in 2020. I'm just saying that right now, he has more voters who think he's doing a good job than he needs to be elected, even after what he's done so far in his term .

But isn't that the point? He's going to do more crazy stuff and end up losing support?

That's not how things have turned out so far. Remember when Trump said he could go on 5th Ave, shoot someone, and not lose a point in the polls? He was absolutely right.

Most politicians work hard on their respectability. Not only does it cost them a lot when they show the slightest crack, it ends up looking more like superiority. Trump made the insane wager that turning the problem upside down could work, and it did. It cost him hatred from half the country, but it earned him unconditional support from the other half.

His vulgarity - note that the word comes from Latin, ' vulgus ', which means 'the people' - puts the bar so low that nothing he does or says does any real damage to him.

And more importantly, his demeanor screams, ' I am like you. I don't speak using fancy words. I'm not PC - when I think something, I just say it, even if it's kinda sexist or racist. At night I just sit and watch Fox News while tweeting mean stuff.'

Trump replaced the 'superego' politician - one that Americans could aspire to be - with the 'id' politician - one that Americans want to be . People don't want to be first of their class, or do their homework. They don't want to be war heroes or presidents of the Harvard Law Review - at best, they aspire to . What people want , is to make money, fuck models, and give orders, all with minimal effort. And that's the fantasy that Trump sells them.

Of course, that's not true of every American, but it's true of enough of them. And now that they've stuck with him through so much, there's little that could turn them around, as long as he maintains this course.

So I think that Trump won't come down much lower than 30–32%. He could go up again during the next election cycle and win.

No, wait. Some of his base doesn't like the character, they just have faith in his nationalist agenda because he says he's going to bring jobs back. They're going to stop supporting him when it doesn't work.

I'm not sure. He's proven quite masterful at bypassing the mainstream media, talking directly to the people, destroying the concept of truth, and painting whoever's in his way as 'the establishment' and 'the elites', all convenient opponents.

There are many ways he could spin his term as a win, or at least blame his failings on others. Hell, he's already campaigning for 2020. I mean, literally . He's started holding rallies for 2020 as soon as he got into office.

I'm pretty sure that right now, Trump supporters believe that the failure to repeal Obamacare was entirely on the GOP establishment. And see how he's already boasting that the job market is doing well, even though there's no policy he's responsible for that could possibly have caused this? To be fair, all Presidents tend to take undue credit for jobs they have little to do with, but still.

Trump hates his job. He's a child who wanted a toy because it was shiny and realized it wasn't meant for him. Maybe he won't run, or sabotage his campaign?

That's right, Trump hates the job. But he's never happier than when he's running, and winning. That's why he can't stop talking about his 2016 win. That's why he's already holding those rallies. He's deeply insecure, and his political career is just a way for him to fill this enormous affection deficit that he has. He is going to run in 2020, and he'll want to win.

At the end of the day, Trump only won because he ran against Hillary Clinton. She was the weakest candidate ever.

No she wasn't. She was ultra-qualified, and had the temperament. She just happened, in an election that was marked by populism, to epitomize the career politician. Bernie scathed her, for Trump to finish her in the General Election. Put down the forks and torches, Bernie bros, I'm not saying it was his fault. He ran a campaign against her, and ultimately conceded and endorsed her. He did what was right all the way through, but the fact is that she came out of the primary quite damaged.

Objectively, the emails were nothing compared to everything Trump had (Russian ties, Trump U, Trump foundation, allegations of sexual harrassment and assault), but remember what I said about setting the bar low?

That's probably what's going to happen with his opponent next time: the Democrats are going to look for an unsinkable candidate, and the harder they'll try, the more Trump will exploit the smallest flaw to maximum effect , while being immune to scandal himself. Once again, he's going to be the champion of right-wingers who want him to 'stick it to those arrogant Dems'.

Democrats cannot defeat Trump just by taking the moral high ground. It simply doesn't work, and Trump understands this perfectly. He sets traps for them, and they keep falling into them, as Bannon says: ' The Democrats, the longer they talk about identity politics, I got 'em. I want them to talk about racism every day. If the left is focused on race and identity, and we go with economic nationalism, we can crush the Democrats.' [1]

Every time he says something awful, he knows that his supporters are either going to agree or not care, and that Democrats and the media will enter the usual cycle of hysterical outrage that accomplishes nothing.

So the Dems haven't proved to me that they're capable of inspiring trust and desire from voters. All they have to propose so far is 'not Trump'. That makes me pessimistic about their 2020 campaign. And that's not even counting the possibility of a third-party run that could split the left and center vote.

Maybe the undoing of Trump will come from the GOP itself. They don't support his platform of economic nationalism.

As long as Trump does the tax cuts for corporations and the wealthy, shrinks the federal government and keeps the NRA happy, the GOP won't ditch him. There will be some clashes between Ryan/McConnell and Trump, but it won't be enough to make them renounce the White House just to get rid of him.

Some 'mavericks' such as McCain (who may have been one of the three GOP Senators who killed the Obamacare repeal, but still votes with Trump 83% of the time [2] ) may openly criticize him or even endorse his opponent, but it won't be enough, just like it wasn't enough during the Access Hollywood turmoil. He played it by saying 'the shackles are off now', and it worked just fine. His base doesn't care about the GOP, they care about him.

Okay. But hey, one more thing. Russia. What if Trump's impeached?

We're gonna have to wait for the results of the investigation for that. Even if they are incriminating, the only real juror here is the public. As long as his public support doesn't fall apart, the GOP-controlled house will not impeach, and the GOP-controlled Senate will not convict.

So, is there just no way of defeating Trump in 2020?

It's not inevitable. All I'm saying is, right now his re-election looks increasingly likely. If Democrats changed their approach, they could find a candidate suited for fighting Trump. If Trump himself changed course, he could finally alienate his base. But it seems that right now, we're stuck in a Nash equilibrium: there are no direct incentives for anyone to behave differently than they are.

Trump is a parasite , that dwells in everyone's cerebrum, living off of attention, obsession even. He constantly lays larvas in our minds, in the form of brash statements or actions. They feed off his supporters' delight and his opponents' outrage, growing into more Trump memes that remain engraved in our brains. We may move on from him one day, but it's going to take waking up from this state of hypnosis he put us in, and start looking around for actual alternatives.


[1] What Steve Bannon gets right about Democrats -- and wrong about Trump

[2] Tracking Congress In The Age Of Trump

[Feb 21, 2019] perl - How to prompt for input and exit if the user entered an empty string - Stack Overflow

Feb 20, 2019 |

NewLearner ,Mar 12, 2012 at 3:22

I'm new to Perl and I'm writing a program where I want to force the user to enter a word. If the user enters an empty string then the program should exit.

This is what I have so far:

print "Enter a word to look up: ";

chomp ($usrword = <STDIN>);

DVK , Nov 19, 2015 at 19:11

You're almost there.
print "Enter a word to look up: ";
my $userword = <STDIN>; # I moved chomp to a new line to make it more readable
chomp $userword; # Get rid of newline character at the end
exit 0 if ($userword eq ""); # If empty string, exit.

Pondy , Jul 6 '16 at 22:11

File output is buffered by default. Since the prompt is so short, it is still sitting in the output buffer. You can disable buffering on STDOUT by adding this line of code before printing...
select((select(STDOUT), $|=1)[0]);

[Jan 29, 2019] New Perl function each is available in Perl 5.14 and later

Jan 29, 2019 |

called on a hash in list context, returns a 2-element list consisting of the key and value for the next element of a hash. In Perl 5.12 and later only, it will also return the index and value for the next element of an array so that you can iterate over it; older Perls consider this a syntax error. When called in scalar context, returns only the key (not the value) in a hash, or the index in an array.

Hash entries are returned in an apparently random order. The actual random order is specific to a given hash; the exact same series of operations on two hashes may result in a different order for each hash. Any insertion into the hash may change the order, as will any deletion, with the exception that the most recent key returned by each or keys may be deleted without changing the order. So long as a given hash is unmodified you may rely on keys , values and each to repeatedly return the same order as each other. See Algorithmic Complexity Attacks in perlsec for details on why hash order is randomized. Aside from the guarantees provided here the exact details of Perl's hash algorithm and the hash traversal order are subject to change in any release of Perl.

After each has returned all entries from the hash or array, the next call to each returns the empty list in list context and undef in scalar context; the next call following that one restarts iteration. Each hash or array has its own internal iterator, accessed by each , keys , and values . The iterator is implicitly reset when each has reached the end as just described; it can be explicitly reset by calling keys or values on the hash or array. If you add or delete a hash's elements while iterating over it, the effect on the iterator is unspecified; for example, entries may be skipped or duplicated--so don't do that. Exception: It is always safe to delete the item most recently returned by each , so the following code works properly:

  1. while ( my ( $key , $value ) = each %hash ) {
  2. print $key , "\n" ;
  3. delete $hash { $key } ; # This is safe
  4. }

Tied hashes may have a different ordering behaviour to perl's hash implementation.

This prints out your environment like the printenv(1) program, but in a different order:

  1. while ( my ( $key , $value ) = each %ENV ) {
  2. print "$key=$value\n" ;
  3. }

Starting with Perl 5.14, an experimental feature allowed each to take a scalar expression. This experiment has been deemed unsuccessful, and was removed as of Perl 5.24.

As of Perl 5.18 you can use a bare each in a while loop, which will set $_ on every iteration.

  1. while ( each %ENV ) {
  2. print "$_=$ENV{$_}\n" ;
  3. }

To avoid confusing would-be users of your code who are running earlier versions of Perl with mysterious syntax errors, put this sort of thing at the top of your file to signal that your code will work only on Perls of a recent vintage:

  1. use 5.012 ; # so keys/values/each work on arrays
  2. use 5.018 ; # so each assigns to $_ in a lone while test

See also keys , values , and sort .

[Jan 17, 2019] How do I launch the default web browser in Perl on any operating system

Jan 17, 2019 |

The second hit on "open url" at search.cpan brings up Browser::Open:

use Browser::Open qw( open_browser );

my $url = '';

If your OS isn't supported, send a patch or a bug report.


More at Stack Overflow More at Stack Overflow

[Jan 10, 2019] linux - How does cat EOF work in bash - Stack Overflow

Notable quotes:
"... The $sql variable now holds the new-line characters too. You can verify with echo -e "$sql" . ..."
"... The file now contains: ..."
"... The b.txt file contains bar and baz lines. The same output is printed to stdout . ..."
Jan 10, 2019 |

How does "cat << EOF" work in bash? Ask Question 454

hasen ,Mar 23, 2010 at 13:57

I needed to write a script to enter multi-line input to a program ( psql ).

After a bit of googling, I found the following syntax works:

cat << EOF | psql ---params

`pg_dump ----something`

update table .... statement ...;


This correctly constructs the multi-line string (from BEGIN; to END; , inclusive) and pipes it as an input to psql .

But I have no idea how/why it works, can some one please explain?

I'm referring mainly to cat << EOF , I know > outputs to a file, >> appends to a file, < reads input from file.

What does << exactly do?

And is there a man page for it?

Dennis Williamson ,Mar 23, 2010 at 18:28

That's probably a useless use of cat . Try psql ... << EOF ... See also "here strings". Williamson Mar 23 '10 at 18:28

hasen ,Mar 23, 2010 at 18:54

@Dennis: good point, and thanks for the link! – hasen Mar 23 '10 at 18:54

Alex ,Mar 23, 2015 at 23:31

I'm surprised it works with cat but not with echo. cat should expect a file name as stdin, not a char string. psql << EOF sounds logical, but not othewise. Works with cat but not with echo. Strange behaviour. Any clue about that? – Alex Mar 23 '15 at 23:31

Alex ,Mar 23, 2015 at 23:39

Answering to myself: cat without parameters executes and replicates to the output whatever send via input (stdin), hence using its output to fill the file via >. In fact a file name read as a parameter is not a stdin stream. – Alex Mar 23 '15 at 23:39

The-null-Pointer- ,Jan 1, 2018 at 18:03

@Alex echo just prints it's command line arguments while cat reads stding(when piped to it) or reads a file that corresponds to it's command line args – The-null-Pointer- Jan 1 '18 at 18:03

kennytm ,Mar 23, 2010 at 13:58

This is called heredoc format to provide a string into stdin. See for more details.

From man bash :

Here Documents

This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen.

All of the lines read up to that point are then used as the standard input for a command.

The format of here-documents is:


No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word . If any characters in word are quoted, the delimiter is the result of quote removal on word , and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \<newline> is ignored, and \ must be used to quote the characters \ , $ , and ` .

If the redirection operator is <<- , then all leading tab characters are stripped from input lines and the line containing delimiter . This allows here-documents within shell scripts to be indented in a natural fashion.

Xeoncross ,May 26, 2011 at 22:51

I was having the hardest time disabling variable/parameter expansion. All I needed to do was use "double-quotes" and that fixed it! Thanks for the info! – Xeoncross May 26 '11 at 22:51

trkoch ,Nov 10, 2015 at 17:23

Concerning <<- please note that only leading tab characters are stripped -- not soft tab characters. This is one of those rare case when you actually need the tab character. If the rest of your document uses soft tabs, make sure to show invisible characters and (e.g.) copy and paste a tab character. If you do it right, your syntax highlighting should correctly catch the ending delimiter. – trkoch Nov 10 '15 at 17:23

BrDaHa ,Jul 13, 2017 at 19:01

I don't see how this answer is more helpful than the ones below. It merely regurgitates information that can be found in other places (that have likely already been checked) – BrDaHa Jul 13 '17 at 19:01

Vojtech Vitek ,Feb 4, 2014 at 10:28

The cat <<EOF syntax is very useful when working with multi-line text in Bash, eg. when assigning multi-line string to a shell variable, file or a pipe. Examples of cat <<EOF syntax usage in Bash: 1. Assign multi-line string to a shell variable
$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'

The $sql variable now holds the new-line characters too. You can verify with echo -e "$sql" .

2. Pass multi-line string to a file in Bash
$ cat <<EOF >
echo \$PWD
echo $PWD

The file now contains:

echo $PWD
echo /home/user
3. Pass multi-line string to a pipe in Bash
$ cat <<EOF | grep 'b' | tee b.txt

The b.txt file contains bar and baz lines. The same output is printed to stdout .

edelans ,Aug 22, 2014 at 8:48

In your case, "EOF" is known as a "Here Tag". Basically <<Here tells the shell that you are going to enter a multiline string until the "tag" Here . You can name this tag as you want, it's often EOF or STOP .

Some rules about the Here tags:

  1. The tag can be any string, uppercase or lowercase, though most people use uppercase by convention.
  2. The tag will not be considered as a Here tag if there are other words in that line. In this case, it will merely be considered part of the string. The tag should be by itself on a separate line, to be considered a tag.
  3. The tag should have no leading or trailing spaces in that line to be considered a tag. Otherwise it will be considered as part of the string.


$ cat >> test <<HERE
> Hello world HERE <-- Not by itself on a separate line -> not considered end of string
> This is a test
>  HERE <-- Leading space, so not considered end of string
> and a new line
> HERE <-- Now we have the end of the string

oemb1905 ,Feb 22, 2017 at 7:17

this is the best actual answer ... you define both and clearly state the primary purpose of the use instead of related theory ... which is important but not necessary ... thanks - super helpful – oemb1905 Feb 22 '17 at 7:17

The-null-Pointer- ,Jan 1, 2018 at 18:05

@edelans you must add that when <<- is used leading tab will not prevent the tag from being recognized – The-null-Pointer- Jan 1 '18 at 18:05

JawSaw ,Oct 28, 2018 at 13:44

your answer clicked me on "you are going to enter a multiline string" – JawSaw Oct 28 '18 at 13:44

Ciro Santilli 新疆改造中心 六四事件 法轮功 ,Jun 9, 2015 at 9:41


kennytm quoted man bash , but most of that is also POSIX 7: :

The redirection operators "<<" and "<<-" both allow redirection of lines contained in a shell input file, known as a "here-document", to the input of a command.

The here-document shall be treated as a single word that begins after the next and continues until there is a line containing only the delimiter and a , with no characters in between. Then the next here-document starts, if there is one. The format is as follows:


where the optional n represents the file descriptor number. If the number is omitted, the here-document refers to standard input (file descriptor 0).

If any character in word is quoted, the delimiter shall be formed by performing quote removal on word, and the here-document lines shall not be expanded. Otherwise, the delimiter shall be the word itself.

If no characters in word are quoted, all lines of the here-document shall be expanded for parameter expansion, command substitution, and arithmetic expansion. In this case, the in the input behaves as the inside double-quotes (see Double-Quotes). However, the double-quote character ( '"' ) shall not be treated specially within a here-document, except when the double-quote appears within "$()", "``", or "${}".

If the redirection symbol is "<<-", all leading <tab> characters shall be stripped from input lines and the line containing the trailing delimiter. If more than one "<<" or "<<-" operator is specified on a line, the here-document associated with the first operator shall be supplied first by the application and shall be read first by the shell.

When a here-document is read from a terminal device and the shell is interactive, it shall write the contents of the variable PS2, processed as described in Shell Variables, to standard error before reading each line of input until the delimiter has been recognized.


Some examples not yet given.

Quotes prevent parameter expansion

Without quotes:

cat <<EOF



With quotes:

cat <<'EOF'

or (ugly but valid):

cat <<E"O"F


Hyphen removes leading tabs

Without hyphen:

cat <<EOF

where <tab> is a literal tab, and can be inserted with Ctrl + V <tab>



With hyphen:

cat <<-EOF



This exists of course so that you can indent your cat like the surrounding code, which is easier to read and maintain. E.g.:

if true; then
    cat <<-EOF

Unfortunately, this does not work for space characters: POSIX favored tab indentation here. Yikes.

David C. Rankin ,Aug 12, 2015 at 7:10

In your last example discussing <<- and <tab>a , it should be noted that the purpose was to allow normal indentation of code within the script while allowing heredoc text presented to the receiving process to begin in column 0. It is a not too commonly seen feature and a bit more context may prevent a good deal of head-scratching... – David C. Rankin Aug 12 '15 at 7:10

Ciro Santilli 新疆改造中心 六四事件 法轮功 ,Aug 12, 2015 at 8:22

@DavidC.Rankin updated to clarify that, thanks. – Ciro Santilli 新疆改造中心 六四事件 法轮功 Aug 12 '15 at 8:22

Jeanmichel Cote ,Sep 23, 2015 at 19:58

How should i escape expension if some of the content in between my EOF tags needs to be expanded and some don't? – Jeanmichel Cote Sep 23 '15 at 19:58

Jeanmichel Cote ,Sep 23, 2015 at 20:00

...just use the backslash in front of the $Jeanmichel Cote Sep 23 '15 at 20:00

Ciro Santilli 新疆改造中心 六四事件 法轮功 ,Sep 23, 2015 at 20:01

@JeanmichelCote I don't see a better option :-) With regular strings you can also consider mixing up quotes like "$a"'$b'"$c" , but there is no analogue here AFAIK. – Ciro Santilli 新疆改造中心 六四事件 法轮功 Sep 23 '15 at 20:01

Andreas Maier ,Feb 13, 2017 at 12:14

Using tee instead of cat

Not exactly as an answer to the original question, but I wanted to share this anyway: I had the need to create a config file in a directory that required root rights.

The following does not work for that case:

$ sudo cat <<EOF >/etc/somedir/foo.conf
# my config file

because the redirection is handled outside of the sudo context.

I ended up using this instead:

$ sudo tee <<EOF /etc/somedir/foo.conf >/dev/null
# my config file


add a comment ,Jun 6, 2018 at 0:15
This isn't necessarily an answer to the original question, but a sharing of some results from my own testing. This:
<<test >
echo \$PWD
echo $PWD

will produce the same file as:

cat <<test >
echo \$PWD
echo $PWD

So, I don't see the point of using the cat command.

> ,Dec 19, 2013 at 21:40

Worth noting that here docs work in bash loops too. This example shows how-to get the column list of table:
export postgres_db_name='my_db'
export table_name='my_table_name'

# start copy 
while read -r c; do test -z "$c" || echo $table_name.$c , ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
SELECT column_name
FROM information_schema.columns
AND table_schema = 'public'
AND table_name   =:'table_name'  ;
# stop copy , now paste straight into the bash shell ...

my_table_name.guid , ,
my_table_name.level ,
my_table_name.seq ,

or even without the new line

while read -r c; do test -z "$c" || echo $table_name.$c , | perl -ne 
's/\n//gm;print' ; done < <(cat << EOF | psql -t -q -d $postgres_db_name -v table_name="${table_name:-}"
 SELECT column_name
 FROM information_schema.columns
 WHERE 1=1
 AND table_schema = 'public'
 AND table_name   =:'table_name'  ;

 # output: daily_issues.guid , ,daily_issues.level ,daily_issues.seq ,daily_issues.prio ,daily_issues.weight ,daily_issues.status ,daily_issues.category , ,daily_issues.description ,daily_issues.type ,daily_issues.owner

[Dec 23, 2018] Founder of LiveJournal doesn't know the definition of "ennui"

Dec 23, 2018 |

That is all . (Ok, so I realize some of you will need some more information. Brad Fitzpatrick, with Danga and now SixApart, is pretty amazing when it comes to the software he's developed and released to the public . These range from utilities to provide secure backups on hardware you don't own ( brackup ) distributed job schedulers (The Schwartz) and others I've written about . Note for you Perl-bashers that he did much of this in Perl.)

[Dec 16, 2018] What are the benefits using Docker?

Dec 16, 2018 |

The main benefit of Docker is that it automatically solves the problems with versioning and cross-platform deployment, as the images can be easily recombined to form any version and can run in any environment where Docker is installed. "Run anywhere" meme...

James Lee , former Software Engineer at Google (2013-2016) Answered Jul 12 · Author has 106 answers and 258.1k answer views

There are many beneifits of Docker. Firstly, I would mention the beneifits of Docker and then let you know about the future of Docker. The content mentioned here is from my recent article on Docker.

Docker Beneifits:

Docker is an open-source project based on Linux containers. It uses the features based on the Linux Kernel. For example, namespaces and control groups create containers. But are containers new? No, Google has been using it for years! They have their own container technology. There are some other Linux container technologies like Solaris Zones, LXC, etc.

These container technologies are already there before Docker came into existence. Then why Docker? What difference did it make? Why is it on the rise? Ok, I will tell you why!

Number 1: Docker offers ease of use

Taking advantage of containers wasn't an easy task with earlier technologies. Docker has made it easy for everyone like developers, system admins, architects, and more. Test portable applications are easy to build. Anyone can package an application from their laptop. He/She can then run it unmodified on any public/private cloud or bare metal. The slogan is, "build once, run anywhere"!

Number 2: Docker offers speed

Being lightweight, the containers are fast. They also consume fewer resources. One can easily run a Docker container in seconds. On the other side, virtual machines usually take longer as they go through the whole process of booting up the complete virtual operating system, every time!

Number 3: The Docker Hub

Docker offers an ecosystem known as the Docker Hub. You can consider it as an app store for Docker images. It contains many public images created by the community. These images are ready to use. You can easily search the images as per your requirements.

Number 4: Docker gives modularity and scalability

It is possible to break down the application functionality into individual containers. Docker gives this freedom! It is easy to link containers together and create your application with Docker. One can easily scale and update components independently in the future.

The Future

A lot of people come and ask me that "Will Docker eat up virtual machines?" I don't think so! Docker is gaining a lot of momentum but this won't affect virtual machines. This reason is that virtual machines are better under certain circumstances as compared to Docker. For example, if there is a requirement of running multiple applications on multiple servers, then virtual machines is a better choice. On the contrary, if there is a requirement to run multiple copies of a single application, Docker is a better choice.

Docker containers could create a problem when it comes to security because containers share the same kernel. The barriers between containers are quite thin. But I do believe that security and management improve with experience and exposure. Docker certainly has a great future! I hope that this Docker tutorial has helped you understand the basics of Containers, VM's, and Dockers. But Docker in itself is an ocean. It isn't possible to study Docker in just one article. For an in-depth study of Docker, I recommend this Docker course.

Please feel free to Like/Subscribe/Comment on my YouTube Videos/Channel mentioned below :

David Polstra , Person at ReactiveOps (2016-present) Updated Oct 5, 2017 · Author has 65 answers and 53.7k answer views

I work at ReactiveOps where we specialize in DevOps-as-a-Service and Kubernetes Consulting. One of our engineers, EJ Etherington , recently addressed this in a blog post:

"Docker is both a daemon (a process running in the background) and a client command. It's like a virtual machine but it's different in important ways. First, there's less duplication. With each extra VM you run, you duplicate the virtualization of CPU and memory and quickly run out resources when running locally. Docker is great at setting up a local development environment because it easily adds the running process without duplicating the virtualized resource. Second, it's more modular. Docker makes it easy to run multiple versions or instances of the same program without configuration headaches and port collisions. Try that in a VM!

With Docker, developers can focus on writing code without worrying about the system on which their code will run. Applications become truly portable. You can repeatably run your application on any other machine running Docker with confidence. For operations staff, Docker is lightweight, easily allowing the running and management of applications with different requirements side by side in isolated containers. This flexibility can increase resource use per server and may reduce the number of systems needed because of its lower overhead, which in turn reduces cost.

Docker has made Linux containerization technology easy to use.

There are a dozen reasons to use Docker. I'll focus here on three: consistency, speed and isolation. By consistency , I mean that Docker provides a consistent environment for your application from development all the way through production – you run from the same starting point every time. By speed , I mean you can rapidly run a new process on a server. Because the image is preconfigured and installed with the process you want to run, it takes the challenge of running a process out of the equation. By isolation , I mean that by default each Docker container that's running is isolated from the network, the file system and other running processes.

A fourth reason is Docker's layered file system. Starting from a base image, every change you make to a container or image becomes a new layer in the file system. As a result, file system layers are cached, reducing the number of repetitive steps during the Docker build process AND reducing the time it takes to upload and download similar images. It also allows you to save the container state if, for example, you need troubleshoot why a container is failing. The file system layers are like Git, but at the file system level. Each Docker image is a particular combination of layers in the same way that each Git branch is a particular combination of commits."

I hope this was helpful. If you would like to learn more, you can read the entire post: Docker Is a Valuable DevOps Tool - One That's Worth Using

Bill William Bill William , M.C.A Software and Applications & Java, SRM University, Kattankulathur (2006) Answered Jan 5, 2018

Docker is the most popular file format for Linux-based container development and deployments. If you're using containers, you're most likely familiar with the container-specific toolset of Docker tools that enable you to create and deploy container images to a cloud-based container hosting environment.

This can work great for brand-new environments, but it can be a challenge to mix container tooling with the systems and tools you need to manage your traditional IT environments. And, if you're deploying your containers locally, you still need to manage the underlying infrastructure and environment.

Portability: let's suppose in the case of Linux you have your own customized Nginx container. You can run that Nginx container anywhere, no matter it's a cloud or data center on even your own laptop as long as you have a docker engine running Linux OS.

Rollback: you can just run your previous build image and all charges will automatically roll back.

Image Simplicity: Every image has a tree hierarchy and all the child images depend upon its parent image. For example, let's suppose there is a vulnerability in docker container, you can easily identify and patch that parent image and when you will rebuild child, variability will automatically remove from the child images also.

Container Registry: You can store all images at a central location, you can apply ACLs, you can do vulnerability scanning and image signing.

Runtime: No matter you want to run thousand of container you can start all within five seconds.

Isolation: We can run hundred of the process in one Os and all will be isolated to each other.

Docker Learning hub

[Dec 16, 2018] What are some disadvantages of using Docker - Quora

Dec 16, 2018 |

Ethen , Web Designer (2015-present) Answered Aug 30, 2018 · Author has 154 answers and 56.2k answer views

Docker is an open platform for every one of the developers bringing them a large number of open source venture including the arrangement open source Docker tools , and the management framework with in excess of 85,000 Dockerized applications. Docker is even today accepted to be something more than only an application stage. What's more, the compartment eco framework is proceeding to develop so quick that with such a large number of Docker devices being made accessible on the web, it starts to feel like an overwhelming undertaking when you are simply attempting to comprehend the accessible alternatives kept directly before you.

Disadvantages Of Docker

Containers don't run at bare-metal speeds.

The container ecosystem is fractured.

Persistent data storage is complicated.

Graphical applications don't work well.

Not all applications benefit from containers.

Advantages Of Docker

Swapnil Kulkarni , Engineering Lead at Persistent Systems (2018-present) Answered Nov 9, 2017 · Author has 58 answers and 24.9k answer views

From my personal experience, I think people just want to containerize everything without looking at how the architectural considerations change which basically ruins the technology.

e.g. How will someone benefit from creating FAT container images of a size of a VM when the basic advantage of docker is to ship lightweight images.

[Nov 17, 2018] Each Google performance review consists of a self-assessment, a set of peer reviews, and if you're applying for a promotion, reasons for why should be promoted to the next level

Nov 17, 2018 |

dmond Lau , former Engineer at Google (2006-2008) Answered Aug 26 2010 ·

Upvoted by Venkata Rajesh Mekala , Engineer at Google (2016-present) and Piyush Khemka , worked at Google

Google schedules their performance reviews twice a year -- one major one at the end of the year and a smaller one mid-year. This answer is based on my experience as a Google engineer, and the performance review process may differ slightly for other positions.

Each review consists of a self-assessment, a set of peer reviews, and if you're applying for a promotion, reasons for why should be promoted to the next level. Each review component is submitted via an online tool. Around performance review time, it's not uncommon to see many engineers taking a day or more just to write the reviews through the tool.

In the self-assessment, you summarize your major accomplishments and contributions since the last review. You're also asked to describe your strengths and areas for improvement; typically you'd frame them with respect to the job expectations described by your career ladder. For example, if you're a senior engineer, you might write about your strengths being the tech lead of your current project.

For peer reviews, employees are expected to choose around 3-8 peers (fellow engineers, product managers, or others that can comment on their work) to write their peer reviews. Oftentimes, managers will also assign additional individuals to write peer reviews for one of their reports, particularly newer or younger reports who may be less familiar with the process.

Peers comment on your projects and contributions, on your strengths, and on areas for improvement. The peer reviews serve three purposes:

An additional part of the peer review is indicating a list of engineers that are working below the level of the peer and a list of engineers that are working above the level of the peer. These factor into a total ordering of engineers within a team and are used to determine cutoffs for bonuses and promotions.

If you're applying for a promotion during a performance review cycle, you're given an additional opportunity to explain why you should be promoted. A key part to a strong application is explaining with specific details and examples how you're achieving and contributing based on the expectations of the next level in the job ladder.

[Nov 17, 2018] How did you handle a bad annual performance review?

Notable quotes:
"... Reviews should never (ever ever ever) be a surprise to either party (ever). If there is something in your review that was never brought up before, ask why your manager waited until now to bring it up instead of addressing it in the moment. ..."
"... Does the company as a whole actually give a crap about reviews? Are reviews used to make decisions on what departments to trim/cut and who is at the bottom? Are they used for financial decisions? (none of those uses is good by the way). ..."
Nov 17, 2018 |

Nanci Lamborn ,

Pretty naive, pro-management, view...

Reviews should never (ever ever ever) be a surprise to either party (ever). If there is something in your review that was never brought up before, ask why your manager waited until now to bring it up instead of addressing it in the moment. Have an uncomfortable discussion (yikes! YES. have an uncomfortable dialogue about it). Uncomfortable doesn't mean ugly or yelling or fist pounding. We don't like conflict, so we don't like asking people to explain why they chose to act in a certain way when we feel wronged. Get over that discomfort (respectfully). You have every right to ask why something was put in your review if it was a surprise.

Does the company as a whole actually give a crap about reviews? Are reviews used to make decisions on what departments to trim/cut and who is at the bottom? Are they used for financial decisions? (none of those uses is good by the way). Or do they sit in a file gathering dust? Has anyone ever actually pulled out someone's performance review from 2 years ago and taken action on it? If none of these things are true, while the bad review is still crappy, perhaps it's less of an issue overall.

... ... ...

If the comments are more behavioral or personal, this will be tougher. "Johnny rarely demonstrates a positive attitude" or "Johnny is difficult to work with" or "Johnny doesn't seem to be a team player" - for statements like this, you must ask for a detailed explanation. Not to defend yourself (at first anyway) but to understand. What did they mean exactly by the attitude or difficulty or team player? Ask for specific examples. "Please tell me when I demonstrated a bad attitude because I really want to understand how it comes across that way". BUT you MUST listen for the answer. If you are not willing to hear the answer and then work on it, then the entire exercise is a waste of time. You have a right to ask for these specifics. If your boss hesitates on giving examples, your response is then "How can I correct this issue if I don't know what the issue is?"

... ... ...

Lastly, if all of this fails and you're not given a chance to discuss the review and you truly believe it is wrong, ask for a meeting with HR to start that discussion. But be sure that you come across with the desire to come to an understanding by considering all the issues together professionally. And don't grumble and complain about it to colleagues unless everyone else is getting the same bad review treatment. This situation is between you and your manager and you should treat it as such or it can backfire.

[Nov 17, 2018] Should I argue a negative performance review?

If traditional performance reviews aren't officially dead, they certainly should be.
The arbitrary task of assigning some meaningless ranking number which is not connected to anything actionable is a painful waste of everyone's time. "You look like a 3.2 today, Joe looks like a 2.7, but Mary looks like a 4.1." In today's environment filled with knowledge workers, such rankings are silly at best and demotivating at worst. There is no proven correlation that such a system yields high-performance productivity results.
Nov 17, 2018 |

David Spearman , I operate by Crocker's Rules. Answered Feb 26, 2015 Yes if and only if you have documentation that some factual information in the review is false. Even then, you need to be careful to be as polite as possible. Anything else is unlikely to get you anywhere and may make your situation much worse.

[Oct 08, 2018] How hard is the Red Hat Certified System Administrator (RHCSA) Certification

It's not MCQ type exam where u will be given options to select right one ..Rather u have to configure everything practically. LDAP, autofs,user management,LVM . 20 questions to be configured in exam setup
The example included some tricky details, so you can fail the first time even if you are experience Linux sysadmin, but did not use particular daemons or functions. You should have working knowledge about LVM, IPtables and SELinux as well as some rounting. You should practice it over and over again until you are confident that you can take the exam.
Authorized Training Centre provide mock exam paper which are beneficial for students. For more details please visit -- Online RedHat Certification at Grras Training .
Oct 08, 2018 |

Jonathan Stade , RH Linux Admin (now Linux/Storage Architect) (2000-present) Answered Jan 10 2017

My answer is slightly dated, I did my RHCE on RHEL4 so it is now expired. At the time, the exam was offered as a combination RHCSA and RHCE exam, where if you received less than 80% you received RHCSA designation and over 80%, RHCE. I took the 4 day bootcamp before the exam as my prep. There were a range of people in the course, from yearlings like you to people with 10+ years of sysadmin work under their belt. Only 2 of us out of 7 got RHCE, although one of the people at the exam didn't take the course (he was disappointed, as he was quite experienced and thought he'd get the advanced cert), but everyone passed and got RHCSA at least.

The main difference between the RHCEs and the RHCSAs was speed. The test required a lot of work to be done fast and without error. I still supervise and work with hands-on admins, and I think if you've been working on it and do some studying you'll have no trouble with RHCSA.

They actually put us under NDA for the exam so I can't talk about what was that old one, but it's pretty well documented what the required skills are, so just make sure you're fresh and are ready to troubleshoot and build cleanly and quickly.

Michael Pagan , Senior Solutions Architect at Red Hat (2012-present) Answered Sep 25 2017 · Upvoted by Alexander Todorov , worked at Red Hat

If you have any kind of background in Linux, it is not too difficult. There are a number of books withexample test scenarios, and if you go through those and practice them for a few evenings you will be fine.

The RHCSA questions are not terribly hard, and the exam is "performance-based," meaning you are given tasks to accomplish on an actual RHEL system, and you are graded by the end state of the system. If you accomplish the task, you get credit for that question. It is not a multiple-choice exam.

Gautam K , Red Hat Certified Engineer (RHCE) Updated Jun 22 2016 · Author has 281 answers and 902.3k answer views

RHCSA is not so hard, but You need to know the Exam Environment.

According to my experience, You will get 20-22 questions along of these:

You need to prepare:-

File Systems
User Administration
Archiving (Compression)
Finding & Processing
Job Scheduling
ACL Permission

Suraj Lulla , Certified RHCSA Red Hat 7, Co-founder Answered Aug 10, 2016 · Author has 65 answers and 94.3k answer views

RHCSA certification is not at all tough if you're good at handling linux. If you're good at the following, you're ready to rock.

  1. Resetting password of the virtual machine's user.
  2. Changing SELinux's status (enforcing).
  3. Creating a new kernel.
  4. Creation of cron jobs.
  5. Accessing directories, adding users + groups and giving them permissions via Terminal.
  6. NTP - your timezone.
  7. Using yum install and vi editor.
  8. Creating different types of compressed archives via terminal.
  9. Time consuming ones:
    1. LDAP
    2. Logical volumes

Once you're fast enough on the above mentioned simple stuff, you can surely give it a try.

[Oct 08, 2018] I have been meeting more and more Americans abroad who permanently left the US and told me it was the best thing they did, or that they never want to go back. Why is that so? Is it due to POTUS?

Oct 08, 2018 |

Jason Perno , Cyber Security Specialist and Forensic Analyst at NNIT A/S (2017-present)

Answered 17h ago

I left the United States because I married a Danish woman. We tried living in New York, but we struggled a lot. She was not used to being without the normal help she gets from the Danish system. We... (more) Loading

I left the United States because I married a Danish woman. We tried living in New York, but we struggled a lot. She was not used to being without the normal help she gets from the Danish system. We made the move a few years ago, and right away our lives started to improve dramatically.

Now I am working in IT, making a great money, with private health insurance. Yes I pay high taxes, but the benefits outweigh the costs. The other things is that the Danish people trust in the government and trust in each other. There is no need for #metoo or blacklivesmatter, because the people already treat each other with respect.

While I now enjoy an easier life in Denmark, I sit back and watch the country I fiercely love continue to fall to pieces because of divisive rhetoric and the corporate greed buying out our government.

Trump is just a symptom of the problem. If people could live in the US as they did 50 years ago, when a single person could take care of their entire family, and an education didn't cost so much, there would be no need for this revolution. But wages have been stagnant since the 70's and the wealth has shifted upwards from the middle class to the top .001 percent. This has been decades in the making. You can't blame Obama or Trump for this.

Meanwhile, I sit in Denmark watching conservatives blame liberalism, immigrants, poor people, and socialism, while Democrats blame rednecks, crony capitalism, and republican greed. Everything is now "fake news". Whether it be CNN or FOX, no one knows who to trust anymore. Everything has become a conspiracy. Our own president doesn't even trust his own FBI or CIA. And he pushes conspiracy theories to mobilize his base. I am glad to be away from all that, and living in a much healthier environment, where people aren't constantly attacking one another.

Maybe if the US can get it's healthcare and education systems together, I would consider moving back one day. But it would also be nice if people learned to trust one another, and trust in the system again. Until then, I prefer to be around emotionally intelligent people, who are objective, and don't fall for every piece of propaganda. Not much of that happening in America these days. The left has gone off the deep end playing identity politics and focusing way too much on implementing government mandated Social Justice. Meanwhile the conservatives are using any propaganda and lying necessary to push their corporate backed agenda. This is all at the cost of our environment, our free trade agreements, peace treaties, and our European allies. Despite how much I love my country, I breaks my heart to say, I don't see myself returning any time soon I'm afraid.

[Sep 21, 2018] Preferred editor or IDE for development work - Red Hat Learning Community

Pycharm supports Perl, althouth this is not advertized.
Sep 21, 2018 |

Re: Preferred editor or IDE for development work

I don't do a lot of development work, but while learning Python I've found pycharm to be a robust and helpful IDE. Other than that, I'm old school like Proksch and use vi.



Re: Preferred editor or IDE for development work

Yes, I'm the same as @Proksch. For my development environment at Red Hat, vim is easiest to use as I'm using Linux to pop in and out of files. Otherwise, I've had a lot of great experiences with Visual Studio.

[Sep 10, 2018] Parsing HTML with Perl by A. Sinan Unur

Notable quotes:
"... Editor's note: If you're looking for tips on how to write more efficient, robust, and maintainable Perl code, you'll want to check out Damien Conway's " Modern Perl Best Practices " video. ..."
Feb 06, 2014 |

Efficiently manipulate documents on the Web|

The need to extract interesting bits of an HTML document comes up often enough that by now we have all seen many ways of doing it wrong and some ways of doing it right for some values of "right".

One might think that one of the most fascinating answers on Stackoverflow has put an end to the desire to parse HTML using regular expressions, but time and again such a desire proves too tempting .

Let's say you want to check all the links on a page to identify stale ones, using regular expressions:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 use strict ; use warnings ; use feature 'say' ; my $ re = qr /< as + href = [ "']([^"']+)["' ] / i ; my $ html = do { local $ / ; < DATA > }; # slurp _DATA_ section my @ links = ($ html =~ m { $ re } gx ); say for @ links ; __DATA__ < html >< body > < p >< a href = "" > An Example </ a ></ p > <!-- < a href = "" > An Example </ a > --> </ body ></ html >

In this self-contained example, I put a small document in the __DATA__ section. This example corresponds to a situation where the maintainer of the page commented out a previously broken link, and replaced it with the correct link.

When run, this script produces the output:

1 2 3 $ . / href . pl http : // http : //

It is surprisingly easy to fix using HTML::TokeParser::Simple . Just replace the body of the script above with:

1 2 3 4 5 6 7 8 use HTML :: TokeParser :: Simple ; my $ parser = HTML :: TokeParser :: Simple -> new ( handle => * DATA ); while ( my $ anchor = $ parser -> get_tag ( 'a' )) { next unless defined ( my $ href = $ anchor -> get_attr ( 'href' )); say $ href ; }

When run, this script correctly prints:

1 2 $ . / href http : //

And, it looks like we made it much more readable in the process!

Of course, interesting HTML parsing jobs involve more than just extracting links. While even that task can be made ever-increasingly complex for the regular expression jockey by, say, adding some interesting attributes between the a and the href , code using HTML::TokeParser::Simple would not be affected.

Another specialized HTML parsing module is HTML::TableExtract . In most cases, it makes going through tables on a page a breeze. For example, the State Actions to Address Health Insurance Exchanges contains State Table 2: Snapshot of State Actions and Figures. The contents of this page may change with new developments, so here is a screenshot of the first few lines of the table:


Parsing this table using HTML::TableExtract is straightforward:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 use HTML :: TableExtract ; use Text :: Table ; my $ doc = 'state-actions-to-implement-the-health-benefit.aspx' ; my $ headers = [ 'State' , 'Selected a Plan' ]; my $ table_extract = HTML :: TableExtract -> new ( headers => $ headers ); my $ table_output = Text :: Table -> new (@$ headers ); $ table_extract -> parse_file ($ doc ); my ($ table ) = $ table_extract -> tables ; for my $ row ($ table -> rows ) { clean_up_spaces ($ row ); # not shown for brevity $ table_output -> load ($ row ); } print $ table_output ;

Running this script yields:

1 2 3 4 5 6 7 $ . / te State Selected a Plan Alabama 624 Alaska 53 Arizona 739 Arkansas 250

Note that I did not even have to look at the underlying HTML code at all for this code to work. If it hadn't, I would have had to delve into that mess to find the specific problem, but, in this case, as in many others in my experience, HTML::TableExtract gave me just what I wanted. So long as the substrings I picked continue to match the content, my script will extract the desired columns even if some of the underlying HTML changes.

Both HTML::TokeParser::Simple (based on HTML::PullParser ) and HTML::TableExtract (which subclasses HTML::Parser parse a stream rather than loading the entire document to memory and building a tree. This made them performant enough for whatever I was able to throw at them in the past.

With HTML::TokeParser::Simple , it is also easy to stop processing a file once you have extracted what you need. That helps when you are dealing with thousands of documents, each several megabytes in size where the interesting content is located towards the beginning. With HTML::TablExtract , performance can be improved by switching to less robust table identifiers such as depths and counts. However, in certain pathological conditions I seem to run into a lot, you may need to play with regexes to first extract the exact region of the HTML source that contains the content of interest.

In one case I had to process large sets of HTML files I had to process where each file was about 8 Mb. The interesting table occurred about 3/4 through the HTML source, and it was clearly separated from the rest of the page by <!-- interesting content here --> style comments. In this particular case, slurping each file, extracting the interesting bit, and passing the content to HTML::TableExtract helped. Throw a little Parallel::ForkManager into the mix, and a task that used to take a few hours went down to less than half an hour.

Sometimes, you just need to be able to extract the contents of the third span within the sixth paragraph of the first content div on the right. Especially if you need to extract multiple pieces of information depending on various parts of the document, creating a tree structure will make that task simpler. It may have a huge performance cost, however, depending on the size of the document. Building trees out of the smallest possible HTML fragments can help here.

Once you have the tree structure, you can address each element or sets of elements. XPath is a way of addressing those elements. HTML::TreeBuilder builds a tree representation of HTML documents. HTML::TreeBuilder::XPath adds the ability to locate nodes in that representation using XPath expressions. So, if I wanted to get the table of contents of the same document, I could have used something along the lines of:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 use HTML :: TreeBuilder :: XPath ; use Text :: Table ; my $ doc = 'state-actions-to-implement-the-health-benefit.aspx' ; my $ tree = HTML :: TreeBuilder :: XPath -> new ; my $ toc_table = Text :: Table -> new ( 'Entry' , 'Link' ); $ tree -> parse_file ($ doc ); my @ toc = $ tree -> findnodes ( '//table[@id="bookmark"]/tbody/*/*/*//li/a' ); for my $ el ( @ toc ) { $ toc_table -> add ( $ el -> as_trimmed_text , $ el -> attr ( 'href' ), ); } print $ toc_table ;

Mojo::DOM is an excellent module that uses JQuery style selectors to address individual elements. It is extremely helpful when dealing with documents were HTML elements, classes, and ids were used in intelligent ways.

XML::Twig will also work for some HTML documents, but in general, using an XML parser to parse HTML documents found in the wild is perilious. On the other hand, if you do have well-formed documents, or HTML::Tidy can make them nice, XML::Twig is a joy to use. Unfortunately, it is depressingly too common to find documents pretending to be HTML, using a mish-mash of XML and HTML styles, and doing all sorts of things which browsers can accommodate, but XML parsers cannot.

And, if your purpose is just to clean some wild HTML document, use HTML::Tidy . It gives you an interface to the command line utility tidyp . For really convoluted HTML, it sometimes pays to pass through tidyp first before feeding it into one of the higher level modules.

Thanks to others who have built on HTML::Parser , I have never had to write a line of event handler code myself for real work. It is not that they are difficult to write. I do recommend you study the examples bundled with the distribution to see how the underlying machinery works. It is just that the modules others have built on top of and beyond HTML::Parser make life so much easier that I never had to worry much about going to the lowest possible level.

That's a good thing.

Editor's note: If you're looking for tips on how to write more efficient, robust, and maintainable Perl code, you'll want to check out Damien Conway's " Modern Perl Best Practices " video.

[May 28, 2018] Handling Binary Files in Perl

May 28, 2018 |

For some reason, there exists a common misconception that there is no cross-platform, built-in way in Perl to handle binary files. The copy_file code snippet below illustrates that Perl handles such tasks quite well. The trick is to use "binmode" on both the input and output files after opening them. "Binmode" switches files to binary mode, which for the input file means it won't stop reading at the first "end of text file" character (^Z in win/dos); for the output file binmode means it won't translate '\n' (LF) into '\r\n' (CRLF) when printing. In this way the files get copied byte for byte.

sub copy_file {
  my ($srcfile, $destfile) = @_;
  my $buffer;

  open INF, $srcfile
    or die "\nCan't open $srcfile for reading: $!\n";
  open OUTF, ">$destfile"
    or die "\nCan't open $destfile for writing: $!\n";

  binmode INF;
  binmode OUTF;

  while (
    read (INF, $buffer, 65536)  # read in (up to) 64k chunks, write
    and print OUTF $buffer      # exit if read or write fails
  ) {};
  die "Problem copying: $!\n" if $!;

  close OUTF
    or die "Can't close $destfile: $!\n";
  close INF
    or die "Can't close $srcfile: $!\n";
Atanas Banov

[May 09, 2018] reading binary files with Perl

May 09, 2018 |

jpk1292000 has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I'm new to the board and I've been struggling with this problem for some time now. Hope someone can give me some suggestions... I am trying to read a binary file with the following format: The 4-byte integer and (4 byte float) are in the native format of the machine.

*** First record (4 byte integer) - byte size of record (4*N) (f77 header) (4 byte float) .. 
      value 1 (4 byte float) .. value 2 ... (4 byte float) .. value N N = number of grid points in the field (4 byte 
      integer) .. byte size of record (4*N) (f77 trailer) **** Second record (4 byte integer) - byte size of record (4*N) 
      (f77 header) (4 byte float) .. value 1 (4 byte float) .. value 2 ... (4 byte float) .. value N N = number of grid 
      points in the field (4 byte integer) .. byte size of record (4*N) (f77 trailer)


    The data is meteorological data (temperature in degrees K) on a 614 x 428 grid. I tried coding up a reader for this, 
    but am getting nonsensical results. Here is the code: 

my $out_file = "/dicast2-papp/DICAST/smg_data/" . $gfn . ".bin"; #path

 to binary file my $template = "if262792i"; #binary layout (integer 262792 floats 

teger) as described in the format documentation 
      above (not sure if th

is is correct) my $record_length 
      = 4; #not sure what record_length is supposed to rep

      (number of values in 1st record, or should it be length of var

      [4 bytes]) my (@fields,$record); open (FH, $out_files ) || die "couldn't open $out_files\n"; until (eof(FH)) { my $val_of_read 
      = read (FH, $record, $record_length) == $record_

      or die "short read\n"; @fields = unpack ($template, $record); print "field = $fields[0]\n"; }


    The results I get when I print out the first field are non-sensical (negative numbers, etc). I think the issue is 
    that I'm not properly setting up my template and record length. Also, how do I find out what is "the native format of 
    the machine"?

Replies are listed 'Best First'.

davorg (Chancellor) on Nov 16, 2006 at 15:53 UTC

Re: reading binary files with Perl

You can find out more about how "read" works by reading its documentation .

From there, you'll find out that the third parameter (your $record_length) is the number of bytes to read from the filehandle[1]. As your template is set up to handle all of the data for one record in one go, you'll need to read one record's worth of data. That's 4 * (1 + 262792 + 1) bytes of data. Currently you're reading four bytes, and the template is looking for a lot more.

The documention for unpack says this:

If there are more pack codes or if the repeat count of a field or a group is larger than what the remainder of the input string allows, the result is not well defined: in some cases, the repeat count is decreased, or unpack() will produce null strings or zeroes, or terminate with an error. If the input string is longer than one described by the TEMPLATE, the rest is ignored.

[1] Actually, the number of _characters_ but let's assume single byte characters for the time being.

< >

"The first rule of Perl club is you do not talk about Perl club."
-- Chip Salzenberg

ikegami (Pope) on Nov 16, 2006 at 16:04 UTC

Re: reading binary files with Perl

Depending on your OS, another problem is the lack of binmode . Add binmode(FH) after the open so that Perl doesn't mess with the data. Not all OSes require binmode , but it's safe to use binmode on all OSes.

Oh and I'd use l instead of i . i is not guaranteed to be 4 bytes.

jpk1292000 (Initiate) on Nov 16, 2006 at 19:09 UTC

Re^2: reading binary files with Perl

by jpk1292000 (Initiate) on Nov 16, 2006 at 19:09 UTC

BrowserUk (Pope) on Nov 16, 2006 at 16:13 UTC

Re: reading binary files with Perl

Something like this should do it. See the docs and/or ask for anything you do not understand.

#! perl -slw use strict; my @grid; open my $fh, '<:raw', 'the file' or die $!; while( 1 
            ) { my( $recSize, $dummy, $record ); sysread( $fh, $recSize, 4 ) or last; $recSize = unpack 'N', $recSize; 
            ##(*) sysread( $fh, $record, $recSize ) == $recSize or die "truncated record"; sysread( $fh, $dummy, 4 ) == 4 
            and unpack( 'N', $dummy ) == $recSize ##(*) or die "missing or invalid trailer"; ## (*) You may need V 
            depending upon which platform your file was

            on push @grid, [ unpack 'N*', $record ]; } close $fh; ## @grid should now contain your data ## Addressable in 
            the usual $grid[ X ][ Y ] manner. ## Though it might be $array[ Y ][ X ] ## I forget which order FORTRAN 
            writes arrays in?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error. Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal? "Science is about questioning the status quo. Questioning authority". In the absence of evidence, opinion is indistinguishable from prejudice.

ikegami (Pope) on Nov 16, 2006 at 16:29 UTC

Re^2: reading binary files with Perl

by ikegami (Pope) on Nov 16, 2006 at 16:29 UTC

BrowserUk (Pope) on Nov 16, 2006 at 19:17 UTC

Re^3: reading binary files with Perl

ikegami (Pope) on Nov 16, 2006 at 21:12 UTC

Re^4: reading binary files with Perl

jmcnamara (Monsignor) on Nov 16, 2006 at 16:33 UTC

Re: reading binary files with Perl

Try something like the following:

#!/usr/bin/perl -w use strict; open FILE, 'file.bin' or die "Couldn't open file: $!\n"; 
            binmode FILE; my $record = 1; my $buffer = ''; while ( read( FILE, $buffer, 4 ) ) { my $record_length = 
            unpack 'N', $buffer; my $num_fields = $record_length / 4; printf "Record %d. Number of fields = %d\n", 
            $record, $num_fie

lds; for (1 .. $num_fields ) { 
            read( FILE, $buffer, 4 ); my $temperature = unpack 'f', $buffer; # Or if the above gives the wrong result try 
            this: #my $temperature = unpack 'f', reverse $buffer; print "\t", $temperature, "\n"; } # Read but ignore 
            record trailer. read( FILE, $buffer, 4 ); print "\n"; $record++; } __END__


          If the number of fields is wrong subtitute
unpack 'V'
unpack 'N'
. If the float is wrong 
          try the
ed value that is commented out. 

Update: Added read for trailer.


[May 09, 2018] How to read binary file in Perl - Stack Overflow

Notable quotes:
"... BTW: I don't think it's a good idea to read tons of binary files into memory at once. You can search them 1 by 1... ..."
May 09, 2018 |

2 down vote favorite 1

Grace ,Jan 19, 2012 at 2:08

I'm having an issue with writing a Perl script to read a binary file.

My code is as the following whereby the $file are files in binary format. I tried to search through the web and apply in my code, tried to print it out, but it seems it doesn't work well.

Currently it only prints the '&&&&&&&&&&&" and ""ppppppppppp", but what I really want is it can print out each of the $line , so that I can do some other post processing later. Also, I'm not quite sure what the $data is as I see it is part of the code from sample in article, stating suppose to be a scalar. I need somebody who can pin point me where the error goes wrong in my code. Below is what I did.

my $tmp = "$basedir/$key";
opendir (TEMP1, "$tmp");
my @dirs = readdir(TEMP1);

foreach my $dirs (@dirs) {
    next if ($dirs eq "." || $dirs eq "..");
    print "---->$dirs\n";
    my $d = "$basedir/$key/$dirs";
    if (-d "$d") {
        opendir (TEMP2, $d) || die $!;
        my @files = readdir (TEMP2); # This should read binary files
        closedir (TEMP2);

        #my $buffer = "";
        #opendir (FILE, $d) || die $!;
        #binmode (FILE);
        #my @files =  readdir (FILE, $buffer, 169108570);
        #closedir (FILE);

        foreach my $file (@files) {
            next if ($file eq "." || $file eq "..");
            my $f = "$d/$file";
            print "==>$file\n";
            open FILE, $file || die $!;
            binmode FILE;
            foreach ($line = read (FILE, $data, 169108570)) {
                print "&&&&&&&&&&&$line\n";
                print "ppppppppppp$data\n";
            close FILE;

I have altered my code so that it goes like as below. Now I can read the $data. Thanks J-16 SDiZ for pointing out that. I'm trying to push the info I got from the binary file to an array called "@array", thinkking to grep data from the array for string whichever match "p04" but fail. Can someone point out where is the error?

my $tmp = "$basedir/$key";
opendir (TEMP1, "$tmp");
my @dirs = readdir (TEMP1);
closedir (TEMP1);

foreach my $dirs (@dirs) {
    next if ($dirs eq "." || $dirs eq "..");
    print "---->$dirs\n";
    my $d = "$basedir/$key/$dirs";
    if (-d "$d") {
        opendir (TEMP2, $d) || die $!;
        my @files = readdir (TEMP2); #This should read binary files
        closedir (TEMP2);

        foreach my $file (@files) {
            next if ($file eq "." || $file eq "..");
            my $f = "$d/$file";
            print "==>$file\n";
            open FILE, $file || die $!;
            binmode FILE;
            foreach ($line = read (FILE, $data, 169108570)) {
                print "&&&&&&&&&&&$line\n";
                print "ppppppppppp$data\n";
                push @array, $data;
            close FILE;

foreach $item (@array) {
    #print "==>$item<==\n"; # It prints out content of binary file without the ==> and <== if I uncomment this.. weird!
    if ($item =~ /p04(.*)/) {
        print "=>$item<===============\n"; # It prints "=><===============" according to the number of binary file I have.  This is wrong that I aspect it to print the content of each binary file instead :(
        next if ($item !~ /^w+/);
        open (LOG, ">log") or die $!;
        #print LOG $item;
        close LOG;

Again, I changed my code as following, but it still doesn't work as it do not able to grep the "p04" correctly by checking on the "log" file. It did grep the whole file including binary like this "@^@^@^@^G^D^@^@^@^^@p04bbhi06^@^^@^@^@^@^@^@^@^@hh^R^@^@^@^^@^@^@p04lohhj09^@^@^@^^@@" . What I'm aspecting is it do grep the anything with p04 only such as grepping p04bbhi06 and p04lohhj09. Here is how my code goes:-

foreach my $file (@files) {
    next if ($file eq "." || $file eq "..");
    my $f = "$d/$file";
    print "==>$file\n";
    open FILE, $f || die $!;
    binmode FILE;
    my @lines = <FILE>;
    close FILE;
    foreach $cell (@lines) {
        if ($cell =~ /b12/) {
            push @array, $cell;

#my @matches = grep /p04/, @lines;
#foreach $item (@matches) {
foreach $item (@array) {
    #print "-->$item<--";
    open (LOG, ">log") or die $!;
    print LOG $item;
    close LOG;

Brad Gilbert ,Jan 19, 2012 at 15:53

use autodie – Brad Gilbert Jan 19 '12 at 15:53

reinierpost ,Jan 30, 2012 at 13:00

There is no such thing as 'binary format'. Please be more precise. What format are the files in? What characteristics do they have that cause you to call them 'in binary format'? – reinierpost Jan 30 '12 at 13:00

Grace ,Jan 31, 2012 at 6:56

It is in .gds format. This file is able to read in Unix with strings command. It was reaable in my Perl script but I am not able to grep the data I wanted (p04* here in my code) . – Grace Jan 31 '12 at 6:56

mivk ,Nov 19, 2013 at 13:16

As already suggested, use File::Find or something to get your list of files. For the rest, what do you really want? Output the whole file content if you found a match? Or just the parts that match? And what do you want to match? p04(.*) matches anything from "p04" up to the next newline. You then have that "anything" in $1 . Leave out all the clumsy directory stuff and concentrate first on what you want out of a single file. How big are the files? You are only reading the first 170MB. And you keep overwriting the "log" file, so it only contains the last item from the last file. – mivk Nov 19 '13 at 13:16

jm666 ,May 12, 2015 at 6:44

@reinierpost the OP under the "binary file" probably mean the opposite of the text files - e.g. same thing as is in the perldoc's -X documentation see the -B explanation. (cite: -B File is a "binary" file (opposite of -T).) – jm666 May 12 '15 at 6:44

J-16 SDiZ ,Jan 19, 2012 at 2:19

$line = read (FILE, $data, 169108570);

The data is in $data ; and $line is the number of bytes read.

       my $f = "$d/$file" ;
       print "==>$file\n" ;
       open FILE, $file || die $! ;

I guess the full path is in $f , but you are opening $file . (In my testing -- even $f is not the full path, but I guess you may have some other glue code...)

If you just want to walk all the files in a directory, try File::DirWalk or File::Find .

Grace ,Jan 19, 2012 at 2:34

Hi J-16 SDiZ, thanks for the reply. each of the $file is in binary format, and what I want to do is to read eaxh of the file to grep some information in readable format and dump into another file (which I consider here as post processing). I want to perform something like "strings <filename> | grep <text synctax>" as in Unix. whereby the <filename> is the $file here in my code. My problem here is cannot read the binary file so that I can proceed with other stuff. Thanks. – Grace Jan 19 '12 at 2:34

Dimanoid ,Jan 20, 2012 at 8:51

I am not sure if I understood you right.

If you need to read a binary file, you can do the same as for a text file:

open F, "/bin/bash";
my $file = do { local $/; <F> };
close F;

Under Windows you may need to add binmode F; under *nix it works without it.

If you need to find which lines in an array contains some word, you can use grep function:

my @matches = grep /something/, @array_to_grep;

You will get all matched lines in the new array @matches .

BTW: I don't think it's a good idea to read tons of binary files into memory at once. You can search them 1 by 1...

If you need to find where the match occurs you can use another standard function, index :

my $offset = index('myword', $file);

Grace ,Jan 30, 2012 at 4:30

Hi Dinanoid, thanks for your answer, I tried it but it didn't work well for me. I tried to edit my code as above (my own code, and it didn't work). Also, tried code as below as you suggested, it didn't work for me either. Can you point out where I did wrong? Thanks. – Grace Jan 30 '12 at 4:30

Peter Mortensen ,May 1, 2016 at 8:31

What will $file be assigned to? An array of characters? A string? Something else? – Peter Mortensen May 1 '16 at 8:31

> ,

I'm not sure I'll be able to answer the OP question exactly, but here are some notes that may be related. (edit: this is the same approach as answer by @Dimanoid, but with more detail)

Say you have a file, which is a mix of ASCII data, and binary. Here is an example in a bash terminal:

$ echo -e "aa aa\x00\x0abb bb" | tee tester.txt
aa aa
bb bb
$ du -b tester.txt 
13  tester.txt
$ hexdump -C tester.txt 
00000000  61 61 20 61 61 00 0a 62  62 20 62 62 0a           |aa bb.|

Note that byte 00 (specified as \x00 ) is a non-printable character, (and in C , it also means "end of a string") - thereby, its presence makes tester.txt a binary file. The file has size of 13 bytes as seen by du , because of the trailing \n added by the echo (as it can be seen from hexdump ).

Now, let's see what happens when we try to read it with perl 's <> diamond operator (see also What's the use of <> in perl? ):

$ perl -e '
open IN, "<./tester.txt";
$data = <IN>; # does this slurp entire file in one go?
print "length is: " . length($data) . "\n";
print "data is: --$data--\n";

length is: 7
data is: --aa aa

Clearly, the entire file didn't get slurped - it broke at the line end \n (and not at the binary \x00 ). That is because the diamond filehandle <FH> operator is actually shortcut for readline (see Perl Cookbook: Chapter 8, File Contents )

The same link tells that one should undef the input record separator, \$ (which by default is set to \n ), in order to slurp the entire file. You may want to have this change be only local, which is why the braces and local are used instead of undef (see Perl Idioms Explained - my $string = do { local $/; }; ); so we have:

$ perl -e '
open IN, "<./tester.txt";
print "_$/_\n"; # check if $/ is \n
local $/; # undef $/; is global
$data = <IN>; # this should slurp one go now
print "_$/_\n"; # check again if $/ is \n
print "length is: " . length($data) . "\n";
print "data is: --$data--\n";

length is: 13
data is: --aa aa
bb bb

... and now we can see the file is slurped in its entirety.

Since binary data implies unprintable characters, you may want to inspect the actual contents of $data by printing via sprintf or pack / unpack instead.

Hope this helps someone,

[May 04, 2018] bit manipulation - Bit operations in Perl

May 04, 2018 |

4 down vote favorite

Toren ,Jan 12, 2011 at 14:50

I have an attribute (32 bits-long), that each bit responsible to specific functionality. Perl script I'm writing should turn on 4th bit, but save previous definitions of other bits.

I use in my program:

Sub BitOperationOnAttr


my $a="";

MyGetFunc( $a);

$a |= 0x00000008;

MySetFunc( $a);


** MyGetFunc/ MySetFunc my own functions that know read/fix value.


  1. if usage of $a |= 0x00000008; is right ?
  2. how extract hex value by Regular Expression from string I have : For example:

"Attribute: Somestring: value (8 long (0x8))"

Michael Carman ,Jan 12, 2011 at 16:13

Your questions are not related; they should be posted separately. That makes it easier for other people with similar questions to find them. – Michael Carman Jan 12 '11 at 16:13

toolic ,Jan 12, 2011 at 16:47

Same question asked on PerlMonks: Jan 12 '11 at 16:47

psmears ,Jan 12, 2011 at 15:00

  1. if usage of $a |= 0x00000008; is right ?

Yes, this is fine.

  1. how extract hex value by Regular Expression from string I have : For example:

"Attribute: Somestring: value (8 long (0x8))"

I'm assuming you have a string like the above, and want to use a regular expression to extract the "0x8". In that case, something like:

if ($string =~ m/0x([0-9a-fA-F]+)/) {
    $value = hex($1);
} else {
    # string didn't match

should work.

Toren ,Jan 16, 2011 at 12:35

Thank you for quick answer. You show me the right way to solve the problem – Toren Jan 16 '11 at 12:35

Michael Carman ,Jan 12, 2011 at 16:32

Perl provides several ways for dealing with binary data:

Your scenario sounds like a set of packed flags. The bitwise operators are a good fit for this:

my $mask = 1 << 3;   # 0x0008
$value |=  $mask;    # set bit
$value &= ~$mask;    # clear bit
if ($value & $mask)  # check bit

vec is designed for use with bit vectors. (Each element has the same size, which must be a power of two.) It could work here as well:

vec($value, 3, 1) = 1;  # set bit
vec($value, 3, 1) = 0;  # clear bit
if (vec($value, 3, 1))  # check bit

pack and unpack are better suited for working with things like C structs or endianness.

Toren ,Jan 16, 2011 at 12:36

Thank you . Your answer is very informative – Toren Jan 16 '11 at 12:36

sdaau ,Jul 15, 2014 at 5:01

I upvoted, but there is something very important missing: vec operates on a string! If we use a number; say: $val=5; printf("b%08b",$val); (this gives b00000101 ) -- then one can see that the "check bit" syntax, say: for($ix=7;$ix>=0;$ix--) { print vec($val, $ix, 1); }; print "\n"; will not work (it gives 00110101 , which is not the same number). The correct is to convert the number to ASCII char, i.e. print vec(sprintf("%c", $val), $ix, 1); . – sdaau Jul 15 '14 at 5:01

[Dec 21, 2017] Common Syntax Errors

Dec 21, 2017 |

One very common error is to use elseif instead of the correct elsif keyword. As you program, you'll find that you consistently make certain kinds of errors. This is okay. Everyone has his or her own little quirks. Mine is that I keep using the assignment operator instead of the equality operator. Just remember what your particular blind spot is. When errors occur, check for your personal common errors first.

This section shows some common syntax errors and the error messages that are generated as a result. First, the error message is shown and then the script that generated it. After the script, I'll cast some light as to why that particular message was generated.

Missing semiconon in one of the statements

Scalar found where operator expected at line 2, near "$bar"
        (Missing semicolon on previous line?)
$foo = { }    # this line is missing a semi-colon.
$bar = 5;
Perl sees the anonymous hash on the first line and is expecting either an operator or the semicolon to follow it. The scalar variable that it finds, $bar , does not fit the syntax of an expression because two variables can't be right after each other. In this case, even though the error message indicates line 2, the problem is in line 1.

Missing quote

Bare word found where operator expected at line 2, near "print("This"
  (Might be a runaway multi-line "" string starting on line 1)
syntax error at line 2, near "print("This is "
String found where operator expected at line 3, near "print(""
  (Might be a runaway multi-line "" string starting on line 2)
        (Missing semicolon on previous line?)
Bare word found where operator expected at line 3, near "print("This"
String found where operator expected at line 3, at end of line
        (Missing operator before ");
Can't find string terminator '"' anywhere before EOF at line 3.
print("This is a test.\n);    # this line is missing a ending quote.
print("This is a test.\n");
print("This is a test.\n");

In this example, a missing end quote has generated 12 lines of error messages! You really need to look only at the last one in order to find out that the problem is a missing string terminator. While the last error message describes the problem, it does not tell you where the problem is. For that piece of information, you need to look at the first line where it tells you to look at line two. Of course, by this time you already know that if the error message says line 2, the error is probably in line 1.

Unquoted literal

Can't call method "a" in empty package "test" at line 1.
print(This is a test.\n);    # this line is missing a beginning quote.

The error being generated here is very cryptic and has little to do with the actual problem. In order to understand why the message mentions methods and packages, you need to understand the different, arcane ways you can invoke methods when programming with objects. You probably need to add a beginning quote if you ever see this error message.

... ... ..

This list of syntax errors could go on for quite a while, but you probably understand the basic concepts:

[Dec 20, 2017] Teach Yourself Perl 5 in 21 days - Table of Contents

Dec 20, 2017 |

Chapter 21 The Perl Debugger


Today's lesson describes the Perl debugging facility. You'll learn the following:

Entering and Exiting the Perl Debugger

The following sections describe how to start the Perl debugger and how to exit.

Entering the Debugger

To debug a Perl program, specify the -d option when you run the program. For example, to debug a program named debugtest , specify the following command:

$ perl -d debugtest

You can supply other options along with -d if you want to.

When the Perl interpreter sees the -d option, it starts the Perl debugger. The debugger begins by displaying a message similar to the following one on your screen:

Loading DB routines from $RCSfile:,v  $$Revision:

$$Date: 92/06/08 13:43:57 $

Emacs support available.

Enter h for help.

main::(debugtest:3):        $dircount = 0;


The first few lines display the date on which this version of the debugger was created. The only lines of interest are the last two.

The second-to-last line in this display lists the line that the debugger is about to execute. When the debugger starts, the first executable line of the program is displayed.

When the debugger displays a line that it is about to execute, it also provides the following information about the line:

The last line of the display prompts you for a debugging command. The number enclosed in angle brackets indicates the command number; in this case, the number is 1 , because you are about to specify the first debugging command.

Later today you will learn how to use the debugging command number to re-enter debugging commands you have previously executed.

To enter the debugger without supplying a program, supply the -e option with the -d option:
$ perl -d -e "1;"
This line starts the debugger with a "program" consisting of the single statement
(which is an expression that doesn't do anything meaningful).
Starting the debugger without a program enables you to examine the predefined system variables or supply statements to be executed. You will learn how to perform both of these tasks later in today's lesson
Exiting the Debugger

To exit the debugger, enter the debugging command q :

DB<1> q

This command halts program execution immediately and returns you to the command shell.

Listing Your Program

You can list any part of your program from within the debugger. The following sections describe debugging commands that perform the display operations.

The command

The simplest way to list part of your program is with the l command, which lists the next few statements in your program:

  DB<1> l

3:      $dircount = 0;

4:      $curdir = "";

5:      while (1) {

6:              # if we don't have a current directory, get one

7:              if ($curdir eq "") {

8:                      print ("Enter directory to list:\n");

9:                      $curdir = <STDIN>;

10:                     $curdir =~ s/^\s+|\s+$//g;

11:                     $curdir = &followlink($curdir);

12:                     &readsubdirs($curdir);

The l command lists a window of executable statements, which is a group of statements small enough to be easily displayed on your screen. A window usually consists of about ten statements. The line number of each statement is displayed at the beginning of its line.

The statements displayed in today's lesson are taken from the program presented in "Week 2 in Review."

Entering the l command again displays the window of statements immediately following the last displayed line, which in this example is line 12:

  DB<1> l

13:             }

14:             $curdir = &menudir($curdir);

15:     }



18:     # Find all subdirectories of the given directory,

19:     # and store them in an associative array.

20:     #

21:     # The associative array subscripts and values are:

22:     # <directory name>:       1

You can specify the lines displayed by the l command. If you specify a single line number with the l command, it displays that line:

  DB<1> l 10

10:                      $curdir =~ s/^\s+|\s+$//g;

To display a range of lines, specify the first and last line number, and separate them with a hyphen:

  DB<1> l 10-15

10:                      $curdir =~ s/^\s+|\s+$//g;

11:                      $curdir = &followlink($curdir);

12:                      &readsubdirs($curdir);

13:             }

14:             $curdir = &menudir($curdir);

15:     }

To display a specified number of lines starting at a certain point, supply the starting line number, a + character, and a number of additional lines to display:

  DB<1> l 10+5

10:                      $curdir =~ s/^\s+|\s+$//g;

11:                      $curdir = &followlink($curdir);

12:                      &readsubdirs($curdir);

13:             }

14:             $curdir = &menudir($curdir);

15:     }

You also can use the l command to specify a subroutine to display. To do this, provide the name of the subroutine to display:

  DB<1> l readsubdirs

26:     sub readsubdirs {

27:             local ($dirname) = @_;

28:             local ($dirvar, $subdircount, $name, $index);


30:             # open the current directory;

31:             # $dircount ensures that each file variable is unique

32:             $dirvar = "DIR" . ++$dircount;

33:             if (!opendir ($dirvar, $dirname)) {

34:                     warn ("Can't open $dirname\n");

35:                     return;

This command lists the statements in the subroutine. If the subroutine is too large to fit in a single window, only the first few statements are listed; you can list subsequent statements by entering l with no arguments.

The Command

You can display the lines immediately preceding the last displayed line by entering the - command. For example, the following - command lists the window of lines immediately preceding the subroutine readsubdirs .

  DB<1> -



18:     # Find all subdirectories of the given directory,

19:     # and store them in an associative array.

20:     #

21:     # The associative array subscripts and values are:

22:     # <directory name>:       1

23:     #       (indicates that directory has been read)

24:     # <directory name>.<num>  the <num>th subdirectory


Subsequent - commands go back further in the file.

The Command

To list a window of lines containinga specified line, use the w command, and specify the number of the line to be included:

  DB<1> w 7

4:      $curdir = "";

5:      while (1) {

6:              # if we don't have a current directory, get one

7:              if ($curdir eq "") {

8:                      print ("Enter directory to list:\n");

9:                      $curdir = <STDIN>;

10:                     $curdir =~ s/^\s+|\s+$//g;

11:                     $curdir = &followlink($curdir);

12:                     &readsubdirs($curdir);

13:             }

The w command displays the three lines before the specified line and fills the window with the lines following it.

The // and ?? Commands

You can search for a line containing a particular pattern by enclosing the pattern in slashes:

  DB<1> /Find/

18:     # Find all subdirectories of the given directory,

The debugger searches forward from the last displayed line for a line matching the specified pattern. If it finds such a line, the line is displayed.

To search backward for a particular pattern, enclose the pattern in question marks:

  DB<1> ?readsubdirs?

12:                      &readsubdirs($curdir);

This command starts with the last displayed line and searches backward until it finds a line matching the specified pattern.

Patterns specified by // and ?? can contain any special character understood by the Perl interpreter.
You optionally can omit the final / or ? character when you match a pattern.
The Command

The S command lists all the subroutines in the current file, one subroutine per line:

  DB<> S





Each subroutine name is preceded by the package name and a single quotation mark.

Stepping Through Programs

One of the most useful features of the Perl debugger is the capability to execute a program one statement at a time. The following sections describe the statements that carry out this action.

The Command

To execute a single statement of your program, use the s command:

  DB<2> s

main::(debugtest:4):        $curdir = "";

This command executes one statement of your program and then displays the next statement to be executed. If the statement executed needs to read from the standard input file, the debugger waits until the input is provided before displaying the next line to execute.

If you have forgotten which line is the next line to execute (because, for example, you have displayed lines using the l command), you can list the next line to execute using the L command:
DB<2> L
3: $dircount = 0;
The L command lists the last lines executed by the program. It also lists any breakpoints and line actions that have been defined for particular lines. Breakpoints and line actions are discussed later today.

If the statement executed by the s command calls a subroutine, the Perl debugger enters the subroutine but does not execute any statements in it. Instead, it stops at the first executable statement in the subroutine and displays it. For example, if the following is the current line:

main::(debugtest:12):                      &readsubdirs($curdir);

specifying the s command tells the Perl debugger to enter readsubdirs and display the following, which is the first executable line of readsubdirs :

main::readsubdirs(debugtest:27):      local ($dirname) = @_;

The s command assumes that you want to debug the subroutine you have entered. If you know that a particular subroutine works properly and you don't want to step through it one statement at a time, use the n command, described in the following section.

The Command

The n command, like the s command, executes one line of your program and displays the next line to be executed:

  DB<2> n

main::(debugtest:5):        while (1) {

The n statement, however, does not enter any subroutines. If the statement executed by n contains a subroutine call, the subroutine is executed in its entirety. After the subroutine is executed, the debugger displays the line immediately following the call.

For example, if the current line is

main::(debugtest:12):                      &readsubdirs($curdir);

the n command tells the debugger to execute readsubdirs and then display the next line in the program, which is

main::(debugtest:13:):             }

Combining the use of s and n ensures that the debugger examines only the subroutines you want to see.

The Perl debugger does not enable you to enter any library functions. You can enter only subroutines that you have created yourself or that have been created previously and added to a subroutine library
The command

The f command tells the Perl debugger to execute the remainder of the statements in the current subroutine and then display the line immediately after the subroutine call. This is useful when you are looking for a bug and have determined that the current subroutine does not contain the problem.

The Carriage-Return Command

If you are stepping through a program using s or n , you can save yourself some typing by just pressing Enter when you want to execute another statement. When you press Enter, the debugger repeats the last s or n command executed.

For example, to step from line 5 to line 7, you can use the s command as usual:

  DB<3> s

main::(debugtest:7):              if ($curdir eq "") {

(Line 6 is skipped because it contains no executable statements.) To execute line 7, you can now just press Enter:


main::(debugtest:8):              print ("Enter directory to list:\n");

Pressing Enter has no effect if you have not specified any s or n commands.
The Command

If you are inside a subroutine and decide that you no longer need to step through it, you can tell the Perl debugger to finish executing the subroutine and return to the statement after the subroutine call. To do this, use the r command:

  DB<4> r

main::(debugtest:13:):             }

The statement displayed by the debugger is the first statement following the call to the subroutine.

Displaying Variable Values

Another powerful feature of the Perl debugger is the capability to display the value of any variable at any time. The following sections describe the commands that perform this action.

The Command

The X command displays variables in the current package (which is main if no other package has been specified). If the X command is specified by itself, it lists all the variables in the current package, including the system-defined variables and the variables used by the Perl interpreter itself. Usually, you won't want to use the X command by itself, because there are a lot of system-defined and internal variables known to the Perl interpreter.

To print the value of a particular variable or variables, specify the variable name or names with the X command:

  DB<5> X dircount

$dircount = '0'

This capability often is useful when you are checking for errors in your program.

You must not supply the $ character with the variable name when you use the X command. If you supply the $ character (or the @ or % characters for arrays), the debugger displays nothing.

You can use X to display the values of array variables and associative array variables.

  DB<6> X regarray

@regarray = (

  0     14

  1     'hello'

  2     36


  DB<7> X assocarray

%assoc_array = (

  'hi'  1

  'there' 2


Each command prints the subscripts of the array and their values. Regular arrays are printed in order of subscript; associative arrays are printed in no particular order.

If you have an array variable and a scalar variable with the same name, the X command prints both variables:
DB<8> X var
$var = '0'
@var = (
0 'test1'
1 'test2'
There is no way to use X to display one variable but not the other.
The Command

The V command is identical to the X command except that it prints the values of variables in any package. If you specify just a package name, as in the following, this command displays the values of all variables in the package (including system-defined and internal variables):

DB<9> V mypack

If you specify a package name and one or more variable names, as in the following, the debugger prints the values of the variables (if they are defined in that package):

  DB<10> V main dircount

$dircount = '0'


As you have seen, you can tell the Perl debugger to execute one statement at a time. Another way of controlling program execution is to tell the debugger to execute up to a certain specified point in the program, called a breakpoint .

The following sections describe the commands that create breakpoints, and the command that executes until a breakpoint is detected.

The Command

To set a breakpoint in your program, use the b command. This command tells the debugger to halt program execution whenever it is about to execute the specified line. For example, the following command tells the debugger to halt when it is about to execute line 10:

DB<11> b 10

(If the line is not breakable, the debugger will return Line 10 is not breakable .)

You can have as many breakpoints in your program as you want. The debugger will halt program execution if it is about to execute any of the statements at which a breakpoint has been defined.

The b command also accepts subroutine names:

DB<12> b menudir

This sets a breakpoint at the first executable statement of the subroutine menudir .

You can use the b command to tell the program to halt only when a specified condition is true. For example, the following command tells the debugger to halt if it is about to execute line 10 and the variable $curdir is equal to the null string:

DB<12> b 10 ($curdir eq "")

The condition specified with the b statement can be any legal Perl conditional expression.

If a statement is longer than a single line, you can set a breakpoint only at the first line of the statement:
71: print ("Test",
72: " here is more output");
Here, you can set a breakpoint at line 71, but not line 72.
The Command

After you have set a breakpoint, you can tell the debugger to execute until it reaches either the breakpoint or the end of the program. To do this, use the c command:

  DB<13> c

main::(debugtest:10):                  $curdir =~ s/^\s+|\s+$//g;


When the debugger detects that it is about to execute line 10-the line at which the breakpoint was set-it halts and displays the line. (Recall that the debugger always displays the line it is about to execute.)

The debugger now prompts you for another debugging command. This action enables you to start executing one statement at a time using n or s , continue execution using c , set more breakpoints using b , or perform any other debugging operation.

You can specify a temporary (one-time-only) breakpoint with the c command by supplying a line number:

  DB<15> c 12

main::(debugtest:12):                      &readsubdirs($curdir);

The argument 12 supplied with the c command tells the debugger to define a temporary breakpoint at line 12 and then resume execution. When the debugger reaches line 12, it halts execution, displays the line, and deletes the breakpoint. (The line itself still exists, of course.)

Using c to define a temporary breakpoint is useful if you want to skip a few lines without wasting your time executing the program one statement at a time. Using c also means that you don't have to bother defining a breakpoint using b and deleting it using d (described in the following section).

If you intend to define breakpoints using c or b , it is a good idea to ensure that each line of your program contains at most one statement. If you are in the habit of writing lines that contain more than one statement, such as
$x++; $y++;
you won't get as much use out of the debugger, because it can't stop in the middle of a line
The Command and Breakpoints

To list all of your breakpoints, use the L command. This command lists the last few lines executed, the current line, the breakpoints you have defined, and the conditions under which the breakpoints go into effect.

  DB<16> L

3:      $dircount = 0;

4:      $curdir = "";

5:      while (1) {

7:              if ($curdir eq "") {

10:                      $curdir =~ s/^\s+|\s+$//g;

  break if (1)

Here, the program has executed lines 3-7, and a breakpoint is defined for line 10. (Line 6 is not listed because it is a comment.) You can distinguish breakpoints from executed lines by looking for the breakpoint conditional expression, which immediately follows the breakpoint. Here, the conditional expression is (1) , which indicates that the breakpoint is always in effect.

The and Commands

When you are finished with a breakpoint, you can delete it using the d command.

DB<16> d 10

This command tells the debugger to delete the breakpoint at line 10. The line itself remains in the program.

If you do not specify a breakpoint to delete, the debugger assumes that a breakpoint is defined for the next line to be executed, and deletes it.

main::(debugtest:12):                      &readsubdirs($curdir);

  DB<17> d

Here, line 12 is the next line to be executed, so the debugger deletes the breakpoint at line 12.

To delete all your breakpoints, use the D command.

DB<18> D

This command deletes all the breakpoints you have defined with the b command.

Tracing Program Execution

When you run a program using the Perl debugger, you can tell it to display each line as it is executed. When the debugger is doing this, it is said to be in trace mode .

To turn on trace mode, use the T command.

  DB<18> t

Trace = on

When a statement is executed in trace mode, the statement is displayed. For example, if the current line is line 5 and the command c 10 (which executes up to line 10) is entered, the following is displayed:

  DB<18> c 10

main::(debugtest:5):      while (1) {

main::(debugtest:7):              if ($curdir eq "") {

main::(debugtest:10):                      $curdir =~ s/^\s+|\s+$//g;


The debugger prints and executes line 5 and line 7, then displays line 10 and waits for further instructions.

To turn off trace mode, specify the t command again.

  DB<19> t

Trace = off

At this point, trace mode is turned off until another t command is entered.

Line Actions

The Perl debugger enables you to specify one or more statements to be executed whenever the program reaches a specified line. Such statements are known as line actions. The most common line actions are printing the value of a variable and resetting a variable containing an erroneous value to the value you want.

The following sections describe the debugging commands that define line actions.

The Command

To specify a line action for a particular line, use the a command.

DB<19> a 10 print ("curdir is $curdir\n");

This command tells the debugger to execute the statement

print ("curdir is $curdir\n");

whenever it is about to execute line 10 of the program. The debugger performs the action just after it displays the current line and before it asks for the next debugging command.

To create a line action containing more than one statement, just string the statements together. If you need more than one line for the statements, put a backslash at the end of the first line.

  DB<20> a 10 print ("curdir is $curdir\n"); print \

("this is a long line action\n");

In this case, when the debugger reaches line 10, it executes the following statements:

print ("curdir is $curdir\n");

print ("this is a long line action\n");

The Command

To delete the line actions defined using the a command, use the A command.

DB<21> A

This command deletes all line actions currently defined.

The A command does not affect the < and > commands, described in the following section.
The < and > Commands

To define a line action that is to be executed before the debugger executes any further statements, use the > command.

DB<21> > print ("curdir before execution is $curdir\n");

This command tells the debugger to print the value of $curdir before continuing.

Similarly, the < command defines a line action that is to be performed after the debugger has finished executing statements and before it asks for another debugging command:

DB<22> < print ("curdir after execution is $curdir\n");

This command tells the debugger to print the value of $curdir before halting execution again.

The < and > commands are useful when you know that one of your variables has the wrong value, but you don't know which statement assigned the wrong value to the variable. By single-stepping through the program using s or n , and printing the variable either before or after executing each statement, you can determine where the variable was given its incorrect value.

To delete a line action defined by the < command, enter another < command with no line action defined.
DB<23> <
Similarly, the following command undoes the effects of a > command:
DB<24> >
Displaying Line Actions Using the Command

The L command prints any line actions you have defined using the a command (as well as breakpoints and executed lines). For example, suppose that you have defined a line action using the following command:

DB<25> a 10 print ("curdir is $curdir\n");

The L command then displays this line action as shown here:

main::(debugtest:10):                      $curdir =~ s/^\s+|\s+$//g;

  action:  print ("curdir is $curdir\n");

The line action is always displayed immediately after the line for which it is defined. This method of display enables you to distinguish lines containing line actions from other lines displayed by the L command.

Other Debugging Commands

The following sections describe the debugging commands not previously covered.

Executing Other Perl Statements

In the debugger, anything that is not a debugging command is assumed to be a Perl statement and is performed right away. For example:

DB<4> @array = (1, 2, 3);

You can use statements such as this to alter values in your program as it is being executed. This capability is useful when you are testing your code.

If you wish, you can omit the semicolon at the end of the statement.
The Command: Listing Preceding Commands

The H (for "history") command lists the preceding few commands you have entered.

  DB<4> H

3: b 7

2: b 14

1: b 13

The commands are listed in reverse order, with the most recently executed command listed first. Each command is preceded by its command number, which is used by the ! command (described in the following section).

The debugger saves only the commands that actually affect the debugging environment. Commands such as l and s , which perform useful work but do not change how the debugger behaves, are not listed by the H command.
This is not a significant limitation because you can enter the letter again if needed.
The Command: Executing Previous Commands

Each command that is saved by the debugger and can be listed by the H command has a command number. You can use this command number to repeat a previously executed command. For example, to repeat command number 5, make the following entry:

  DB <11> !5

b 8

  DB <12>

The debugger displays command number 5-in this case, the command b 8 - and then executes it.

If you omit the number, the debugger repeats the last command executed.

  DB <12> $foo += $bar + 1

  DB <13> !

$foo += $bar + 1

  DB <14>

If you specify a negative number with ! , the debugger skips back that many commands:

  DB <14> $foo += $bar + 1

  DB <15> $foo *= 2

  DB <16> ! -2

$foo += $bar + 1

  DB <17>

Here, the ! -2 command refers to the command $foo += $bar + 1 .

You can use ! only to repeat commands that are actually repeatable. Use the H command to list the commands that the debugger has saved and that can be repeated
The Command: Stack Tracing

The T command enables you to display a stack trace, which is a collection of all the subroutines that have been called, listed in reverse order. Here is an example:

  DB <16> T

$ = &main::sub2('hi') from file debug1 line 7

$ = &main::sub1('hi') from file debug1 line 3

Here, the T command indicates that the program is currently inside subroutine sub2 , which was called from line 7 of your program; this subroutine is part of the main package. The call to sub2 is passed the argument 'hi' .

The $ = preceding the subroutine name indicates that the subroutine call is expecting a scalar return value. If the call is expecting a list to be returned, the characters @ = appear in front of the subroutine name.

The next line of the displayed output tells you that sub2 was called by another subroutine, sub1 . This subroutine was also passed the argument 'hi' , and it was called by line 3 of the program. Because the stack trace lists no more subroutines, line 3 is part of your main program.

The list of arguments passed to a subroutine that is displayed by the stack trace is the list of actual values after variable substitution and expression evaluation are performed. This procedure enables you to use the stack trace to check whether your subroutines are being passed the values you expect.
The Command: Printing an Expression

An easy way to print the value of an expression from inside the debugger is to use the p command.

  DB <17> p $curdir + 1


The p command evaluates the expression and displays the result.

The p command writes to the screen even when the program has redirected STDOUT to a file.
The Command: Defining Aliases

If you find yourself repeatedly entering a long debugging command and you want to save yourself some typing, you can define an alias for the long command by using the = command. For example:

  DB <15> = pc print ("curdir is $curdir\n");

= pc print ("curdir is $curdir\n");

The = command prints the alias you have just defined and then stores it in the associative array %DB'alias (package DB , array name alias ) for future reference. From here on, the command

DB <16> pc

is equivalent to the command

DB <16> print ("curdir is $curdir\n");

To list the aliases you have defined so far, enter the = command by itself:

  DB <17> =

pc =  print ("curdir is $curdir\n")

This command displays your defined aliases and their equivalent values.

Predefining Aliases

You can define aliases that are to be created every time you enter the Perl debugger.

When the debugger starts, it first searches for a file named .perldb in your home directory. If the debugger finds this file, it executes the statements contained there.

To create an alias, add it to the .perldb file. For example, to add the alias

= pc print ("curdir is $curdir\n");

add the following statement to your .perldb file:

$DB'alias{"pc"} = 's/^pc/print ("curdir is $curdir\n");/';

Here's how this works: when the Perl debugger creates an alias, it adds an element to the $DB'alias associative array. The subscript for this element is the alias you are defining, and the value is a substitution command that replaces the alias with the actual command you want to use. In the preceding example, the substitution takes any command starting with pc and replaces it with

print ("curdir is $curdir\n");

Be careful when you define aliases in this way. For example, your substitution should match only the beginning of a command, as in /^pc/ . Otherwise, the alias will replace any occurrence of the letters pc with your print command, which is not what you want.
The Command: Debugger Help

The h (for help) command provides a list of each of the debugger commands listed in today's lesson, along with a one-line explanation of each. This is handy if you are in the middle of debugging a program and forget the syntax of a particular command.


Today, you have learned about the Perl debugger. This debugger enables you to perform the following tasks, among others:

Q: Is it possible to enter more than one debugging command at a time?
A: No; however, there's no real need to do so. If you want to perform several single steps at once, use the c command to skip ahead to a specified point. If you want to both step ahead and print the value of a variable, use the < or > command.
Q: Is it possible to examine variables in one package while inside another?
A: Yes. Use the V command or the standard Perl package/variable syntax.
Q: If I discover that my program works and I want to turn off debugging, what do I do?
A: You cannot exit the debugger in the middle of a program. However, if you delete all breakpoints and line actions and then enter the c command, the program begins executing normally and is no longer under control of the debugger.
Q: How can I convert to a reusable breakpoint a one-time breakpoint created using c ?
A: By default, the b command sets a breakpoint at the line that is about to be executed. This is the line at which c has set its one-time breakpoint.
Q: How can I execute other UNIX commands from inside the debugger?
A: Enter a statement containing a call to the Perl system function. For example, to display the contents of the current directory, enter the following command:
DB <11> system ("ls");
To temporarily escape from the debugger to a UNIX shell, enter the following command:
DB <12> system ("sh");
When you are finished with the shell, enter the command exit, and you will return to the debugger.
Q: What special built-in variables can be accessed from inside the debugger?
A: All of them.

The Workshop provides quiz questions to help you solidify your understanding of the material covered.

  1. Define the following terms:
    1. trace mode
    2. stack trace
    3. breakpoint
    4. line action
  1. Explain the differences between the X and V commands.
  2. Explain the differences between the // and ?? commands.
  3. Explain the differences between the < and > commands.
  4. Explain the differences between the s and n commands.
  5. What do the following commands do?
    1. l
    2. l 26
    3. l 5-7
    4. l 5+7
    5. w

[Dec 20, 2017] debugging - Can the Perl debugger save the ReadLine history to a file

Dec 20, 2017 |
The way I do this is by having the following line in my ~/.perldb file:


Debugger commands are then stored in ~/.perldb.hist and accessible across sessions.

I did the following:

1) Created ~/.perldb , which did not exist previously.

2) Added &parse_options("HistFile=$ENV{HOME}/.perldb.hist"); from mirod's answer.

3) Added export PERLDB_OPTS=HistFile=$HOME/.perldb.history to ~/.bashrc from mephinet's answer.

4) Ran source .bashrc

5) Ran perl -d my , and got this warning/error

perldb: Must not source insecure rcfile /home/ics/.perldb.
        You or the superuser must be the owner, and it must not 
        be writable by anyone but its owner.

6) I protected ~/.perldb with owner rw chmod 700 ~/.perldb , and the error went away.

[Dec 20, 2017] The Perl Debugger

Dec 20, 2017 |


There is one more variation of the list code command, l . It is the ability to list the code of a subroutine, by typing l sub , where sub is the subroutine name.

Running the code in Listing 2 returns:

Loading DB routines from version 1
Emacs support available.
Enter h or h h for help.
main::(./ require 5.001;

Entering l searchdir allows us to see the text of searchdir , which is the meat of this program.

22 sub searchdir { # takes directory as argument
23: my($dir) = @_;
24: my(@files, @subdirs);
26: opendir(DIR,$dir) or die "Can't open \"
27:     $dir\" for reading: $!\n";
29: while(defined($_ = readdir(DIR))) {
30: /^\./ and next; # if file begins with '.', skip
32 ### SUBTLE HINT ###
As you can see, I left a subtle hint. The bug is that I deleted an important line at this point.

Setting Breakpoints

If we were to step through every line of code in a subroutine that is supposed to be recursive, it would take all day. As I mentioned before, the code as in Listing 2 seems only to list the files in the current directory, and it ignores the files in any subdirectories. Since the code only prints the files in the current, initial directory, maybe the recursive calls aren't working. Invoke the Listing 2 code under the debugger.

Now, set a breakpoint. A breakpoint is a way to tell the debugger that we want normal execution of the program until it gets to a specific point in the code. To specify where the debugger should stop, we insert a breakpoint. In the Perl debugger, there there are two basic ways to insert a breakpoint. The first is by line number, with the syntax b linenum . If linenum is omitted, the breakpoint is inserted at the next line about to be executed. However, we can also specify breakpoints by subroutine, by typing b sub , where sub is the subroutine name. Both forms of breakpointing take an optional second argument, a Perl conditional. If when the flow of execution reached the breakpoint the conditional evaluates to true, the debugger will stop at the breakpoint; otherwise, it will continue. This gives greater control of execution.

For now we'll set a break at the searchdir subroutine with b searchdir . Once the breakpoint is set, we'll just execute until we hit the subroutine. To do this, enter c (for continue). Adding Actions

Looking at the code in Listing 2, we can see that the first call to searchdir comes in the main code. This seems to works fine, or else nothing would be printed out. Press c again to continue to the next invocation of searchdir , which occurs in the searchdir routine.

We wish to know what is in the $dir variable, which represents the directory that will be searched for files and subdirectories. Specifically, we want to know the contents of this variable each time we cycle through the code. We can do this by setting an action. By looking at the program listing, we see that by line 25, the variable $dir has been assigned. So, set an action at line 25 in this way:

a 25 print "dir is $dir\n"

Now, whenever line 25 comes around, the print command will be executed. Note that for the a command, the line number is optional and defaults to the next line to be executed.

Pressing c will execute the code until we come across a breakpoint, executing action points that are set along the way. In our example, pressing c continuously will yield the following:

main::(../ require 5.001;
 DB<1> b searchdir
 DB<2> a 25 print "dir is $dir\n"
 DB<3> c
main::searchdir(../ my($dir) = @_;
 DB<3> c
dir is .
main::searchdir(../ my($dir) = @_;
 DB<3> c
dir is dir1.0
main::searchdir(../ my($dir) = @_;
 DB<3> c
dir is dir2.0
main::searchdir(../ my($dir) = @_;
 DB<3> c
dir is dir3.0
2043: "Debugged program terminated. Use `q' to quit or `R' to

Note that older versions of the debugger don't output the last line as listed here, but instead exit the debugger. This newer version is nice because when the program has finished it still lets you have control so that you can restart the program.

It still seems that we aren't getting into any subdirectories. Enter D and A to clear all breakpoints and actions, respectively, and enter R to restart. Or, in older debugger versions, simply restart the program to begin again.

We now know that the searchdir subroutine isn't being called for any subdirectories except the first level ones. Looking back at the text of the program, notice in lines 44 through 46 that the only time the searchdir subroutine is called recursively is when there is something in the @subdirs list. Put an action at line 42 that will print the $dir and @subdirs variables by entering:

a 42 print "in $dir is @subdirs \n"

Now, put a breakpoint at line 12 to prevent the program from outputting to our screen ( b 12 ), then enter c . This will tell us all the subdirectories that our program thinks are in the directory.

main::(../ require 5.001;
 DB<1> a 42 print "in $dir is @subdirs \n"
 DB<2> b 12
 DB<3> c
in . is dir1.0 dir2.0 dir3.0
in dir1.0 is
in dir2.0 is
in dir3.0 is
main::(../ foreach (@files) {
This program sees that there are directories in ".", but not in any of the subdirectories within ".". Since we are printing out the value of @subdirs at line 42, we know that @subdirs has no elements in it. (Notice that when listing line 42, there is the letter "a" after the line number and a colon. This tells us that there is an action point here.) So, nothing is being assigned to @subdirs in line 37, but should be if the current (as held in $_ ) file is a directory. If it is, it should be pushed into the @subdirs list. This is not happening.

One error I've committed (intentionally, of course) is on line 38. There is no catch-all "else" statement. I should probably put an error statement here. Instead of doing this, let's put in another action point. Reinitialize the program so that all points are cleared and enter the following:

a 34 if( ! -f $_ and ! -d $_ ) { print "in $dir: $_ is
weird!\n" }
b 12"

which reveals:

main::(../ require 5.001;
 DB<1> a 34 if( ! -f $_ and ! -d $_ ) { print "in $dir:
$_ is weird!\n" }
 DB<2> b 12
 DB<3> c
in dir1.0: dir1.1 is weird!
in dir1.0: dir2.1 is weird!
in dir1.0: file2 is weird!
in dir1.0: file3 is weird!
in dir2.0: dir2.1 is weird!
in dir2.0: dir1.1 is weird!
in dir2.0: file2 is weird!
in dir2.0: file3 is weird!
main::(../ foreach (@files) {
While the program can read (through the readdir call on line 29) that dir1.1 is a file of some type in dir1.0, the file test (the -f construct) on dir1.1 says that it is not.

It would be nice to halt the execution at a point (line 34) where we have a problem. We can use the conditional breakpoint that I mentioned earlier to do this. Reinitialize or restart the debugger, and enter:

b 34 ( ! -f $_ and ! -d $_ )
p $dir

You'll get output that looks like this:

main::(../ require 5.001;
 DB<1> b 34 ( ! -f $_ and ! -d $_ )
 DB<2> c
main::searchdir(../ if( -f $_) { # if its a file...
 DB<2> p
 DB<2> p $dir
The first line sets the breakpoint, the next c executes the program until the break point stops it. The p prints the contents of the variable $_ and the last command, p $dir prints out $dir . So, dir1.1 is a file in dir1.0, but the file tests ( -d and -f ) don't admit that it exists, and therefore dir1.1 is not being inserted into @subdirs (if it's a directory) or into @files (if it's a file).

Now that we are back at a prompt, we could inspect all sorts of variables, subroutines or any other Perl construct. To save you from banging your heads against your monitors, and thus saving both your heads and your monitors, I'll tell you what is wrong.

All programs have something known as the current working directory (CWD). By default, the CWD is the directory where the program starts. Any and all file accesses (such as file tests or file and directory openings) are made in reference from the CWD. At no time does our program change its CWD. But the values returned by the readdir call on line 29 are simply file names relative to the directory that readdir is reading (which is in $dir ). So, when we do the readdir , $_ gets assigned a string representing a file (or directory) within the directory in $dir (which is why it's called a subdirectory). But when running the -f and -d file tests, they look for $_ in the context of the CWD. But it isn't in the CWD, it's in the directory represented by $dir . The moral of the story is that we should be working with $dir/$_ , not just $_ . So the string


should be replaced by

$_ = "$dir/$_"; # make all path names absolute
That sums it up. Our problem was we were dealing with relative paths, not absolute (from the CWD) paths.

Putting it back into our example, we need to check dir1.0/dir1.1 , not dir1.1 . To check to make sure that this is what we want, we can put in another action point. Try typing:

a 34 $_ = "$dir/$_"

In effect this temporarily places the corrective measure into our code. Action points are the first item on the line to be evaluated. You should now see the proper results of the execution of the program:

DB<1> a 34 $_ = "$dir/$_"
DB<2> c
2043: "Debugged program terminated. Use `q' to quit or `R' to

Stack Traces

Now that we've got the recursive call debugged, let's play with the calling stack a bit. Giving the command T will display the current calling stack. The calling stack is a list of the subroutines which have been called between the current point in execution and the beginning of execution. In other words, if the main portion of the code executes subroutine "a", which in turn executes subroutine "b", which calls "c", then pressing "T" while in the middle of subroutine "c" outputs a list going from "c" all the way back to "main".

Start up the program and enter the following commands (omit the second one if you have fixed the bug we discovered in the last section):

b 34 ( $_ =~ /file2$/)
a 34 $_ = "$dir/$_"

These commands set a breakpoint that will only stop execution if the value of the variable $_ ends with the string file2 . Effectively, this code will halt execution at arbitrary points in the program. Press T and you'll get this:

@ = main::searchdir('./dir1.0/file2') called from file '../' line
@ = main::searchdir(.) called from file '../' line 10

Enter c , then T again:

@ = main::searchdir('./dir1.0/dir1.1/file2') called from file
`../' line 45
@ = main::searchdir(undef) called from file '../' line 45
@ = main::searchdir(.) called from file '../' line 10

Do it once more:

@ = main::searchdir('./dir2.0/file2') called from file '../' line
@ = main::searchdir(.) called from file '../' line 10

You can go on, if you so desire, but I think we have enough data from the arbitrary stack dumps we've taken.

We see here which subroutines were called, the debugger's best guess of which arguments were passed to the subroutine and which line of which file the subroutine was called from. Since the lines begin with @ = , we know that searchdir will return a list. If it were going to return a scalar value, we'd see $ = . For hashes (also known as associative arrays), we would see % = .

I say "best guess of what arguments were passed" because in Perl, the arguments to subroutines are placed into the @_ magic list. However, manipulating @_ (or $_ ) in the body of the subroutine is allowed and even encouraged. When a T is entered, the stack trace is printed out, and the current value of @_ is printed as the arguments to the subroutine. So when @_ is changed, the trace doesn't reflect what was actually passed as arguments to the subroutine.

[Dec 20, 2017] Creating Command Aliases

Notable quotes:
"... You use the = command without any arguments when you want a list of the current aliases. ..."
Dec 20, 2017 |

The = command is used to create command aliases. If you find yourself issuing the same long command over and over again, you can create an alias for that command. For example, the debugger command

= pFoo print("foo=$foo\n");
creates an alias called pFoo . After this command is issued, typing pFoo at the debugger prompt produces the same results as typing print("foo=$foo\n"); .

You use the = command without any arguments when you want a list of the current aliases.

If you want to set up some aliases that will always be defined, create a file called .perldb and fill it with your alias definitions. Use the following line as a template:

$DB::alias{'pFoo'} = 'print("foo=$foo\n");';
After you create this file and its alias definitions, the aliases will be available in every debugging session.

[Dec 20, 2017] Perl Debugger Quick Reference Card by Andrew Ford

Notable quotes:
"... in the current and home directories ..."
"... Any input to the debugger that is not recognized is executed as Perl code in the current package. ..."
Dec 20, 2017 |

Revision 0.1 for Perl Debugger version 5.8.x

Copyright: Andrew Ford™

... ... ...

Debugger Commands

The debugger reads commands from the files .perldb in the current and home directories, and stops before the first run-time executable statement, displaying the line it is about to execute and a prompt:


If you run code from the debugger and hit another breakpoint, the prompt will look like DB"42". The numbers within the angle brackets are the command numbers, used when repeating commands.

Any input to the debugger that is not recognized is executed as Perl code in the current package.

Prefixing a command with ' | ' pipes the output to your current pager.

Help and Quiting

Debugger Control

... ... ...

[Dec 20, 2017] Chapter 30 -- Using the Perl Debugger

Dec 20, 2017 |
... ... ... Looking at Values

To see the values of certain variables in the program, use the V command. Used by itself, V lists all the variables in scope at this time. Here's the syntax:

V [ package [ variable ]]

To look at values in your program, you'll want to look at the main package. For example, to print the value of $reply , use this command:

V main reply
$reply = '1'

Note that the dollar sign before the variable specified to V is not supplied. Therefore, if you specify the command V main $reply , you are actually asking for the value of $$reply and not $reply .

The trace option is available with the t toggle command. Issuing trace once turns it on, and issuing it again turns it off. See Figure 30.4 for a sample use of the trace command on Listing 30.2. In this example, trace is turned on, and then the c command is issued to run the debugger continuously. In trace mode, the debugger prints out each line of code that executes.

Figure 30.4 : Using the trace command with breakpoints.

The X command is helpful when displaying values of variables in the current package. Remember that the main package is the default package for a Perl script. Issued by itself with no options, the X command displays all the variables in the current package. Avoid issuing the X command by itself because it can generate a very long listing of all the variables in the main package.

To see the value of a particular variable instead of all the variables, type the name of the variable after the X command. For example, the following command

X fileNumber

will print the value of the fileNumber variable in the current package. If you have array variables and scalar variables with the same name in the same package, the X command will display the values of both these variables. For example, if you have a scalar variable called names and an array called names , the X command will show the values of both variables:

DB<3> X names
$names = "kamran"
@names = (

You can place breakpoints at suspect locations in your code and run the program until one of the specified breakpoints is hit. Breakpoints can be specified to be hit as soon as the line of code is about to be executed.

The c command is used to step forward until either the program stops or a specified breakpoint is hit. To specify a breakpoint at the current line, use the b command without any parameters. To specify a specific line, use the command of the form:

b linenumber

Usually, you use trace statements to see statements between the current execution point and a breakpoint (refer to Figure 30.4). The program is run in continuous mode with the c command until it hits a breakpoint. There is a breakpoint in Listing 30.1 that causes the debugger to stop. The L command is issued in the example to list the breakpoints in the system.

Breakpoints can also be specified to occur at the first executable line of code within a subroutine. Simply use the b command with the name of the subroutine as the first parameter. For example, to break at the first line of code in the xyc subroutine, try this command:

b xyc

You can also ask the debugger to look at a condition when a line is hit with a breakpoint tag on it. If the breakpoint is specified at a line and the condition is true, the debugger stops; otherwise, it keeps on going. For example, if you want the debugger to stop in xyc only when the global $reply is 1 , use this command:

b xyc ($reply == '1')

To list all breakpoints defined during a debug session, use the L command. If you issue unconditional breakpoints, you'll see breakpoints listed as this:

break if (1)

The L command will also list up to the last five executed lines of the program.

To remove a breakpoint, use the d command and specify the line number to delete. To remove all breakpoints, use the D command. For example, to delete a breakpoint at line 12, you would issue the command d 12 .

The DB package uses the following sequence to hit breakpoints and evaluate code on each line of executable code:

  1. Checks to see whether the breakpoint is defined at this line number. If there is no breakpoint defined for this line, it starts to process the next line. If there is a break-
    point at this line, the debugger prepares to stop. If the condition for the defined breakpoint is true, the debugger stops execution and presents a prompt to the user.
  2. Checks to see whether the line of code is printable. If so, it prints the entire line of code (including code spanning multiple lines).
  3. Checks to see whether there are any actions defined for this line and performs these actions. (An action is a set of Perl commands to be executed.)
  4. Checks to see whether the stop was due to a breakpoint. If the condition for the breakpoint is true and a breakpoint has been marked in this location, the debugger stops and presents a prompt for user interaction.
  5. Evaluates the line and gets ready to execute it. Gets user input if the user is stopping; otherwise, it executes the line and returns to item 1 in order to process the next line.

You can specify actions to take when a certain line of code is executed. This step is very important when you want to print out values as the program executes (see Figure 30.5). Notice how the value of reply is printed out when line 73 is reached. The action is defined with this statement:

Figure 30.5 : Using actions in the debugger.

a 73 print "I am on line 73 and reply is $reply"

Notice that you did not have to terminate the action command with a semicolon. You need to use semicolons only if you have more than one statement for an action. If you forget to supply the terminating semicolon, the debugger will supply it for you. In any event, try to keep actions simple and short. Don't write lengthy actions unless absolutely necessary; otherwise, you'll slow down the debugger and clutter up the output on your terminal.

Actions are not limited to displaying values. For instance, you can use an action to reset a variable to a known value while in a loop, using a statement like this:

a 73 $reply = 1; print "forced reply to 1\n";

To execute statements within the debugged program's space, simply type the command at the prompt. For example, to explicitly create and set the value of $kw to 2 in the code, use the following commands at the DB<> prompt:

DB<1> $kw = 2
... nothing is printed here ...
DB<1> print $kw
DB<1> V main kw
$kw = '2'

In this example, the variable $kw is created and defined in the program environment. You cannot modify the source code in the original program, but you can add items to the name space.

In some cases, your program may have redirected its output to STDOUT and therefore whatever it is printing will not be shown on the console. To evaluate an expression and print its value out to the console regardless of how STDOUT is redirected, you can use the p command. The p command evaluates an expression in the current program's environment and prints it out to the debugger console. Basically, the print command prints the output to wherever STDOUT is redirected, whereas the p command is equivalent to the following print command:

print DB::OUT

The command above forces output from a print command to where the DB:: package prints its output.

Searching for Patterns

To look for certain strings in the source code, you can use the forward slash command followed by the string to look for. Note that there are no spaces between the / and the string you are looking for. The string can be specified between two slashes, but the second slash is optional. Actually, you can search for regular expressions, just as in Perl.

To search forward in the file, use the / operator. To search backward, use the question mark operator ( ? ).

The history of the commands you have executed is tracked in the debugger. Only commands greater than one character long are listed in this directory. To execute commands from the history list, use the bang operator ( ! ) followed by the index of the command. To execute a command from the history, type ! and the index of the command to redo. This should be familiar to Bash and C shell programmers.

To see the current history of commands in the buffer of commands in the debugger, type the H command. For example, in the middle of a debug session, if you type in the H command at the DB<3> prompt, you should expect to see three items listed in reverse order of execution:

DB<3> H
3: b 79
2: w 2
1: w 9

To list all the subroutines currently in the system, use the S command. The output from the S command lists all subroutines in any package that your code uses. For example, if you run the program in Listing 30.2 with the debugger, you will see output as shown in Figure 30.6.

Figure 30.6 : Listing subroutine names.

Listing 30.2. A sample listing.
1 #!/usr/bin/perl -d
3 use VRML;
4 use VRML::Cube;
6 my $header = VRML::new();
7 $header->VRML::startHeader;
9 $header->VRML::startSeparator;
11 my $cubeb = $header->VRML::putCube(
12 'width' => 0.5, 'height' => 0.5 , 'depth' => 0.5 ,
13 'translation' => [1,0,0]
14 );
15 my $cubed = $header->VRML::putCube(
16 'width' => 1, 'height' => 1 , 'depth' => 1 ,
17 'translation' => [1,1,0],
18 );
19 $header->VRML::stopSeparator;

At any time in a debug session, you can do a "stack trace," which is a listing of the calling order of the functions called so far. Be aware that if you are modifying the argument stack in any way, the values of the passed arguments might not be correct. The T command will do a stack trace for you.


First of all, there is no way to restart the debugger if there is a problem. If you overstep something, you have to start all over. This means getting out of the program and restarting the debugger.

Second, the debugger itself is not completely debugged yet. If you notice certain problems, such as your commands not being recognized, it's probably because you typed too many characters at the prompt.

Table 30.1 lists the information about the available debugger commands. All information in this table is gleaned from the source file. Keep this table handy so that you don't have to go to the file to see what options are available.

Table 30.1. The commands available from the debugger.
Command Description
a [ ln ] command Sets an action to take before the line is executed.
b Sets an unconditional breakpoint at the current line.
b [ ln ] [ cond ] Sets a breakpoint if the condition is true at the specified line number.
b sname [ cond ] Sets a breakpoint at the first line inside the subroutine sname() .
c Continues until the next breakpoint or until the end of the program.
c line Continues and stops at the specified line.
d [ line ] Deletes the breakpoint at a given line.
D Deletes all breakpoints.
f filename Switches to the filename as the default.
H - number Displays history of all commands longer than one character.
L Lists all breakpoints and actions.
l min+incr Lists incr+1 lines starting at line #min .
l min-max Lists lines from min to max , inclusively.
l line Lists one line of code at a specified line.
l Lists the next 10 lines of code from the last location.
l name Lists a subroutine by name.
n Next code at the same level. Steps over subroutine calls.
p expr Same as print DB::OUT expr in current package.
q or ^D Quits. You cannot use quit .
r Returns from current subroutine.
s Single-step over code. Steps into subroutines.
S Lists all known subroutine names in the current scope.
t Toggles trace mode on and off.
T Performs a stack trace.
V Lists all variables in all used packages.
V pkg List all variables in a given package.
V pkg var Lists all variables in a package that have var in them.
w line Lists five lines before and five lines after current line.
<CR> Repeats last n or s .
- Lists the previous window.
/ regexp / Searches forward for a pattern using a regular expression.
? regexp ? Searches backward for a pattern using a regular expression.
< command Defines the command before the prompt.
> command Defines the command after the prompt.
! number Redoes a command (the default is the previous command).
! - number Redoes number\'th to the last command.
= [ alias value ] Starts a command alias.
= Lists all the current aliases.
command Executes as a Perl statement in the current package.
Customizing Your Debugger Environment

There are ways to customize your debugger environment. If you do not like the one-character commands that come with the debugger, you can use different aliases. There is a hash in the DB:: package called %alias() that contains the command strings. You can substitute your own commands in place of the existing ones using the = command. Since most of the time you'll want to keep your changes consistent between debug sessions, you can edit a file called .perldb in the current working directory and place the assignments there. Here's a sample .perldb file:

$DB::alias{'ln'} = 's/ln/p $1/';
$DB::alias{'z'} = 's/z/l/';

These two lines will substitute the value of p for every command ln you type, and the value of l for every z command. Of course, you'll probably want to alias long commands into short one-character sequences to save yourself some time.

Using the debugger should not be your only method for getting bugs out of the system. The -w switch is important if you want Perl to do checking and warn you of error conditions while executing. The types of messages generated vary from warnings to notifications of fatal errors that can cause the program to abort.

For More Information

Reading the source file gives you a few clues about how the debugger works and the commands that are available during a debug session. Consult the perldebug.html page at . This file contains the full list of all the options in the debug environment. Review the perldiag.html page for a list of possible diagnostic values you get from using the w switch.


Nothing really beats the use of well-placed print statements to do debugging. However, Perl does offer a simple yet powerful debugging tool with the -d option. The interactive debugger lets you step through code, into or over subroutines, set breakpoints, execute commands, and look at variables in a Perl program.

[Dec 20, 2017] chomp -

Notable quotes:
"... Note that parentheses are necessary ..."
Dec 20, 2017 |

chomp Perl functions A-Z | Perl functions by category | The 'perlfunc' manpage

[Dec 19, 2017] Perl IDE and Editor Poll, October 2009 - Which editor(s) or IDE(s) are you using for Perl development

Oct 01, 2009 |

In October 2009 we ran a poll asking people Which editor(s) or IDE(s) are you using for Perl development? . The poll was promoted via the blog of Gabor Szabo which is syndicated in several Perl related sites such as the Iron Man Challenge , Perlshpere and Planet Perl . It was also promoted via Twitter , the Perl group in Reddit , the Perl Mongers group in LinkedIn and the Perl Community Adserver to get more people to cast their vote. Request was also sent to the Perl Monger group leaders. Some of them have forwarded the request to their respective groups.

The list of editors was taken from the Perl Development Tools page on Perlmonks and the "randomize answers" checkbox was clicked after filling in the data. No idea if that really randomized the answers. During the poll people could mark other editors and type in the name of and editor. Some of these editors were added to the list of possible answers during the poll. In addition there were people who typed in the name of the editor in the other field even though the name appeared on the list.

At the begining we set the poll to allow multiple choice with up to 3 answers per person but later on we noticed that at one of the updates it became multiple choice unlimited answers. Unfortunatelly the free polling system we used gave details only on the number of answers and not the number of people who answered.

The poll ran between 21-24 October 2009 for about 72 hours. There were 3,234 answers when it was closed.

The results are as follows.
Vim (or vi or gvim) 1097 34%
Emacs (or xemacs, with or without extensions) 430 13%
Ultra Edit (plain or Studio) 224 7%
Eclipse EPIC 210 6%
Other answer... 143 4%
Notepad++ 142 4%
Komodo IDE 128 4%
Komodo Edit 105 3%
TextMate 105 3%
Padre 101 3%
Kate 56 2%
Gedit 55 2%
TextPad 49 2%
nano 40 1%
SciTE 38 1%
Geany 36 1%
NEdit 27 1%
mcedit 26 1%
EditPlus 26 1%
BBEdit 25 1%
JEdit 23 1%
Joe 20 1%
Smultron 16 0%
TextWrangler 14 0%
PSPad 12 0%
Notepad2 12 0%
Open Perl IDE 10 0%
OptiPerl 9 0%
Pico 7 0%
Jed 6 0%
Kephra 6 0%
SlickEdit 6 0%
KDevelop 6 0%
Notepad 5 0%
Crimson 4 0%
Anjuta 3 0%
EngInSite-Perl 3 0%
KEdit 3 0%
Perl Express 2 0%
DzSoft Perl 2 0%
PerlWiz 1 0%
Far 1 0%
Perl Studio 0 0%
Perl Builder 0 0%
Editeur 0 0%
Perl Code Editor 0 0%
ED for Windows 0 0%
PerlEdit 0 0%
FTE 0 0%
visiPerl+ 0 0%
Prof. Notepad 0 0%
Perl Scripting Tool 0 0%

[Dec 19, 2017] Programming in Perl - Debugging

Mar 13, 2007 |

On this page, I will post aides and tools that Perl provides which allow you to more efficently debug your Perl code. I will post updates as we cover material necessary for understanding the tools mentioned.

Dump is one of the functions exported in's :standard set. It's functionality is similar to that of Data::Dumper . Rather than pretty-printing a complex data structure, however, this module pretty-prints all of the parameters passed to your CGI script. That is to say that when called, it generates an HTML list of each parameter's name and value, so that you can see exactly what parameters were passed to your script. Don't forget that you must print the return value of this function - it doesn't do any printing on its own.
use CGI qw/:standard/;
print Dump;
As you know by now, one of Perl's mottos is "There's More Than One Way To Do It" (TMTOWTDI ©). This is usually a Good Thing, but can occasionally lead to confusion. One of the most common forms of confusion that Perl's verstaility causes is wondering which of multiple ways one should use to get the job done most quickly.

Analyzing two or more chunks of code to see how they compare time-wise is known as "Benchmarking". Perl provides a standard module that will Benchmark your code for you. It is named, unsurprisingly, Benchmark . Benchmark provides several helpful subroutines, but the most common is called cmpthese() . This subroutine takes two arguments: The number of iterations to run each method, and a hashref containing the code blocks (subroutines) you want to compare, keyed by a label for each block. It will run each subroutine the number of times specified, and then print out statistics telling you how they compare.

For example, my solution to ICA5 contained three different ways of creating a two dimensional array. Which one of these ways is "best"? Let's have Benchmark tell us:

use strict;
use warnings;
use Benchmark 'cmpthese';

sub explicit {
    my @two_d = ([ ('x') x 10 ],
                 [ ('x') x 10 ],
                 [ ('x') x 10 ],
                 [ ('x') x 10 ],
                 [ ('x') x 10 ]);

sub new_per_loop {
    my @two_d;
    for (0..4){
        my @inner = ('x') x 10;
        push @two_d, \@inner;

sub anon_ref_per_loop {
    my @two_d;
    for (0..4){
        push @two_d, [ ('x') x 10 ];

sub nested {
    my @two_d;
    for my $i (0..4){
        for my $j (0..9){
            $two_d[$i][$j] = 'x';
cmpthese (10_000, {
                 'Explicit'           => \&explicit,
                 'New Array Per Loop' => \&new_per_loop,
                 'Anon. Ref Per Loop' => \&anon_ref_per_loop,
                 'Nested Loops'       => \&nested,
The above code will print out the following statistics (numbers may be slightly off, of course):
Benchmark: timing 10000 iterations of Anon. Ref Per Loop, Explicit, Nested Loops, New Array Per Loop...
Anon. Ref Per Loop:  2 wallclock secs ( 1.53 usr +  0.00 sys =  1.53 CPU) @ 6535.95/s (n=10000)
Explicit:  1 wallclock secs ( 1.24 usr +  0.00 sys =  1.24 CPU) @ 8064.52/s (n=10000)
Nested Loops:  4 wallclock secs ( 4.01 usr +  0.00 sys =  4.01 CPU) @ 2493.77/s (n=10000)
New Array Per Loop:  2 wallclock secs ( 1.76 usr +  0.00 sys =  1.76 CPU) @ 5681.82/s (n=10000)
                     Rate Nested Loops New Array Per Loop Anon. Ref Per Loop Explicit
Nested Loops       2494/s           --               -56%               -62%     -69%
New Array Per Loop 5682/s         128%                 --               -13%     -30%
Anon. Ref Per Loop 6536/s         162%                15%                 --     -19%
Explicit           8065/s         223%                42%                23%       --

The benchmark first tells us how many iterations of which subroutines it's running. It then tells us how long each method took to run the given number of iterations. Finally, it prints out the statistics table, sorted from slowest to fastest. The Rate column tells us how many iterations each subroutine was able to perform per second. The remaining colums tells us how fast each method was in comparison to each of the other methods. (For example, 'Explicit' was 223% faster than 'Nested Loops', while 'New Array Per Loop' is 13% slower than 'Anon. Ref Per Loop'). From the above, we can see that 'Explicit' is by far the fastest of the four methods. It is, however, only 23% faster than 'Ref Per Loop', which requires far less typing and is much more easily maintainable (if your boss suddenly tells you he'd rather have the two-d array be 20x17, and each cell init'ed to 'X' rather than 'x', which of the two would you rather had been used?).

You can, of course, read more about this module, and see its other options, by reading: perldoc Benchmark

Command-line options
Perl provides several command-line options which make it possible to write very quick and very useful "one-liners". For more information on all the options available, refer to perldoc perlrun
This option takes a string and evaluates the Perl code within. This is the primary means of executing a one-liner
perl -e'print qq{Hello World\n};'
(In windows, you may have to use double-quotes rather than single. Either way, it's probably better to use q// and qq// within your one liner, rather than remembering to escape the quotes).
This option has two distinct effects that work in conjunction. First, it sets $\ (the output record terminator) to the current value of $/ (the input record separator). In effect, this means that every print statement will automatically have a newline appended. Secondly, it auto-chomps any input read via the <> operator, saving you the typing necessary to do it.
perl -le 'while (<>){ $_ .= q{testing};  print; }'
The above would automatically chomp $_, and then add the newline back on at the print statement, so that "testing" appears on the same line as the entered string.
This is the standard way to enable warnings in your one liners. This saves you from having to type use warnings;
This option auto- use s a given module.
perl -MData::Dumper -le'my @foo=(1..10); print Dumper(\@foo);'
This disturbingly powerful option wraps your entire one-liner in a while (<>) { ... } loop. That is, your one-liner will be executed once for each line of each file specified on the command line, each time setting $_ to the current line and $. to current line number.
perl -ne 'print if /^\d/' foo.txt beta.txt
The above one-line of code would loop through foo.txt and beta.txt, printing out all the lines that start with a digit. ($_ is assigned via the implicit while (<>) loop, and both print and m// operate on $_ if an explict argument isn't given).
This is essentially the same thing as -n , except that it places a continue { print; } block after the while (<>) { ... } loop in which your code is wrapped. This is useful for reading through a list of files, making some sort of modification, and printing the results.
perl -pe 's/Paul/John/' email.txt
Open the file email.txt, loop through each line, replacing any instance of "Paul" with "John", and print every line (modified or not) to STDOUT
This one sometimes astounds people that such a thing is possible with so little typing. -i is used in conjunction with either -n or -p. It causes the files specified on the command line to be edited "in-place", meaning that while you're looping through the lines of the files, all print statements are directed back to the original files. (That goes for both explicit print s, as well as the print in the continue block added by -p.)
If you give -i a string, this string will be used to create a back-up copy of the original file. Like so:
perl -pi.bkp -e's/Paul/John/' email.txt msg.txt
The above opens email.txt, replaces each line's instance of "Paul" with "John", and prints the results back to email.txt. The original email.txt is saved as email.txt.bkp. The same is then done for msg.txt

Remember that any of the command-line options listed here can also be given at the end of the shebang in non-one-liners. (But please do not start using -w in your real programs - use warnings; is still preferred because of its lexical scope and configurability).

The standard Data::Dumper module is very useful for examining exactly what is contained in your data structure (be it hash, array, or object (when we come to them) ). When you use this module, it exports one function, named Dumper . This function takes a reference to a data structure and returns a nicely formatted description of what that structure contains.
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my @foo = (5..10);
#add one element to the end of the array
#do you see the error?
$foo[@foo+1] = 'last';

print Dumper(\@foo);

When run, this program shows you exactly what is inside @foo:

$VAR1 = [

(I know we haven't covered references yet. For now, just accept my assertion that you create a reference by prepending the variable name with a backslash...)

__DATA__ & <DATA>
Perl uses the __DATA__ marker as a pseudo-datafile. You can use this marker to write quick tests which would involve finding a file name, opening that file, and reading from that file. If you just want to test a piece of code that requires a file to be read (but don't want to test the actual file opening and reading), place the data that would be in the input file under the __DATA__ marker. You can then read from this pseudo-file using <DATA>, without bothering to open an actual file:
#!/usr/bin/env perl
use strict;
use warnings;

while (my $line = <DATA>) {
  chomp $line;
  print "Size of line $.:  ", length $line, "\n";

hello world

The above program would print:

Size of line 1: 11
Size of line 2: 2
Size of line 3: 5
The $. variable keeps track of the line numbers of the file currently being processed via a while (<$fh>) { ... } loop. More explicitly, it is the number of the last line read of the last file read.
__FILE__ & __LINE__
These are two special markers that return, respectively, the name of the file Perl is currently executing, and the Line number where it resides. These can be used in your own debugging statements, to remind yourself where your outputs were in the source code:
  print "On line " . __LINE__ . " of file " . __FILE__ . ", \$foo = $foo\n";

Note that neither of these markers are variables, so they cannot be interpolated in a double-quoted string

warn() & die()
These are the most basic of all debugging techniques. warn() takes a list of strings, and prints them to STDERR. If the last element of the list does not end in a newline, warn() will also print the current filename and line number on which the warning occurred. Execution then proceeds as normal.

die() is identical to warn() , with one major exception - the program exits after printing the list of strings.

All debugging statements should make use of either warn() or die() rather than print() . This will insure you see your debugging output even if STDOUT has been redirected, and will give you the helpful clues of exactly where in your code the warning occurred.

[Dec 19, 2017] Open Perl IDE - User Manual

Dec 19, 2017 |

This section explains how to use Open Perl IDE for debugging.

Important: Open Perl IDE is not able to debug any scripts, if it does not know a path to "perl.exe". If the PATH environment variable contains a valid location, then "perl.exe" will be detected automatically. Otherwise it is necessary to enter a valid location into the "Preferences | General | Directories | Path to perl.exe" field.

There are two methods to debug a script:

After execution is stopped, it is possible to analyse the actual state of the script by Furthermore, it is possible to set/delete breakpoints (see section 5.1 Breakpoints) or to continue/abort the execution of the script. The following table shows the different navigation possibilities:

Table: Debug Navigation

Name Shortcut Description
Run F9 Start/Continue script execution until next breakpoint is reached.
Step Over F8 Execute the current script line, not tracing into subroutines.
Step Into F7 Execute the next command in the current script line, tracing into subroutines.
Abort CTRL-F2 Request termination of debug session.
Force Termination CTRL-ALT-F12 Immediately terminate debug session.
You should only use "Force Termination" if you see no other way to stop script execution. Dont't expect Open Perl IDE to work correctly after using forced termination !

If script execution has finished, then Open Perl IDE automatically switches back from debug mode to edit mode.

[Dec 19, 2017] Antibugging in Perl 7 Tips for Reducing Complexity

Notable quotes:
"... The complexity of a program is a function of several factors: ..."
Dec 19, 2017 |

"Complexity is the enemy, and our aim is to kill it." -Jan Baan

One of Perl's greatest strengths is its expressiveness and extreme conciseness. Complexity is the bane of software development: when a program grows beyond a certain size, it becomes much harder to test, maintain, read, or extend. Unfortunately, today's problems mean this is true for every program we need. Anything you can do to minimize the complexity of your program will pay handsome dividends.

The complexity of a program is a function of several factors:

Whenever a language allows you to change some code to reduce any of these factors, you reduce complexity.

3.7.1 Lose the Temporary Variables

The poster child for complexity is the temporary variable. Any time a language intrudes between you and the solution you visualize, it diminishes your ability to implement the solution. All languages do this to some degree; Perl less than most. 13 In most languages, you swap two variables a and b with the following algorithm:

Declare temp to be of the same type as a and b
temp = a;
a = b;
b = temp;

But most languages are not Perl:

($b, $a) = ($a, $b);

Iterating over an array usually requires an index variable and a count of how many things are currently stored in the array:

int i;
for (i = 0; i < count_lines; i++) 
 strcat (line[i], suffix);

Whereas in Perl, you have the foreach construct borrowed from the shell:

foreach my $line (@lines) { $line .= $suffix }

And if you