Table of Contents
New Developers Working Group
The Perl Logic Layer
Structure
Most of Evergreen's business logic can be found in perl modules. In the git repository, these can be found at Open-ILS/src/perlmods/lib. Perl modules typically have the .pm file extension.
Evergreen's business logic is tested by the tests in Open-ILS/src/perlmods/t (which do not require the concerto data set to be running in the database) and Open-ILS/src/perlmods/live_t (which do). Perl tests have the .t file extension. The perl code is also exercised indirectly by the end-to-end tests for the Angular staff client.
There are many Perl scripts throughout the project. Perl scripts generally have the .pl file extension.
Dependencies
Evergreen's Perl code relies on many packages from CPAN. They are installed by your operating system's package manager and cpan itself when you run the Open-ILS/src/extras/Makefile.install Makefile. When you need to add or remove a dependency, do so for all of the operating systems listed in the Open-ILS/src/extras/install directory.
Checking your work
Here are some things you can do to check your work while working with Evergreen's perl code:
- If it is in an OpenSRF method: Build it, install it, and restart your services. Then call the method (through the UI, or directly using the srfsh). Confirm that the behavior is what you expected.
- To build and install the perl code, you can run
make
as opensrf thenmake install
as root. Alternatively, you can build and install the perl code in a single step withcd Open-ILS/src/perlmods && ./Build install
as root.
- Write some tests to confirm that your code is working as intended, without any unintended side effects.
- Run
perl -cw [name of file]
to check your syntax and check for warnings. - Run perlcritic on your code to check for common gotchas and readability. You can paste your code directly into the online PerlCritic checker or install the command line tool from CPAN. This is not a requirement (most perl code in Evergreen violates these rules), but it can be very instructive.
- Temporarily adding print or logging statements to your work. If you'd like to print an array or hash, try using Data::Dumper.
Using Cstore to interact with the database
A lot of the Perl code uses a Cstore editor to create, retrieve, update, delete, and search records in the database. The following examples are loosely based on the Carousel Perl module:
use strict; use warnings; use OpenILS::Utils::CStoreEditor qw/:funcs/; use OpenILS::Utils::Fieldmapper; ######### # Setup # ######### # Create a new Cstore editor my $e = new_editor(authtoken => $auth); # Check that the auth token is valid return $e->event unless $e->checkauth; # Check that the user has the ADMIN_CAROUSEL permission. # CStore doesn't perform any permission checks by itself, # so your Perl code needs to explicity do these checks. return $e->event unless $e->allowed('ADMIN_CAROUSEL'); ######################### # Create a new carousel # ######################### # Assemble a new fieldmapper object in memory my $carousel = Fieldmapper::container::carousel->new; $carousel->name('My carousel'); $carousel->type(1); $carousel->owner($e->requestor->ws_ou); $carousel->creator($e->requestor->id); $carousel->editor($e->requestor->id); $carousel->max_items(12); $carousel->bucket(30); # Then, start a transaction in the database. This is # required any time you are changing data in the database $e->xact_begin; # Persist the carousel to the database $e->create_container_carousel($carousel) or return $e->event; # Commit the transaction. It's a best practice to not leave # transactions open for a long time. $e->xact_commit or return $e->event; ############################# # Retrieve a carousel by ID # ############################# my $other_carousel = $e->retrieve_container_carousel(3); # Retrieve by id: 3 print "The other carousel name is $other_carousel->name"; ##################### # Update a carousel # ##################### # Again, make our changes in memory $carousel->bucket(40); # Open a transaction, persist our change to the database, and commit the transaction $e->xact_begin; $e->update_container_carousel($carousel) or return $e->event; $e->xact_commit or return $e->event; ##################### # Delete a carousel # ##################### # Similarly, open a transaction, call the delete method, and commit the transaction. # Note that the delete_container_carousel method accepts a Fieldmapper object, rather # than just an ID. So, if you only have an ID, you'll need to retrieve the object # from the database before you can delete it. $e->xact_begin; $e->delete_container_carousel($carousel) or return $e->event; $e->xact_commit or return $e->event; #################################### # Search carousels by field values # #################################### # No transaction needed, since we aren't making changes my $carousels_with_bucket_forty = $e->search_container_carousel( { bucket => 30 }); # The search_* methods return a reference. To access our actual data, we'll need to dereference by # putting the array sigil (@) in front of our variable name. for my $found_carousel (@$carousels_with_bucket_forty) { print $found_carousel->name; } # We can turn it back into a scalar to find the number of matching rows. my $matching_rows = scalar @$carousels_with_bucket_forty; # Perl critic recommends putting curly braces around the reference for clarity $matching_rows = scalar @{ $carousels_with_bucket_forty }; # You can also use the arrow operator and square brackets to get data directly from the array reference. print 'The name of the first carousel is: ' . $carousels_with_bucket_forty->[0]->name; 1;
Evergreen Conference Sessions
Further Reading
- Dereferencing in Perl from perlmeme.org