📜 ⬆️ ⬇️

JAPH - Perl scripts that show what PERL is capable of in capable hands

[introduction]
Practically any programmer who has ever encountered the GREAT LANGUAGE OF PROGRAMMING - PERL, but does not write on it regularly, believes that it is very complex and confusing! Practically not understandable to the ordinary man in the street! With my article I would like to confirm this myth and tell about such a phenomenon as JAPH.

[climax]
JAPH is an abbreviation, stands for “Just Another Perl Hacker”, introduced into use in the distant 1990 by one widely known perl-hacker Randal Schwartz aka merlyn. “But what is perl about?” - you ask. The answer to this question is best of all with one of the most famous japhs, which, in my opinion, demonstrates the essence of this phenomenon!

print "Just another Perl hacker," if "you can't think of anything better..."

As soon as you run this code, you will see the word “Just another Perl hacker,” on the screen :-) (I would like to make a reservation right after the word “hacker.” As far as I know, it was in the first merlyn script. Probably, the author wanted to emphasize some incompleteness, to push those who see it to continue. Later, it disappeared :-)) Isn't it a strange script? It consists of only two operators! first print, and only then if, and not what; between them! It would seem that it should not work, but it works! and works correctly! In one line hidden two hacks, embedded in perl. The 1st is that in the conditional if statement, anything can be an argument and the condition will be true if the argument is not 0 or undef (an undefined value). The 2nd is the position of the if and print statements. If as a result of checking the condition in if'e one command should be executed, then it can be placed in the code before the if'm. This gives the code a more compact look. By the way, this form of record is valid for any operator conditions and listings.
This is one of the simplest examples of JAPH, there are more interesting ones:
')
''=~('('.'?' . '{'.(
'/'.'/'.')'.'.'.'/'.
'`'.'|'.'`'.'.'.'.'.
'/'.'`'.'`'.'.'.'/'.
'/'.'('.':'.'/'.'`'.
'~'.':'.'/'.','.'`'.
'`'.':'.'>'.'+'.':'.
'/'.'|'^'_'.']'.'@'.
'@'.'['.'@'.'['.'*'.
'['.']'.'['.'@'.'!'.
'@'.'@'.'['.'@'.'_'.
']'.'@'.'.'.'_'.']'.
'@'.'@'.'('.'['.']'.
'@'.'_'.']'.'[').','
.'$' .'/'.'}'.')' );

(Monolith by boo) This is a rectangle in which there are NO letters. Guess what this script displays? :-)
There are other interesting geometric shapes:


not exp log srand xor s qq qx xor
sxx length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq qq xor int
eval lc qm cos and print chr ord
for qw y abs ne open tied hex exp
ref ym xor scalar srand print qq
qq xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local xy or print qq
ss and eval qs undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return ys gt sin sort split

This is a famous square consisting of PERL keywords. Let's try to disassemble it in more detail. The first thing that catches the eye is repetitive XOR and AND, which, as you know, can replace; Now we can consider the output of spaces between the words: " print qq qq " " print qq qq " " print qq ss ". qq indicates that the sequence delimited by a delimiter is enclosed in double quotes. The separator here are the q and s characters. Now the code can be divided into four parts:

not exp log srand xor s qq qx xor
sxx length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq qq xor

int
eval lc qm cos and print chr ord
for qw y abs ne open tied hex exp
ref ym xor scalar srand print qq
qq xor

int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local xy or print qq
ss and

eval qs undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return ys gt sin sort split

Let's take a closer look at the first part: not exp log srand XOR will not display anything on the screen because there will always be a lie. s qq qx xor equivalent to s// / Thanks to this operation, the variable $ _ will be a space. The next part will look like this s/ /length uc ord and print chr ord for qw q join use sub tied q/ This operation will replace the space in the $ _ variable with the length uc ord and print chr ord for qw q join use sub tied q variable length uc ord and print chr ord for qw q join use sub tied q . length uc ord and always true, do not take into account. but print chr ord for qw q join use sub tied q just prints the word "just." This will become more visible if you convert to the following form: print chr ord for('join','use','sub','tied') . It works like this: for iterates over words from an array, ord gets the code of only the first character of each word, and chr is the inverse of the ord function, returns a character by code. Then eval will execute the contents of the $ _ variable (just print just), and print qq qq will print a space. The remaining parts are dealt with on the same principle.
There are japh'i in the form of various freakish figures:


Or from star wars fans :-)



[conclusion]
In general, the analysis of foreign japh'v good training, especially for beginners! Dare! And at http://www.cpan.org/misc/japh you can find a rather large collection for experiments and training ;-)

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


All Articles