RPerl Quick-Start Checklist & Guide
Restricted Perl, The Optimizing Perl 5 Compiler
RPerl is a compiler. For general info:
https://github.com/wbraswell/rperl/blob/master/README.md
http://rperl.org
Filename my_program.pl:
#!/usr/bin/env perl # My Program Name # My Program Description # [[[ PREPROCESSOR ]]] # <<< TYPE_CHECKING: TRACE >>> # [[[ HEADER ]]] use RPerl; use strict; use warnings; our $VERSION = 0.001_000; # [[[ CRITICS ]]] ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils ## no critic qw(ProhibitConstantPragma ProhibitMagicNumbers) # USER DEFAULT 3: allow constants # [[[ INCLUDES ]]] use My::FooPackage qw(foo_exported_ok); use My::BarClass; # [[[ CONSTANTS ]]] use constant PI => my number $TYPED_PI = 3.141_59; use constant PIE => my string $TYPED_PIE = 'pecan'; # [[[ SUBROUTINES ]]] sub pies_are_round { { my void $RETURN_TYPE }; print 'in pies_are_round(), having PIE() = ', PIE(), "\n"; return; } sub pi_r_squared { { my number $RETURN_TYPE }; ( my number $r ) = @ARG; my number $area = PI() * $r ** 2; print 'in pi_r_squared(), have $area = PI() * $r ** 2 = ', $area, "\n"; return $area; } # [[[ OPERATIONS ]]] pies_are_round(); my number $area = pi_r_squared(23.456_789); foo_exported_ok(42); print My::PackageFoo::foo_not_exported(3), "\n"; my My::BarClass $bar_object = My::BarClass->new(bar_number => 21.12, bar_string => 'howdy'); $bar_object->bar_method1(3); my number $bar_method2_retval = $bar_object->bar_method2(5);
$ rperl -V my_program.pl $ ./my_program
Filename My/FooPackage.pm:
# [[[ HEADER ]]] use RPerl; package My::FooPackage; use strict; use warnings; our $VERSION = 0.001_000; # [[[ EXPORTS ]]] use RPerl::Exporter qw(import); our @EXPORT_OK = qw(foo_exported_ok); # [[[ CRITICS ]]] ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils ## no critic qw(ProhibitConstantPragma ProhibitMagicNumbers) # USER DEFAULT 3: allow constants # [[[ INCLUDES ]]] use My::OtherPackage; # implementation left as an exercise for the user use My::OtherClass; # ditto # [[[ CONSTANTS ]]] use constant FOO_CONSTANT => my string $TYPED_FOO_CONSTANT = 'foo constant data'; # [[[ SUBROUTINES ]]] sub foo_exported_ok { { my void $RETURN_TYPE }; ( my integer $arg ) = @ARG; print 'in My::FooPackage::foo_exported_ok(), received $arg = ', $arg, "\n"; return; } sub foo_not_exported { { my string $RETURN_TYPE }; ( my integer $arg ) = @ARG; print 'in My::FooPackage::foo_exported_ok(), received $arg = ', $arg, "\n"; return('howdy' x $arg); } 1; # end of class
Filename My/BarClass.pm:
# [[[ HEADER ]]] use RPerl; package My::BarClass; use strict; use warnings; our $VERSION = 0.001_000; # [[[ OO INHERITANCE ]]] # RPerl base class, no inheritance; replace with parent class as needed use parent qw(RPerl::CompileUnit::Module::Class); use RPerl::CompileUnit::Module::Class; # [[[ CRITICS ]]] ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils ## no critic qw(ProhibitConstantPragma ProhibitMagicNumbers) # USER DEFAULT 3: allow constants # [[[ INCLUDES ]]] use My::OtherPackage; # implementation left as an exercise for the user use My::OtherClass; # ditto # [[[ CONSTANTS ]]] use constant BAR_CONSTANT => my string $TYPED_BAR_CONSTANT = 'bar constant data'; # [[[ OO PROPERTIES ]]] our hashref $properties = { bar_number => my integer $TYPED_bar_number = 42.23, bar_string => my string $TYPED_bar_string = 'default bar string data' }; # [[[ SUBROUTINES & OO METHODS ]]] sub bar_method1 { { my void::method $RETURN_TYPE }; ( my My::BarClass $self, my integer $arg ) = @ARG; print 'in My::BarClass->bar_method1(), received $arg = ', $arg, "\n"; print ($self->{bar_string} x $arg); } sub bar_method2 { { my number::method $RETURN_TYPE }; ( my My::BarClass $self, my integer $arg ) = @ARG; print 'in My::BarClass->bar_method2(), received $arg = ', $arg, "\n"; return($self->{bar_number} * $arg); } 1; # end of class
$ rperl -V My/FooPackage.pm My/BarClass.pm $ perl -e 'use My::FooPackage; use My::BarClass;'
1. File Formats, Programs & Modules: Follow Exact Syntax & Order In Synopsis Code Examples Above
2. Data Types, Constants & Variables & OO Properties: Always use constant PI => my number $TYPED_PI = 3.141_59; or my integer $foo; or our hashref $properties = { foo => my integer $TYPED_foo = 23, ...}; ; Never use constant PI => 3.141_59; or my $foo; or our $properties = { foo => 23, ...};
use constant PI => my number $TYPED_PI = 3.141_59;
my integer $foo;
our hashref $properties = { foo => my integer $TYPED_foo = 23, ...};
use constant PI => 3.141_59;
my $foo;
our $properties = { foo => 23, ...};
3. Return Types, Subroutines & OO Methods: Always sub foo {{ my integer $RETURN_TYPE }; ...} ; Never sub foo ($) {...} etc.
sub foo {{ my integer $RETURN_TYPE }; ...}
sub foo ($) {...}
4. Argument Types, Subroutines & OO Methods: Always ( my integer $arg1, my string $arg2, ... ) = @ARG; ; Never my $arg1 = shift; my $arg2 = shift;
( my integer $arg1, my string $arg2, ... ) = @ARG;
my $arg1 = shift; my $arg2 = shift;
5. Data Structures By Reference: Always my integer_arrayref $ar = [...]; & my integer_hashref $hr = {...}; ; Never my @a = (...); or my %h = (...);
my integer_arrayref $ar = [...];
my integer_hashref $hr = {...};
my @a = (...);
my %h = (...);
6. Lexical Variables: Always my integer $foo ; Never our $foo or state $foo etc.
my integer $foo
our $foo
state $foo
7. No Punctuation Variables: Never Use $_ or @_ or $! etc.
$_
@_
$!
8. Perl Critic: Always perlcritic --brutal my_program.pl or perlcritic --brutal MyModule.pm, Except For Specified & Allowed ## no critic Commands
perlcritic --brutal my_program.pl
perlcritic --brutal MyModule.pm
## no critic
9. No External Dependencies: Always Write Your Own Code & Only Load CPAN Modules From Non-Compiled Code; Never Directly Load Non-Compilable Code or CPAN Modules etc.
10. Pure Perl: Always Low-Magic Perl 5, Never XS or Non-Perl Code
RPerl currently supports a restricted subset of the Perl 5 programming language.
This Quick-Start Guide is meant to serve as a primer or companion for the much more in-depth textbook Learning RPerl.
Here are the most important things a Perl programmer needs to know to get started using RPerl immediately.
All RPerl program and module files must follow specific file formats, as shown in the Synopsis code examples.
"SYNOPSIS, PERL PROGRAM, INPUT CODE"
"SYNOPSIS, PERL MODULES, INPUT CODE"
The first line of Perl code in any RPerl file must be use RPerl;, after which the files must be organized into the proper format for 1 of 3 file types:
use RPerl;
You can see above that both packages and classes must use the *.pm file name suffix; they are compiled differently based on the presence a class' OO inheritance use parent qw(...); and OO properties our hashref $properties = {...};.
use parent qw(...);
our hashref $properties = {...};
If the OO inheritance and properties are not found, a *.pm file name is assumed to be a package and not a class.
The official RPerl file format templates are here:
Program Template
Package Template
Class Template
All RPerl constants, variables, subroutine & object method return values, and object properties must have an explicitly-specified scalar data type or non-scalar data structure.
"CHAPTER 2: SCALAR VALUES & VARIABLES (NUMBERS & TEXT)" in RPerl::Learning
RPerl provides 7 scalar data types:
boolean
unsigned_integer
integer (core)
integer
gmp_integer
number (core)
number
character
string (core)
string
Of the 7 RPerl scalar data types, 3 are directly (natively) supported by the Perl 5 core: integer, number, and string. This means the Perl 5 core is capable of directly identifying and storing those 3 core types. The remaining 4 non-core types are indirectly supported by the Perl 5 interpreter: boolean and unsigned_integer can be stored within either an integer or number; character can be stored within a string; and gmp_integer is supported by the use bigint; wrapper around the Math::BigInt::GMP module.
use bigint;
Math::BigInt::GMP
"CHAPTER 3: ARRAY VALUES & VARIABLES" in RPerl::Learning
For arrays with more than just a few elements, it may be impractical or impossible to pass by value, because a full copy of each array element must be made in the process, which may fill up all your program's available memory or take a prohibitively long time to complete. Also, Perl allows us to provide explicit data types only when an array is stored by reference, so we can not provide a data type for an array stored by value. Because of these reasons, all RPerl arrays are stored by reference, and are declared with an explicit RPerl data type ending with _arrayref.
_arrayref
my @foo_by_value = (2, 4, 6); # fine in normal Perl, error in RPerl my $foo_by_reference = [2, 4, 6]; # fine in normal Perl, error in RPerl my integer_arrayref $foo_by_reference_typed = [2, 4, 6]; # fine in normal Perl, fine in RPerl
In a few special cases, Perl forces us to provide an array by value instead of by reference, in which case we need to "dereference" our array variable, which is the process of converting from the stored-by-reference memory address to the stored-by-data values. This is achieved by use of Perl's closefix array dereference syntax, comprised of enclosing the scalar array variable within at-sign-curly-braces @{ }. Because all arrays in RPerl are stored by reference, only necessary uses of the dereference syntax are supported by the RPerl compiler. (Please see "Section 3.8: push & pop Operators" in RPerl::Learning for more information on pop.)
@{ }
push
pop
my integer_arrayref $foo_by_reference_typed = [10, 20, 30]; # fine in normal Perl, fine in RPerl my integer $foo_last_element = pop @{$foo_by_reference_typed}; # fine in normal Perl, fine in RPerl, necessary dereference my @foo_by_value = @{$foo_by_reference_typed}; # fine in normal Perl, error in RPerl, unnecessary dereference
In normal Perl, a single array may contain elements with multiple different data types, such as a three-element array containing one string and one integer and one floating-point number. In RPerl, a single array must contain elements of all the same data type, so you can have a three-element array with all strings, but you can't store an integer inside an array of strings, and likewise you can't store a string inside an array of integers, etc.
my integer_arrayref $foo = [5, 10, 15]; # fine my number_arrayref $bar = [5, 10, 15.5]; # fine my string_arrayref $bat = ['five', 'ten', 'fifteen']; # fine my integer_arrayref $foo = [5, 10, 15.5]; # error in RPerl, compiled modes my number_arrayref $bar = [5, 10, 'fifteen']; # error in RPerl, compiled modes my string_arrayref $bat = ['five', 'ten', 15]; # error in RPerl, compiled modes
You can create an array with only one element, sometimes called a "singleton"; you can even create an empty array with zero elements:
my integer_arrayref $foo = []; # zero elements, empty array my integer_arrayref $bar = [23]; # one element, singleton array
To display the contents of an array, you may utilize the *_arrayref_to_string() family of stringification subroutines:
*_arrayref_to_string()
my integer_arrayref $foo; $foo = [23, 42, 2_112]; print '$foo = ', integer_arrayref_to_string($foo), "\n";
Running the code example above generates the following output:
$foo = [23, 42, 2_112]
RPerl currently supports the following array stringification subroutines, with support for all RPerl array data types coming soon:
integer_arrayref_to_string()
number_arrayref_to_string()
string_arrayref_to_string()
# NEED ADD CONTENT!
rperl
Learning RPerl e-Book, POD Format
Learning RPerl e-Book, Web Format
The Low-Magic Perl Commandments
William N. Braswell, Jr.
mailto:wbraswell@NOSPAM.cpan.org
To install RPerl, copy and paste the appropriate command in to your terminal.
cpanm
cpanm RPerl
CPAN shell
perl -MCPAN -e shell install RPerl
For more information on module installation, please visit the detailed CPAN module installation guide.