-1

There are some perl files, which I have to convert them to python. Reading perl concepts and understanding.

some_file.pl

use Cwd qw(realpath cwd);
realpath( $0 ) =~ /(.+)\/[^\/]+$/;
require "some_other.pl";
use warnings;
use strict;

sub sub_routine1 {
    my ($a) = @_;
    # Do something
}

sub sub_routine2 {
    my ($b, $c) = @_;
    # Do something
}

sub sub_routine3 {
    my ($c, $d, $e) = @_;
    # do something
}

if (!caller) {
    # Variable decalarations
    # Do something
}
  1. In the above code, what does (!caller) mean ? How can I use that in python or any equivalent ?
  2. In second line, I guess it's matching reg-ex pattern. But what does this exactly mean realpath( $0 ) =~ /(.+)\/[^\/]+$/;
Fresher
  • 97
  • 2
  • 7
  • 1
    The second line is nonsense unless captured $1 is used afterwards. – mpapec Sep 13 '20 at 07:09
  • 2
    Please don't ask unrelated questions in the same Question. – ikegami Sep 13 '20 at 08:02
  • 2
    hmmm.... The second question was [asked very recently](https://stackoverflow.com/q/63772027/589924), and it was answered in detail too. So weird to get two people asking about the same badly-written code?! – ikegami Sep 13 '20 at 08:03
  • 1
    See also [Modulino: both script and module in Perl](https://perlmaven.com/modulino-both-script-and-module) – Håkon Hægland Sep 13 '20 at 09:25

3 Answers3

2

if (!caller) ... is the modulino pattern for Perl, used in dual-use source code files (a source code file that can either be incorporated into another script or run on its own). The equivalent pattern in Python is:

if __name__ == "__main__":
    ...
mob
  • 117,087
  • 18
  • 149
  • 283
1

caller is a built-in Perl function that returns information about the caller of a subroutine. perldoc -f caller or see here for more information.

caller returns undef (which is treated as false) if there is no caller -- i.e., if it's called from the top level of your script rather than from inside a subroutine. if (!caller) can be used in a Perl module to let it behave in one way if it's invoked directly, and to behave differently if it's invoked from another script or module.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • Thank yo, Keith. So, when i execute as "perl some_file.pl" , it directly invokes if "(!caller)" section, correct ? – Fresher Sep 14 '20 at 04:07
  • How does this script behave when invoked from another script ? When this "some_perl.pl" imported (require) in another perl script (let's say, test.pl). So, when executed test.pl, will it invoke "(!caller)" ? – Fresher Sep 14 '20 at 04:10
0

I'd highly recommend taking a chance to read through some of Perl's documentation as the regex operators are quite confusing/unintuitive at first.

Here are some things that might help:

https://perldoc.perl.org/perlrequick.html

https://perldoc.perl.org/perlretut.html

https://perldoc.perl.org/perlop.html

https://www.tutorialspoint.com/perl/perl_subroutines.htm

When we look at the line

realpath( $0 ) =~ /(.+)\/[^\/]+$/;

'$0' contains the name of the program being run, as given to the shell. If the program was run directly through the Perl interpreter, '$0' contains the file name. The backslash can perform one of two tasks: it either takes away the special meaning of the character following it (for instance, | matches a vertical bar, it's not an alternation), or it is the start of a backslash or escape sequence. The '.' is the concatenation operator, Perl's way of combining two or more things. So this statement is simply reading in the filepath.

Taking a look at:

https://perldoc.perl.org/functions/caller.html

Caller returns the context of the current pure perl subroutine call.

And so the following

if (!caller) {
    # Variable decalarations
    # Do something
}

is handling the case for whatever reason there are no subroutines running. Subroutines in Perl have to be called before they begin running. So this probably acts as a simple null check for when the file is called.

MFerguson
  • 1,739
  • 9
  • 17
  • 30
  • if '(!caller)' section is executed only when "some_file.pl" is run, is that correct ? – Fresher Sep 14 '20 at 04:18
  • will "if (!caller)" section be executed, if "some_file.pl" invoked from another script ? – Fresher Sep 14 '20 at 04:19
  • @Fresher It depends on the circumstances. I think that the other answers describing it as a dual-source code tool are exactly what it is used for. So if you wanted to call a specific subroutine in the file it wouldn't execute. If you called the entire file "some_file.pl" the "if (!caller)" would execute. – MFerguson Sep 14 '20 at 20:54
  • confusing. can you help me to understand better ? – Fresher Sep 14 '20 at 21:58
  • Since you are trying to convert the file to Python, just focus on doing it piece by piece. [This](https://medium.com/python-features/understanding-if-name-main-in-python-a37a3d4ab0c3) might help you understand @mob's suggestion to use __ name __ = "__ main __". You might also start by writing a simple program in Perl, then implementing some subroutines and calling them to get the hang of things. Once you understand that, porting it to python will be quite easy. If this is a school assignment I'd suggest reaching out to your professor for help if you aren't able to make any progress. – MFerguson Sep 15 '20 at 02:34