Skip to main content
Engineering LibreTexts

8.1: Packages — Groups of Classes and Methods

  • Page ID
    39612
    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    We have pointed out earlier (in Chapter : A First Application) packages are more or less a group of classes and methods. Now we will see exactly what the relationship is. The package system is a simple, lightweight way of organizing Pharo source code that exploits a simple naming convention.

    Let’s explain this using an example. Suppose that you are developing a framework to facilitate the use of relational databases from Pharo. You have decided to call your framework PharoLink, and have created a couple of classes such as OracleConnection, MySQLConnection, PostgresConnection but also DBTable, DBRow, DBQuery, and so on. These classes are placed inside a package called PharoLink. However, not all of your code will reside in these classes. For example, you may also have a series of methods to convert objects into an SQL-friendly format: Object>>#asSQL, String>>#asSQL, or Date>>#asSQL.

    These methods belong in the same package as the classes. But clearly the whole of class Object does not belong in your package! So you need a way of putting certain methods in a package, even though the rest of the class is in another package.

    The way that you do this is by placing those methods in a protocol (of Object, String, Date, and so on) named *PharoLink (note the initial asterisk). The *PharoLink protocols added to the package named PharoLink. To be precise, the rules for what goes in a package are as follows.

    A package named Foo contains:

    1. All class definitions of classes in the package Foo.
    2. All methods in any class in protocols named *Foo or *foo (When performing this comparison, the case of the letters in the names is ignored.), or whose name starts with *Foo- or *foo-.
    3. All methods in classes in the package Foo except for those methods in protocols whose names start with *: Because classes of package Foo can be also extended by other packages.

    A consequence of these rules is that each class definition and each method belongs to exactly one package.

    Accessing packages

    The class RPackage represents packages. The class RPackageOrganizer implements a singleton that holds all the Pharo packages. The following expressions are examples of the queries that you can perform.

    (RPackageOrganizer default packageNamed: 'AST-Core') definedClassNames
    (RPackageOrganizer default packageNamed: 'AST-Core') extendedClasses
    

    Basic Monticello

    When you open the Monticello browser, you will see two list panes and a row of buttons, as shown in Figure \(\PageIndex{1}\). The left-hand pane lists all of the packages that have been loaded into the image that you are running; the particular version of the package is shown in parentheses after the name.

    The Monticello Browser.
    Figure \(\PageIndex{1}\): The Monticello browser.

    The right-hand pane lists all of the source code repositories that Monticello knows about, usually because it has loaded code from them. If you select a package in the left pane, the right pane is filtered to show only those repositories that contain versions of the selected package.

    The package-cache

    One of the repositories is a directory named package-cache, which is a sub-directory of the directory in which your image is running. When you load code from or write code to a remote repository, a copy is also saved in the package cache. This can be useful if the network is not available and you need to access a package. Also, if you are given a Monticello (.mcz) file directly, for example as an email attachment, the most convenient way to access it is to place it in the package-cache directory.

    Adding repositories

    To add a new repository to the list, click the +Repository, and choose the kind of repository from the pop-up menu. Let’s add an HTTP repository.

    To do

    Open Monticello, click on +Repository, and select HTTP. Edit the dialog to read:

    MCHttpRepository
        location: 'http://squeaksource.com/PharoByExample'
        user: ''
        password: ''

    Click on Open to open a repository browser on this repository. You should see something like Figure \(\PageIndex{2}\). On the left is a list of all of the packages in the repository; if you select one, then the pane on the right will show all of the versions of the selected package in this repository.

    A Repository browser.
    Figure \(\PageIndex{2}\): A Repository browser.

    Browsing versions

    If you select one of the versions, you can Browse it (without loading it into your image), Load it, or look at the Changes that will be made to your image by loading the selected version. You can also make a Copy of a version of a package, which you can then write to another repository.

    As you can see, the names of versions contain the name of the package, the name of the author of the version, and a version number. The version name is also the name of the file in the repository. Never change these names; correct operation of Monticello depends on them! Monticello version files are just zip archives, and if you are curious you can unpack them with a zip tool, but the best way to look at their contents is using Monticello itself.

    Creating a package

    To create a package with Monticello, you have to do two things: write some code, and tell Monticello about it.

    To do

    Create a package called PBE, and put a couple of classes in it, as shown in Figure \(\PageIndex{3}\). Also, create a method in an existing class, such as Object, and put it in the same package as your classes – see Figure \(\PageIndex{4}\).

    Two classes and one extension.
    Figure \(\PageIndex{3}\): Two classes and one extension in the PBE package.
    An extension method that is also in the PBE package.
    Figure \(\PageIndex{4}\): An extension method that is also in the PBE package.

    Committing a package

    When you add a package via the class browser, Monticello automatically add the package to its list. PBE is now in list of packages; the package entry will be marked with an asterisk to show that the version in the image has not yet been written to any repository (It is said to be dirty).

    Initially, the only repository associated with this package will be your package cache, as shown in Figure \(\PageIndex{5}\). That’s OK: you can still save the code, which will cause it to be written to the package cache. Just click Save and you will be invited to provide a log message for the version of the package that you are about to save, as shown in Figure \(\PageIndex{6}\); when you accept the message, Monticello will save your package. To indicate this, the asterisk decorating the name in Monticello’s package pane will be removed, and the version number added.

    The unsaved PBE package in Monticello.
    Figure \(\PageIndex{5}\): The as-yet-unsaved PBE package in Monticello.
    Providing a log message for a new version of a package.
    Figure \(\PageIndex{6}\): Providing a log message for a new version of a package.

    Introducing a change

    If you then make a change to the package – say by adding a method to one of the classes – the asterisk will re-appear, showing that you have unsaved changes. If you open a repository browser on the package cache, you can select the saved version, and use Changes and the other buttons. You can of course save the new version to the repository too; once you Refresh the repository view, it should look like Figure \(\PageIndex{7}\).

    Two versions of a package in the cache.
    Figure \(\PageIndex{7}\): Two versions of our package are now in the package cache.

    To save the new package to a repository other than the package cache, you need to first make sure that Monticello knows about the repository, adding it if necessary. Then you can use the Copy in the package-cache repository browser, and select the repository to which the package should be copied. You can also associate the desired repository with the package by right-clicking on the repository and selecting add to package... and select the corresponding package. Once the package knows about a repository, you can save a new version by selecting the repository and the package in the Monticello Browser, and clicking Save. Of course, you must have permission to write to a repository. The PharoByExample repository on SqueakSource is world readable but not world writable, so if you try and save there, you will see an error message.

    However, you can create your own repository and save your code there. Nowadays the favorite code repositories are www.smalltalkhub.org and ss3.gemstone.com. This is especially useful as a mechanism to share your code with others and to make sure that you can use automated build systems such as Jenkins or Travis.

    If you do try and save to a repository where you don’t have write permission, a version will nevertheless be written to the package-cache. So you can recover by editing the repository information (right-click in the Monticello Browser) or choosing a different repository, and then using Copy from the package-cache browser.


    This page titled 8.1: Packages — Groups of Classes and Methods is shared under a CC BY-SA 3.0 license and was authored, remixed, and/or curated by via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.