Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
#module request for those typing python myprogram.pl use DidYouMeanPython; # new error message "did you mean python?"
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: did you mean python
by Corion (Patriarch) on Jan 27, 2026 at 08:40 UTC | |
... as the code is run through the python3 interpreter, you will need to write a polyglot program that runs under Python as well as under Perl. Under Python, the program should compile (as not to raise a meaningless syntax error) but then output an error message, while under Perl, the program should run as-is. Ideally the Python implementation would restart the program under Perl. I can easily see a Python module import working, but I'm unsure about the compile-time / run-time semantics and implementation of Python, and whether the top unit must compile completely before imported code is run. The following code could work under Perl and Python:
This would be interpreted as valid Python code, importing the RunPerlCodeFromPython module. Under Perl, this would be interpreted as RunPerlCodeFromPython->import(). The problem is that Perl and Python syntax are largely incompatible and you need to find a good escape hatch to make the Python interpreter ignore all lines following this import. Maybe a cleverly crafted here-document can help there. | [reply] [d/l] [select] |
by harangzsolt33 (Deacon) on Jan 27, 2026 at 17:59 UTC | |
I would love to see something like that!!! That would be interesting! But how would one even begin something like that? I mean the first line in a perl program "#!/usr/bin/perl" prevents it from being interpreted as a python program. No? | [reply] |
by afoken (Chancellor) on Jan 28, 2026 at 13:21 UTC | |
I mean the first line in a perl program "#!/usr/bin/perl" prevents it from being interpreted as a python program. See perlrun: The shebang line does not have to be the first line in the file. You can make the perl interpreter skip a lot of lines in the file until it finds a line starting with "#!" and containing "perl". And the shebang line is not required at all. You can start your perl script right in the first line of a file, without a shebang line. Many operating systems don't use the shebang line at all, in fact, it is specific to the Unix family of operating systems. Other systems use file name extensions, file name prefixes, or some other mechanisms. Most other scripting languages, including Python, also do not need the shebang line. So, you can get a very simple polyglot program just like this:
Not very impressive, but it is both a valid Perl script and a valid Python script. The syntax is similar enough for this to work. Of course, things get more complicated if you want more than just "Hello World". That's where you need to be creative. Find a way for the two (three, four) languages to make them interpret the same text in a different way. Like this:
This is both a DOS batch file and a Perl script. DOS batches don't print lines starting with @ and ignore everything following rem. They also do not interpret lines that aren't executed. So for DOS, this is a non-printed comment (@rem), a non-printed command to disable printing (@echo off), a print statement (echo), a jump to a label at the end of the file, three lines that are not executed, and a jump label (:end). For Perl, this is an assignment of a multi-line string to the array @rem, followed by a print, followed by an end-of-script marker, followed by data which is not processed by this script. The assignment to @rem just wastes a little bit of RAM and CPU, but does nothing except skipping the DOS batch script. perlrun shows how a script can be both a (Unix) shell script and a perl script, where the former starts the latter. This trick is used to work around problems in ancient operating systems. A similar trick is used in Strawberry Perl, where batch files start embedded Perl scripts. And another little detail may be useful on Unix: If a text file is made executable, is invoked as a program, and the kernel won't find a shebang line as line 1 or some other file identifier, the shell will execute the text file as a shell script:
See also Re^2: Shebang behavior with perl. <Update> The perl interpreter has another little detail that might suprise you, but it is meant to be helpful:
If perl sees a shebang line for another interpreter, it happily replaces itself with the other interpreter. So even if this file is started via perl and has a .pl extension, it will be executed by /bin/bash. </Update> Alexander
-- Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-) | [reply] [d/l] [select] |
|
Re: did you mean python
by bliako (Abbot) on Jan 27, 2026 at 13:55 UTC | |
The main problem is that pyton and perl interpreters have different command line arguments and so detecting the script name is a pain. Otherwise, once you have the code, detecting computer language is a solved problem if avoiding the edges. My line of attack is to pass the whole CLI (edit: CLI means command-line params really) to a Perl diy interpreter which uses builtin CLI and script parsing (perl_parse()) to assess if the CLI and the provided script/one-liner parse as valid Perl CLI/Perl code. If it does not it passes the whole CLI to pyton via exec. This check is lame because if you intended to run Perl code which has syntax errors or your Perl CLI has errors then it will assume it is not Perl. This is better done by whipping our own Perl interpreter via perlembed and taking advantage of its builtin CLI and script parsing. Doing it via a Perl script is also possible following a similar approach using eval(). Well, hopefully this can ascend you a step or two in the PyAno process, leading to Liberation soon, bw bliako EDIT: usage: after compiling it: gcc python.c -o python `perl -MExtUtils::Embed -e ccopts -e ldopts`run it with a perl or python script or one-liner, using any valid switches for any of the two interpreters:
Note, the below program has been modified a couple of times already
| [reply] [d/l] [select] |
by Anonymous Monk on Jan 28, 2026 at 08:04 UTC | |
python.c:37:3: error: call to undeclared function 'execvpe'; ISO C99 and later do not support implicit function declarations -Wimplicit-function-declaration execvpe("/usr/bin/python", argv, env); ^ 1 error generated. | [reply] |
by bliako (Abbot) on Jan 28, 2026 at 12:39 UTC | |
Yes, execvpe() is a GNU extension. Replace said function and its params with this: execv("/usr/bin/python", argv); or add #define _GNU_SOURCE at the beginning if your compiler supports GNU extensions, e.g. gcc and I think clang. For M$ alternatives, good luck. P.S. You also need to adjust the (real) python path "/usr/bin/python" with whatever you have. And make sure that the real python executable does not shadow your newly created one. The new one must have precedence. That depends on your PATH env var and OS specific rules. P.S.2 The side-effect of this change would be that your current environment is not passed to the (real) python executable. I am not sure what happens if your python script expects env vars. Perhaps it will read the system-wide ones and ignore those session/terminal-specific ones you may have set earlier. | [reply] [d/l] [select] |
by Anonymous Monk on Jan 28, 2026 at 14:10 UTC | |
by bliako (Abbot) on Jan 28, 2026 at 19:41 UTC | |
by Anonymous Monk on Jan 29, 2026 at 04:01 UTC | |
| |
|
Re: did you mean python
by Jenda (Abbot) on Jan 30, 2026 at 01:52 UTC | |
Why? If you give either interpreter a script in the other language you end up with a syntax error right at the start and especially in case of a Perl script fed to python, the error is RIGHT at the use strict;. Do you really spend time reviewing the script to find out why do you get
Even if you did find a way to hide the rest of the python script from Perl and getting it to print that message AND a way to hide the rest of the Perl script from python and getting it to print the opposite message, there is no chance you'd consistently include that thing even in your own scripts. Besides on a well set system, you do not need to specify the interpreter. The right one is used either based on the shebang or the file extension. Jenda | [reply] [d/l] [select] |