📜 ⬆️ ⬇️

Why Perl sucks?

Perhaps "sucks" is too gross a word, but by analogy with
"Why C sucks"
and
"Why C ++ sucks"
This is probably the appropriate heading.

First, let me say that Perl is currently my favorite language.
programming. I love his power, I love his elegance, and,
Most of all, I love its expressiveness. However, Perl,
certainly not without flaws.

The tone of this article is not intended to be negative. I think it will be useful for us to know.
about the weak points of used programming languages, especially popular ones,
so that we are sure that these weaknesses will not fall into other languages.
')
So here is my list of problems in Perl:

  1. No inheritance of objects.



    Perl inheritance is implemented through an ISA array (pronounced as
    "Is a", as in "this is a problem"), which allows you to call
    methods from one package through a bless link to another package.
    For example, if SomeClass contains SomeOtherClass in its global
    ISA array, then you can call any SomeOtherClass method directly
    via bless link in SomeClass.

    Unfortunately, there is no real way to inherit objects from
    another class in Perl, you can inherit only their methods. Usually
    the workaround used is from the constructor of the class that wants
    inherit, the constructor of the class that is inherited is called to
    get the object, add your own fields to the hash, and then
    Ove-bless-thread object into your class:

     package SomeClass;
     use SomeOtherClass;
    
     @ISA = 'SomeOtherClass';
    
     sub new {
    	 my $ class = shift;
    
    	 # create a new SomeOtherClass object:
    	 my $ self = $ class-> SUPER :: new;
    
    	 # mess with it:
    	 $ self -> {'_ something'} = 1;
    	 $ self -> {'_ something_else'} = 2;
    
    	 # now bless it into SomeClass:
    	 bless ($ self, $ class);
    	 return $ self;
     }
    
     one;
    


    The problem is that it violates the laws of encapsulation and
    abstraction: you need to know the details of the implementation of the object,
    which you inherit, and then you climb right inside and work with
    his fields directly. You can declare global variables in one
    package, write procedures to manipulate these variables, then
    inherit these procedures ... but it's all wrong.

    Given the countless number of object-oriented modules on
    CPAN is easy to forget that Perl was originally designed as a pure
    structured programming language. Such moments make it absolutely clear:
    OO in Perl is really nothing more than bless links and a little bit
    syntactic sugar.

    Reference count.



    Perl uses a reference counter for the garbage collector, an easy way
    memory management which guarantees timely release
    unused resources. Every scalar, array, hash, something else has
    built-in reference counter, which starts from one. Everytime,
    when a reference is created to this variable, the reference count
    increases. When the link is deleted, the counter decreases. At some
    the moment when the last link is deleted and the counter reaches zero,
    the memory used for this variable is released.
    The problem occurs when you have two variables referencing each other
    friend, like the parent hash and child hash, which both contain
    links to each other. Since nobody's counter can be reduced
    until zero until the last link is destroyed, one cannot be
    released until the second is released, and as a result they both remain
    hang in the memory. This is what is known as "circular links".
    (see additional information:
    http://www.perl.com/pub/a/2002/08/07/proxyobject.html
    ).

    This means that it is unexpectedly easy to fix Perl memory leaks.
    Many budding Perl hackers did this by chance. They thought:
    "Ha, it would be useful for this object to contain a reference to the parent,
    and vice versa, ”and, voila, a memory leak.

    Perl is definitely not alone in using the reference count: VB it
    uses, Python still uses it, as does PHP.

    Probably the greatest problem with link counters is the extra
    load on the authors of XS-extensions. Counters make them produce
    calls to SvREFCNT_inc () and SvREFCNT_dec () throughout the code, controlling what
    each SvREFCNT_inc () has a corresponding SvREFCNT_dec (). what
    leads me to the next annoyance ...

    Not an intuitive API.



    The Perl C API is pretty curious. First, there is no visible
    naming convention. Some procedure names are written in mixed
    case, for example newSViv (), while others contain
    underscore, for example newRV_noinc (). Many variable names and
    members of the structures have short, sometimes disorienting names, for example
    “Cur” for length and “len” for size.

    The API is also awash with macros, many of which are not documented.
    in perlapi or any other man pages, for example HvKEYS ().

    And, to make life even more interesting, for functions that
    documented, often not told whether they will change the counters
    references of their arguments.

    Non-intuitive array / list behavior in scalar context.



    I really don't like writing code with extra brackets like:

     my ($ first_field) = split (/ \ t /, $ tab_delimited_fields); 
    


    to interfere with the list or array returned from some function,
    behave wrong.

    In Perl, arrays return their size when used in scalar
    context and lists (eg "(70, 80, 90)" in the program text)
    return your last item. First, what for all
    introduced the difference between lists and arrays? Secondly, when and why
    I may need to use the list in scalar context
    to get his last item?

    I think it would be much better if both the arrays and the lists worked
    in the same way and returned the first element in a scalar context, instead of
    length or last item. Then it would be possible to write code like:

     my $ email_address = $ input = ~ / (\ S + \ @ \ S +) /; 
    


    and he would work.

    How, you ask, then get the size of the array? Well, why not with
    using the length () function? A lot of newbies suggest that this
    should work that way.

    Formats.



    Perl formats were supposedly “Report” part of
    "Practical Extraction and Report Language" - of course "Perl" is
    no longer an acronym, and when, honestly, you can remember that you
    used formats? In fact, can you even remember how
    use them correctly?

    This large, completely ignored part of Perl sucks in various ways.
    reasons.

    First, the format definition syntax is awkward (how about 20
    or so the characters "<" one-by-one?), global (you
    it will take a large, dotted block somewhere - more likely
    just under your code) and completely different from the usual
    syntax of Perl (increasing the likelihood that you will forget it, especially
    since you never used it).

    Secondly, an attempt to do something full using formats
    leads to verbosity, often requires the use of the select () function and
    messing with $ ^ before calling write (), forcing you to use three
    expressions to achieve what one would be enough for. (Four
    expressions if you count and restore select ().)

    Thirdly, all that formats can do is usually able to do and
    printf () with sprintf () ohm Even when the format syntax is really
    more flexible than printf (), using several printf () s is usually
    allows you to solve a problem, and this is a shorter and cleaner way.
    Perhaps the worst part of all this is that write () is used
    to output non-existent formats instead of executing I / O as read (),
    its English opposite:
    “Note that write is * not * the opposite of 'read'. Unfortunately. "

    from (perldoc -f write).

    No constants or macros.



    In fact, it should be two separate items, there is no Perl
    simple way to declare variables as constants or to define
    macros as an alternative to scattering magic numbers throughout
    code.

    Yes, Perl has the “constant” pragma that should do both, and
    another, but this is really just a hack; agile but elegant hack
    nevertheless hack:

     use constant PORT => 80;
    


    PORT can now be used as an rvalue in assignments, as if
    it would be something like a constant, and any attempt to assign something in
    It will cause a fatal error. But, you see, PORT is actually
    not a constant, it's just a function with a prototype "without arguments."
    You can still block it by redefining the function, or through
    “Use sub”, or directly through the symbol table.
    More importantly, one of the goals of constants is efficiency; to make
    life is easier for the compiler eliminating the need to assign
    something in the variable. Here, instead of a small win, perl,
    interpreter, gets an indecent performance hit.

    No type information.



    In Perl, scalars can contain either a value or a reference to a value.
    Unfortunately, Perl does not provide operators to find out what type
    "Value" contains a scalar, the operator is only to determine the type
    links. This results in, for example, determining whether
    scalar number suitable for arithmetic calculations unexpectedly
    complicated. Yes, I understand that we, Perl hackers, used to think that numbers
    and the strings are interchangeable, but the problem still arises, and is ridiculous
    seek help from regular expressions to determine:

     print "Not a number!"  unless ($ thing = ~ / ^ \ d + $ /); 
    


    Of course, this expression does not work very well, since numbers can
    contain other characters like "+", "-" or "." to indicate the sign
    fractional part or exponent.

    Even functions from ctype.h would be more useful than nothing.

    This is even more annoying because Perl seems to have
    A pretty good guess is what type of value is in SV (S-shny typedef
    describing the value of the scalar) based on the value of the "flags" field,
    and can easily convert one into the other if necessary.

    Autovivification.



    The key / value pairs autovivify hashes (comment of the translator: I do not know how
    in one word translate autovivify, meaning - “are created
    automatically, on the fly ") in Perl. This means that you can specify
    A new key of the type “autovived” and it will arise:

     my% hash = (key1 => 'value1', key2 => 'value2');
    
     $ hash {autovived} = 1;
    


    It also means that you can be sealed in the name of the key, and he too
    will occur without any warning. It is not big
    problem when you use hashes as dictionaries, because your keys
    often come from somewhere else, but when you use a hash like
    structure or object, this leads to problems:

     $ self = {
    	 name => undef,
             age => undef
    
     ...
    
     sub name {
     	 my $ self = shift;
    
     	 $ self -> {Name} = shift if @_;
    
     	 return $ self -> {name};
     }
    


    When I use hashes as objects, I always define and initialize
    each hash element inside the constructor is something at least “undef”.
    That only I would not give for the keyword "static", which would hurt
    New elements are added to the hash after initialization:

     static my $ self = {
     	 name => undef,
     	 age => undef
    
     ...
    
     $ self -> {Name} = shift;  # fatal error
    




    Other, weaker stimuli that come to mind include
    no equivalent for chop () before the line, impossibility to apply
    -x chained file tests (you need to write "-e $ filename && -T
    $ filename && -w $ filename "instead of" -e -T -w $ filename "or" -eTw $ filename "),
    strange convention to call binmode (), unstable signals,
    misleading names like local (), and the lack of the sizeof () function.

    This 16-year-old language has been steadily swelling for some time. Many his
    aspects become non-intuitive, ineffective, or simply ugly.
    Implementation is difficult to change, and adding new features
    without breaking old it becomes extremely difficult.

    Perl 6 is an attempt by the Perl community to fix many of these problems.
    The real object support will be added, the link count will go away,
    sigils ($, @,%) will be more intuitive, and many new features
    will be added.

    This top-down rewriting is still far from complete, but I,
    along with many others, eagerly waiting for him. Up to this point, I think, I
    I will continue to use Perl 5 to do most of my work.

Source: https://habr.com/ru/post/31074/


All Articles