Skip to content

Perl developer guide

Pavel Serikov edited this page May 2, 2017 · 16 revisions

Learn Perl in about 2 hours 30 minutes - http://qntm.org/files/perl/perl.html

General guidelines

http://perldoc.perl.org/index-tutorials.html

http://perldoc.perl.org/index-faq.html

https://www.reg.ru/coding_standards

OOP

https://metacpan.org/pod/distribution/perl/pod/perlootut.pod RUS

https://metacpan.org/pod/distribution/perl/pod/perlobj.pod

https://perlmaven.com/oop-with-moo

https://metacpan.org/pod/distribution/Moose/lib/Moose/Cookbook.pod

https://metacpan.org/pod/distribution/Moose/lib/Moose/Manual/Attributes.pod

Style

https://metacpan.org/pod/distribution/perl/pod/perlstyle.pod

https://metacpan.org/pod/distribution/Perl-Tidy/bin/perltidy

Mojolicious

https://habrahabr.ru/post/233991/

Module naming conventions

https://pause.perl.org/pause/query?ACTION=pause_namingmodules

Special variables

The @ISA array contains a list of that class's parent classes, if any

Other good learning resources

https://www.youtube.com/user/gabor529/videos

http://modernperlbooks.com/books/modern_perl_2016/07-object-oriented-perl.html

IDE recommendations

I recommend to use PyCharm Community Edition with Perl Plugin

It allow quicky:

  • jump to variable or function declaration (Ctr+B shortcut)
  • find a class by name (Ctrl+N)
  • auto-tidy and auto-indent source code before commit

Run tests before commit

dockerctl.sh prove

Useful perl modules for debug

Data::Dumper

E.g. you can STDOUT all input parameters of particular method:

sub list {
	my ($calendar, $span) = @_;
	warn "".(caller(0))[3]."() : ".Dumper \@_; # return a list, $calendar - first element, $span - second

Class::Inspector

Particular code guidelines

It's good idea to always pass arguments to new class or function as named hashes if arguments > 2. Named params are always better

So don't do like this (InstructorFSMController.pm)

sub new {
	my ($class, $user,
		$chat_id, $api,
		$instructors, $resources, $recordtimeparser) = @_;

	my $self = $class->SUPER::new($chat_id, $api); # init instance of parent class (BaseFSMController)
	$self->{instructor} = $instructors->name($user->{id});
	$self->{resources} = $resources;
	$self->{recordtimeparser} = $recordtimeparser;
	$self->{log} = Log->new("instructorfsmcontroller");

	$self;
}

So call of this method will be (FSMFactory.pm)

InstructorFSMController->new(
			$user,
			$chat_id,
			$self->{api},
			$self->{instructors},
			$self->{resources},
			$self->{recordtimeparser}));
}

When following style guide

sub new {
	my ($class, $params) = @_; # $params - hash with named parameters
	my $self = $class->SUPER::new($params->{chat_id}, $params->{api}); # init instance of parent class (BaseFSMController)
	$self->{instructor} = ($params->{instructors})->name($params->{user}{id});
	$self;
}

has recources;
has recordtimeparser;
has log => Log->new("instructorfsmcontroller");

# ...

InstructorFSMController->new(
	user => $user,
	chat_id => $chat_id,
	api => $self->{api},
	instructors => $self->{instructors},
	resources => $self->{resources},
	recordtimeparser => $self->{recordtimeparser}
);

Avoid such complex code

sub datetime_rule_instructor {
	my ($self, $state, $update) = @_;
	FSMUtils::_with_text($update, sub {
		FSMUtils::_parse_value($state, sub {
			$self->{dtf}->parse(shift);
		}, shift);
	});
}
Clone this wiki locally