[
  {
    "path": ".github/workflows/continuous.yml",
    "content": "name: Broken links\n\nenv:\n  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n# Controls when the action will run. Triggers the workflow on push or pull request\n# events but only for the development branch\non:\n  push:\n    branches:\n      - 'master'\n  pull_request:\n    types: [assigned, opened, synchronize, reopened]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v3\n    - name: Defining a new Environment Variable\n      run: |                          \n        TEMPFILES=$(ls **/*.md)    \n        echo \"FILES<<EOF\" >> $GITHUB_ENV\n        echo $TEMPFILES >> $GITHUB_ENV\n        echo \"EOF\" >> $GITHUB_ENV\n    - uses: docker://dkhamsing/awesome_bot:latest\n      with:\n        args: --white-list travis-ci,127.0.0.1,smalltalkhub.com/mc,github.com/MY_USERNAME/MY_PROJET_NAME --allow 403 --allow-dupe --allow-redirect --skip-save-results ${{ env.FILES }}\n"
  },
  {
    "path": ".gitignore",
    "content": "**/.DS_STORE\n"
  },
  {
    "path": "CONTRIBUTION.md",
    "content": "# Contribution guidlines\n\n  * [Suggest new pages](#suggest-new-pages)\n  * [Entries structure](#entries-structure)\n  * [Edit a page](#edit-a-page)\n  * [Add a new page](#add-a-new-page)\n  * [Deleting, Moving or Renaming a page](#deleting-moving-or-renaming-a-page)\n    + [If the content is obsolete](#if-the-content-is-obsolete)\n    + [If we want to move a page](#if-we-want-to-move-a-page)\n    + [If we want to split a page](#if-we-want-to-split-a-page)\n    + [If we want to rename a page](#if-we-want-to-rename-a-page)\n  * [Review content](#review-content)\n\n## Suggest new pages\n\nTo suggest pages that could fit the wiki, the recommended way is to open an issue containing a summary of the page, the section in which it should be (General, Internal projects of Pharo or External projects of Pharo) and optionaly links to already existing documentation on the projects.\n\nOn the language and environment part of the wiki we accept to document a part of the system that is already documented outside the wiki at the condition that we reference in a *See also* section those documentation. The goal is to have a centralized information and to provide alternative ways of explaining.\n\nIf you wish to add the new entry yourself, see section [Add a new page](#add-a-new-page).\n\n## Entries structure\n\nThe entries structure is free but we still have some conventions. \n\n* Documentation on external projects should mostly contains small example, comparaisons between multiple projects, links to official documentations and repositories. We can accept documentation on the external projects in case there is none by the official maintainer.\n* Long entries should begin with a table of content. We recommand [https://ecotrust-canada.github.io/markdown-toc/](https://ecotrust-canada.github.io/markdown-toc/).\n* References to external/decentralized documentation should be in a *See also* section at the end of the entry.\n* Smalltalk code snippets should use *tabulation* for source code indentation.\n* Smalltalk code snippets should be highlighted using this format:\n\n\n<pre>```Smalltalk\n Code\n```</pre>\n\n## Edit a page\n\nIf you see some typo, wrong informations or missing informations you can report it in the issues or you can also edit the document yourself and create a pull request.\n\nCreating a PR is as easy as clicking on the Edit (pen) button, updating the document and propose the changes.\n\n![Gif showing how to edit a page](Resources/EditPage.gif)\n\n## Add a new page\n\nIn order to add a page you can just go into the folder of the section where the page should be and use the \"Create new file button\".\n\n![Gif showing how to add a new page](Resources/CreatePage.gif)\n\nIf you need to integrate images in your entry, add them next to the Markdown file with an name following this pattern: `<NameOfThePage>_Image_<Description>.extension`. For example for an image illustrating `Iceberg` in a page called `VCS.md`, the image should be named `VCS_Image_IcebergIllustration.png`.\n\nOnce the page is created you need to add it to the [README.md](README.md) in the right section.\n\n> Note: If you have contents to start a page but don't have the time or the knowledge to finish it, it is advised to propose a pull request with the content you have already. Then, one can open issues with the missing sections pointing to the concerned page.\n\nAn entry in the README can also have a one short sentense explaining the purpose of the page.\n\nThe pages focus mainly on the latest stable Pharo version. This does not mean we refuse contribution on older or development version of Pharo, but those should be complement of the current stable version.\n\n## Deleting, Moving or Renaming a page\n\n**/!\\\\ We never delete a page. /!\\\\**\n\nThis is a rule in this wiki. What is more annoying than a 404 when we look for documentation?\n\nInstead we have different strategies depending on why we want to delete a page.\n\n### If the content is obsolete\n\nIf the content is obsolete, we do not delete the page but we add a note (using `> OBSOLETE : bla`) at the beginning explaining why the guide is obsolete. The guide can be removed from the README. \n\n### If we want to move a page\n\nIf we want to move a page, we can copy it to the new location and let the old page at the original location with an explanation and a link to the new page.\n\n### If we want to split a page\n\nSometimes a page is too big and would win to be splited. In that case the content can be extracted in multiple pages but the original page should stay and contains an index of the new pages.\n\n### If we want to rename a page\n\nIf we want to rename a page, we can copy it with the new name and let the old page at the original location with an explanation and a link to the new page.\n\n## Review content\n\nIt is really helpful to get reviews of the wiki's content. This can be achieved in multiple ways:\n- Review a Pull Request. Comments, approvals and changes request on pull request will help the intergation of new contents.\n- Open issues on existing entries.\n- Create a Pull Request to propose enhancements to an existing entry.\n"
  },
  {
    "path": "ExternalProjects/DataStructures/DataFrame.md",
    "content": "# DataFrame\n\n"
  },
  {
    "path": "ExternalProjects/Export/Arff.md",
    "content": "# Arff support in Pharo\nTo be done, talk about the [Arff parser/generator](https://github.com/juliendelplanque/Arff)\n"
  },
  {
    "path": "ExternalProjects/Export/CSV.md",
    "content": "# CSV support in Pharo\nCurrently, Pharo provides one main framework to handle the [CSV format](https://fr.wikipedia.org/wiki/Comma-separated_values): NeoCSV.\n\n## NeoCSV\nNeoJSON is actually maintained by Sven Van Caekenberghe on [github](https://github.com/svenvc/NeoCSV).\nThis section shows some quick examples but there is a great [documentation made by Sven](https://github.com/svenvc/docs/blob/master/neo/neo-csv-paper.md) and a chapter in [Enterprise Pharo (chapter 7)](http://books.pharo.org/enterprise-pharo/).\n\n> NeoCSV provides utilities to map Smalltalk objects to CSV lines, this page does not cover this topic to avoid duplication with the great documentation available in [Sven's documentation](https://github.com/svenvc/docs/blob/master/neo/neo-csv-paper.md) and [Enterprise Pharo (chapter 7)](http://books.pharo.org/enterprise-pharo/). Check it out if you need to use such feature!\n\n### Install\nTo install NeoCSV, simply execute the following code snippet in a playground:\n```Smalltalk\nMetacello new\n\trepository: 'github://svenvc/NeoCSV/repository';\n\tbaseline: 'NeoCSV';\n\tload\n```\n\n### Parse CSV\n- From `String`:\n```Smalltalk\nstr := 'id, name\n0, Julien\n1, Cyril\n2, Guillaume\n'.\nstr readStreamDo: [ :s |\n\t(NeoCSVReader on: s)\n\t\tskipHeader;\n\t\taddIntegerField;\n\t\taddField;\n\t\tupToEnd ]\n```\n\n- From `Stream`:\n```Smalltalk\nstream := 'id, name\n0, Julien\n1, Cyril\n2, Guillaume\n' readStream.\n\n(NeoCSVReader on: stream)\n\tskipHeader;\n\taddIntegerField;\n\taddField;\n\tupToEnd\n```\n\n- Read from CSV file:\n```Smalltalk\n'/path/to/file.csv' asFileReference\n\treadStreamDo: [ :readStream |\n\t\t(NeoCSVReader on: readStream)\n\t\t\tskipHeader;\n\t\t\taddIntegerField;\n\t\t\taddField;\n\t\t\tupToEnd ]\n```\n\n### Generate CSV\nLet `data` be defined as:\n```Smalltalk\ndata := #(\n(0 'Julien')\n(1 'Cyril')\n(2 'Guillaume')).\n```\n\n- To generate a CSV `String`:\n```Smalltalk\nString streamContents: [ :writeStream |\n\t(NeoCSVWriter on: writeStream)\n\t\twriteHeader: #(id name);\n\t\tnextPutAll: data ]\n```\n\n- To generate CSV on a `Stream`:\n```Smalltalk\n(NeoCSVWriter on: writeStream)\n\twriteHeader: #(id name);\n\tnextPutAll: data\n```\n\n- To write a CSV file:\n```Smalltalk\n'/path/to/file.csv' asFileReference\n\twriteStreamDo: [ :writeStream |\n\t\t(NeoCSVWriter on: writeStream)\n \t\t\twriteHeader: #(id name);\n\t\t\tnextPutAll: data ]\n```\n"
  },
  {
    "path": "ExternalProjects/Export/ESCP.md",
    "content": "# ESCP support in Pharo\nTo be done, talk about the [ESCP parser/generator](https://github.com/juliendelplanque/ESCP)\n"
  },
  {
    "path": "ExternalProjects/Export/HTML.md",
    "content": "# HTML support in Pharo\nTo be done, talk about HTML parser(s)\n\n- XMLParser-HTML\n\n- Soup ?\n"
  },
  {
    "path": "ExternalProjects/Export/JSON.md",
    "content": "# JSON support in Pharo\nCurrently, Pharo provides two main frameworks to handle the [JSON format](https://en.wikipedia.org/wiki/JSON).\n\nThis page briefly present these two frameworks and expose their differences to help users to choose the one fitting their needs.\n\n- [STONJSON](#stonjson)\n  * [Parse JSON](#parse-json)\n  * [Generate JSON](#generate-json)\n- [NeoJSON](#neojson)\n  * [Install](#install)\n  * [Parse JSON](#parse-json-1)\n  * [Generate JSON](#generate-json-1)\n- [STONJSON v.s. NeoJSON](#stonjson-vs-neojson)\n- [JSON Schema](#json-schema)\n\n## STONJSON\nSTONJSON is the built-in JSON parser available in default Pharo images. It is part of the STON package and its development takes place in Pharo's [github repository](https://github.com/pharo-project/pharo).\n\n### Parse JSON\n- From `String`:\n```Smalltalk\nSTONJSON fromString: '{ \"foo\" : 42.0 }' \"a Dictionary('foo'->42.0 )\"\n```\n\n- From `Stream`:\n```Smalltalk\nreadStream := '{ \"foo\" : 42.0 }' readStream.\nSTONJSON fromStream: readStream \"a Dictionary('foo'->42.0 )\"\n```\n\n- Read from JSON file:\n```Smalltalk\n'/path/to/file.json' asFileReference\n\treadStreamDo: [ :readStream |\n\t\tSTONJSON fromStream: readStream ] \"a Dictionary('foo'->42.0 )\"\n```\n\n### Generate JSON\n- Let `jsonObject` be defined as:\n```Smalltalk\njsonObject := Dictionary new\n\tat: 'foo' put: 42.0;\n\tyourself.\n```\n\n- To generate a JSON `String`:\n```Smalltalk\nSTONJSON toString: jsonObject \"'{\"\"foo\"\":42.0}'\"\n```\n\n- To generate JSON on a `Stream`:\n```Smalltalk\nSTONJSON put: jsonObject onStream: writeStream\n```\n\n- To write a JSON file:\n```Smalltalk\n'/path/to/file.json' asFileReference\n\twriteStreamDo: [ :writeStream |\n\t\tSTONJSON put: jsonObject onStream: writeStream ]\n```\n\nTo pretty print JSON, either use `STONJSON>>#toStringPretty:` or `STONJSON>>#put:onStreamPretty:`.\n\n## NeoJSON\nNeoJSON is actually maintained by Sven Van Caekenberghe on [github](https://github.com/svenvc/NeoJSON). \nThis section shows some quick examples but there is a great [documentation made by Sven](https://github.com/svenvc/docs/blob/master/neo/neo-json-paper.md) and a chapter in [Enterprise Pharo (chapter 8)](http://books.pharo.org/enterprise-pharo/).\n\n### Install\nTo install NeoJSON, simply execute the following code snippet in a playground:\n```\nMetacello new\n\trepository: 'github://svenvc/NeoJSON/repository';\n\tbaseline: 'NeoJSON';\n\tload\n```\n\n### Parse JSON\n\n- From `String`:\n```Smalltalk\nNeoJSONReader fromString: '{ \"foo\" : 42.0 }' \"a Dictionary('foo'->42.0 )\"\n```\n\n- From `Stream`:\n```Smalltalk\nreadStream := '{ \"foo\" : 42.0 }' readStream.\n(NeoJSONReader on: readStream) next\n```\n\n- Read from JSON file:\n```Smalltalk\n'/path/to/file.json' asFileReference\n\treadStreamDo: [ :readStream |\n\t\t(NeoJSONReader on: readStream) next ] \"a Dictionary('foo'->42.0 )\"\n```\n\n### Generate JSON\nLet `jsonObject` be defined as:\n```Smalltalk\njsonObject := Dictionary new\n\tat: 'foo' put: 42.0;\n\tyourself.\n```\n\n- To generate a JSON `String`:\n```Smalltalk\nNeoJSONWriter toString: jsonObject \"'{\"\"foo\"\":42.0}'\"\n```\n\nPretty:\n```Smalltalk\nNeoJSONWriter toStringPretty: jsonObject\n```\n\n- To generate JSON on a `Stream`:\n```Smalltalk\n(NeoJSONWriter on: writeStream)\n\tnextPut: jsonObject\n```\n\nPretty:\n```Smalltalk\n(NeoJSONWriter on: writeStream)\n\tprettyPrint: true;\n\tnextPut: jsonObject.\n```\n\n- To write a JSON file:\n```Smalltalk\n'/path/to/file.json' asFileReference\n\twriteStreamDo: [ :writeStream |\n\t\t(NeoJSONWriter on: writeStream)\n\t\t\tnextPut: jsonObject ]\n```\n\nPretty:\n```Smalltalk\n'/path/to/file.json' asFileReference\n\twriteStreamDo: [ :writeStream |\n\t\t(NeoJSONWriter on: writeStream)\n\t\t\tprettyPrint: true;\n\t\t\tnextPut: jsonObject ]\n```\n\n## STONJSON v.s. NeoJSON\n\n|Property                                        |STONJSON            |NeoJSON               |\n|------------------------------------------------|--------------------|----------------------|\n|Parse JSON                                      | :white_check_mark: | :white_check_mark:   |\n|Generate JSON                                   | :white_check_mark: | :white_check_mark:   |\n|Pretty-printing                                 | :white_check_mark: | :white_check_mark:   |\n|Built-in                                        | :white_check_mark: | :x:                  |\n|Facilities to map JSON objects to Pharo objects | :x:                | :white_check_mark:   |\n|Facilities to query JSON objects                | :x:                | :white_check_mark: * |\n\n> *See [this post](http://forum.world.st/How-to-query-a-JSON-tp4948175p4948177.html) from Sven on the mailing list to know how to use this feature implemented in `NeoJSONObject`.\n\n## JSON Schema\nJSON Schema allows to describes the structure of JSON objects. It is similar to [XML Schema](https://en.wikipedia.org/wiki/XML_Schema_(W3C)) but for JSON.\n\nA yet incomplete (but working in its scope) implementation of JSON Schema is provided by Zweidenker [on github](https://github.com/zweidenker/JSONSchema).\n"
  },
  {
    "path": "ExternalProjects/Export/XML.md",
    "content": "# XML support in Pharo\nTo be done, talk about XML parsers, XML model, XPath implementation, etc...\n"
  },
  {
    "path": "ExternalResources/Community.md",
    "content": "# Community\nThis page lists links to external resources created by members of Pharo (and sometimes other smalltalks) community.\nLinks are ranked in the lexicographic order which means that the position of a link in the list is not representative of the quality of the content.\n\nThis page exists for the sake of discoverability of Pharo community.\n\n**We do not take any responsibility for content published in these external resources as we have no control on it.**\n\n- [https://astares.blogspot.com](https://astares.blogspot.com) - Blog related to Pharo in general.\n- [https://blog.sebastiansastre.co](https://blog.sebastiansastre.co) - Blog related to Pharo in general.\n- [https://clementbera.wordpress.com](https://clementbera.wordpress.com) - Blog related to the Pharo virtual machine and its development.\n- [https://endormitoire.wordpress.com/2016/10/03/freewill-in-progress-4/](https://endormitoire.wordpress.com/2016/10/03/freewill-in-progress-4/) - Blog related to Pharo in general.\n- [https://fuhrmanator.github.io](https://fuhrmanator.github.io) - Blog related to Moose and Pharo in general but not only.\n- [https://masteringobjects.wordpress.com](https://masteringobjects.wordpress.com) - Blog related to Pharo development.\n- [https://medium.com/@i.oleks](https://medium.com/@i.oleks) - Blog related to Pharo, AI and machine learning.\n- [https://medium.com/concerning-pharo](https://medium.com/concerning-pharo) - Blog related to Pharo in general, multiple authors involved.\n- [https://medium.com/@juliendelplanque](https://medium.com/@juliendelplanque) - Blog related to Pharo in general.\n- [http://www.mirandabanda.org/cogblog/](http://www.mirandabanda.org/cogblog/) - Blog for open-smalltalk-vm.\n- [https://thiscontext.com](https://thiscontext.com) - Blog related to caffeine, a smalltalk vm in Javascript and other smalltalk topics.\n- [https://80738163270632.blogspot.com/] - Blog related to Pharo in general.\n"
  },
  {
    "path": "General/Baselines.md",
    "content": "# Baselines\n\nPharo projects often require a configuration to declare how they should be loaded. This configuration is done via **Baselines**. A baseline defines the packages of the project, their dependencies to each other and to external projects and independent sub-groups that can be loaded.\n\nAdding a baseline to a project has some advantages:\n- It makes it easier to load the project\n- It makes it easier for others to contribute to your project\n- It allows the users of the project to be unaware of the project's dependencies\n- It makes explicit the dependencies of the project\n- It ensures that packages and dependencies of the project are loaded in the right order\n\nThis documentation explains how to write a baseline and how to load the project described by this baseline.\n\n- [Baselines](#baselines)\n\t- [How to define Baselines](#how-to-define-baselines)\n\t\t- [Define packages forming your project](#define-packages-forming-your-project)\n\t\t- [Define external dependencies](#define-external-dependencies)\n\t\t\t- [To other remote git projects](#to-other-remote-git-projects)\n\t\t\t\t- [Depend on a subset of a git project](#depend-on-a-subset-of-a-git-project)\n\t\t\t\t- [Depends on the same project with different groups](#depends-on-the-same-project-with-different-groups)\n\t\t\t- [To a local git project](#to-a-local-git-project)\n\t\t\t- [To smalltalkhub projects](#to-smalltalkhub-projects)\n\t\t- [Groups](#groups)\n\t\t\t- [The default group](#the-default-group)\n\t\t- [Pre/post load actions](#prepost-load-actions)\n\t\t- [Loads different packages depending on the Pharo version](#loads-different-packages-depending-on-the-pharo-version)\n\t\t- [Define custom attributes](#define-custom-attributes)\n\t\t- [Loading types](#loading-types)\n\t\t\t- [Linear loading](#linear-loading)\n\t\t\t- [Atomic loading](#atomic-loading)\n\t\t- [Full example](#full-example)\n\t- [How to load a git project using its baseline](#how-to-load-a-git-project-using-its-baseline)\n\t\t- [From the playground](#from-the-playground)\n\t\t\t- [Project managed with Git](#project-managed-with-git)\n\t\t\t\t- [Project from github/gitlab/bitbucket](#project-from-githubgitlabbitbucket)\n\t\t\t\t- [Project from local repository](#project-from-local-repository)\n\t\t\t- [Project managed with Smalltalkhub](#project-managed-with-smalltalkhub)\n\t\t\t- [Project without repository](#project-without-repository)\n\t\t\t- [Loading groups](#loading-groups)\n\t\t\t- [Conflict, Upgrade and Downgrade resolution](#conflict-upgrade-and-downgrade-resolution)\n\t\t\t- [Manage warnings](#manage-warnings)\n\t\t- [From Iceberg](#from-iceberg)\n\t- [Other features](#other-features)\n\t\t- [Metacello lock feature](#metacello-lock-feature)\n\t\t- [Metacello get feature](#metacello-get-feature)\n\t\t- [Metacello fetch feature](#metacello-fetch-feature)\n\t\t- [Metacello record feature](#metacello-record-feature)\n\t\t- [Metacello listing feature](#metacello-listing-feature)\n\t- [See also](#see-also)\n\n## How to define Baselines\n\nThe first step to create a baseline is to create a new subclass of `BaselineOf`. In the following example, `MyProject` is to be substituted by the name of your project:\n\n```Smalltalk\nBaselineOf subclass: #BaselineOfMyProject\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'BaselineOfMyProject'\n```\n\nThis class should be in a package separated from other packages' projects. The package holding the baseline **must** have the same name as the baseline. To summarize, `BaselineOfMyProject` class is in the `BaselineOfMyProject` package.\n\nThen, create a method that defines the spec of the project for the commit it will be included in.\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"The main code of the baseline will go here\"\n\t\t]\n```\n\n> The name of this method does not have to be `#baseline:`; however, that is the name that is commonly used. In fact, it is the `<baseline>` pragma which specifies that the method defines the spec of the project.\n\nIf your project is stored using a metadataless format (Tonel or FileTree metadataless), which is the default since Pharo 6, you need to add this method to your baseline:\n\n```Smalltalk\nprojectClass\n\t^ MetacelloCypressBaselineProject\n```\n\nOr, if the project should be loadable in Pharo < 6.1, use this version:\n\n```Smalltalk\nprojectClass\n\t^ [ self class environment at: #MetacelloCypressBaselineProject ]\n\ton: NotFound\n\tdo: [ super projectClass ]\n```\n> The method is common to all projets using the metadataless format and the class return does not depend on the name of your baseline.\n\nThis will allow Metacello to be able to update your project and is needed because the default project class of Metacello used metadata to know if an update was needed.\n\n### Define packages forming your project\n\nTo define the packages of the project, send the message `#package:` to the spec with the name of the package as argument.\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests';\n\t\t\t\tpackage: 'MyProject-Gui';\n\t\t\t\tpackage: 'MyProject-Gui-Tests';\n\t\t\t\tpackage: 'MyProject-Examples' ]\n```\n\n> Note: Packages are the most atomic entities managed by the baseline. It is not possible to declare entities at the package-tag granularity.\n\nDefining packages is not enough to load them, because some of them might depend on other packages/projects. For example, `MyProject-Tests` needs to be loaded after `MyProject`.\n\nTo manage dependencies that are external to a project, see section *[Define external dependencies](#define-external-dependencies)*.\n\nFor dependencies between the packages of your project, you can use the message `#package:with:` to give more information to the spec.\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\t\tdo: [\n\t\t\t\t\"Packages\"\n\t\t\t\tspec\n\t\t\t\t\tpackage: 'MyProject';\n\t\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject') ];\n\t\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ]\n```\n\nThe method `#requires:` will define the list of dependencies of a specific package.\n\nAnother way to declare requirements is to use the method `#includes:`. This method takes a collection of declarations as a parameter and will notify Metacello that all of them should include the package if they are loaded. This is helpful when defining platform-specific requirements, in case we want one of our packages to come with a platform-dependant package, which is depending on this package. See example in section *[Loads different packages depending on the Pharo version](#loads-different-packages-depending-on-the-pharo-version)*.\n\n### Define external dependencies\n\nDefining external dependencies can be done in different ways depending on where the dependency is hosted.\n\n> To improve readability, I recommend extracting the definitions of dependencies into separate methods.\n\n#### To other remote git projects\n\nTo depend on a git project, you can use the method `#baseline:with:`.\n\n```Smalltalk\nspec\n\tbaseline: '{BaselineName}'\n\twith: [ spec repository: '{prefix}://{url}:{owner}/{projectName}:{version}/{subfolder}' ]\n```\n\nThis snippet should be configured with:\n\n- `{BaselineName}`: The name of the baseline to load (e.g, `'MaterialDesignLite'` to load `BaselineOfMaterialDesignLite`)\n- `{prefix}`: This is host-specific:\n  - `github` for github\n  - `bitbucket` for bitbucket\n  - `gitlab` for gitlab\n  - `git` for others (and {url} is thus mandatory)\n- `{url}`: Base url to the git host. Mandatory when prefix `git` is used, optional for other prefixes (can be useful for self hosted gitlab for example)\n- `{owner}`: Name of the user or organization hosting the project\n- `{projectName}`: Name of the project\n- `{version}`: This parameter is optional (defaults to master). It can be the name of a branch, a tag like `'v1.2.0'` or `'v1.x.x'`, or a the SHA of a commit\n- `{subfolder}`: This parameter is optional in case the code is not at the root of the project. It should point to the sub-folder containing the code\n\nExample:\n\n```Smalltalk\nspec\n\tbaseline: 'MaterialDesignLite'\n\twith: [ spec repository: 'github://DuneSt/MaterialDesignLite:v1.x.x/src']\n```\n\n##### Depend on a subset of a git project\n\nSome projects can defines `groups` in their baselines. They are subsets of the project that can be loaded independently.\nThe previous snippet can also be customized to load only a specific group of the dependency like this:\n\n\n```Smalltalk\nspec\n\tbaseline: 'MaterialDesignLite'\n\twith: [\n\t\tspec\n\t\tloads: #('Extensions');\n\t\trepository: 'github://DuneSt/MaterialDesignLite:v1.x.x/src'\n\t]\n```\n\nOnce the dependency is defined, add `BaselineName` to the list of the required dependencies of the package depending on it.\n\nExample:\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Dependencies\"\n\t\t\tself materialDesignLite: spec.\n\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject' 'MaterialDesignLite') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n```\n\n```Smalltalk\nmaterialDesignLite: spec\n\tspec\n\t\tbaseline: 'MaterialDesignLite'\n\t\twith: [\n\t\t\tspec  \n\t\t\t\tloads: #('Extensions');\n\t\t\t\trepository: 'github://DuneSt/MaterialDesignLite:v1.x.x/src'\n\t\t]\n```\n\n##### Depends on the same project with different groups\n\nIn some cases your project might depend on an external project, but two packages of your project depend on different groups of this external project.\n\nYou can use the message `#project:copyFrom:with:` to create a new dependency spec.\n\n```Smalltalk\nmaterialDesignLite: spec\n\tspec\n\t\tbaseline: 'MaterialDesignLite' with: [ spec repository: 'github://DuneSt/MaterialDesignLite:v1.x.x/src' ];\n\t\tproject: 'MaterialDesignLiteExtensions' copyFrom: 'MaterialDesignLite' with: [ spec loads: #('Extensions') ]\n```\n\nThen you can use the new project name in the specification of dependencies.\n\nExample:\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Dependencies\"\n\t\t\tself materialDesignLite: spec.\n\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject' 'MaterialDesignLiteExtensions') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests' 'MaterialDesignLite' \"We load the version containing MDL tests for our tests only\") ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n```\n\n```Smalltalk\nmaterialDesignLite: spec\n\tspec\n\t\tbaseline: 'MaterialDesignLite' with: [ spec repository: 'github://DuneSt/MaterialDesignLite:v1.x.x/src' ];\n\t\tproject: 'MaterialDesignLiteExtensions' copyFrom: 'MaterialDesignLite' with: [ spec loads: #('Extensions') ]\n```\n\n#### To a local git project\n\nSometimes we do not have access to a network, so we want to define dependencies to local git repositories.\n\nThis works like in the previous section, but with this repository format:\n\n```Smalltalk\nspec\n\tbaseline: 'MaterialDesignLite'\n\twith: [ spec repository: 'gitlocal://full/path/to/repository' ]\n```\n\n#### To smalltalkhub projects\n\nDepending on a [Smalltalkhub](http://smalltalkhub.com) project is done via `#project:with`.\n\n```Smalltalk\nspec\n\tproject: '{DependencyName}'\n\twith: [ spec\n\t\tclassName: #ConfigurationOf{ConfigurationName};\n\t\tversionString: #'{Version}';\n\t\trepository: 'http://smalltalkhub.com/mc/{owner}/{repositoryName}/main/' ]\n```\n\nThe snippet should be configured with:\n\n- `{DependencyName}`: It can be anything from your packages, groups and other dependencies names. It will be used to define dependency to this project in your packages/groups\n- `{ConfigurationName}`: It is the name of the configuration you wish to reference\n- `{Version}`: Name of the version you wish to reference. It can be something like `'development'`, `'stable'`, `'release1'`, `'1.2.6'`, `'1.0-baseline'`, etc.\n- `{owner}`: Name of the team or user hosting the project\n- `{repositoryName}`: Name of the repository on SmalltalkHub\n\nExample:\n\n```Smalltalk\nspec\n\tproject: 'Magritte3'\n\twith: [ spec\n\t\tclassName: #ConfigurationOfMagritte3;\n\t\tversionString: #'release3';\n\t\trepository: 'http://smalltalkhub.com/mc/Magritte/Magritte3/main/' ]\n```\n\nAs for git-hosted repositories, you can ask for a specific group:\n\n```Smalltalk\nspec\n\tproject: 'Magritte3'\n\twith: [ spec\n\t\tclassName: #ConfigurationOfMagritte3;\n\t\tversionString: #'release3';\n\t\tloads: #('Seaside');\n\t\trepository: 'http://smalltalkhub.com/mc/Magritte/Magritte3/main/' ]\n```\n\nYou can now use the dependency names to add the project as a dependency of your packages.\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Dependencies\"\n\t\t\tself magritte3: spec.\n\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject' 'Magritte3') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n```\n\n```Smalltalk\nmagritte3: spec\n\tspec\n\t\tproject: 'Magritte3'\n\t\twith: [ spec\n\t\t\tclassName: #ConfigurationOfMagritte3;\n\t\t\tversionString: #'release3';\n\t\t\tloads: #('Seaside');\n\t\t\trepository: 'http://smalltalkhub.com/mc/Magritte/Magritte3/main/' ]\n```\n\n### Groups\n\nSometimes we don't want to load the full project, but just a sub part, e.g.:\n\n- Only the model of a project is needed without the UI (for example to build an alternative UI)\n- Only the core of the project is needed without the tests and examples\n- The project has some optional modules\n- etc.\n\nTo manage such cases, baselines have the concept of a `Group`. A group is a loadable spec containing only a sub part of the project.\n\nThey can be declared with the `#group:with:` message. The second parameter defines the content of the group. The content can either be a package name, a dependency name, or even another group name.\n\nExample:\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n\n\t\t\t\"Groups\"\n\t\t\tspec\n\t\t\t\tgroup: 'Model' with: #('MyProject');\n\t\t\t\tgroup: 'Tests' with: #('MyProject-Tests' 'MyProject-Gui-Tests');\n\t\t\t\tgroup: 'Gui' with: #('MyProject-Gui');\n\t\t\t\tgroup: 'Example' with: #('MyProject-Examples');\n\t\t\t\tgroup: 'All' with: #('Model' 'Tests' 'Gui' 'Example')\n```\n\n> To load a project with a given group, you can check the section [loading groups](#loading-groups).\n\n#### The default group\n\nEach baseline has a default group named `'default'`. This group includes all the packages and the dependencies declared in the baseline.\n\nWhen using the message `#load` with Metacello, or when not specifying the group of a dependency, it will load the \"default\" group.\n\nThis group can be redefined to change what will be loaded by default in a project.\n\nExample:\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n\n\t\t\t\"Groups\"\n\t\t\tspec\n\t\t\t\tgroup: 'default' with: #('Model' 'Gui');\n\t\t\t\tgroup: 'Model' with: #('MyProject');\n\t\t\t\tgroup: 'Tests' with: #('MyProject-Tests' 'MyProject-Gui-Tests');\n\t\t\t\tgroup: 'Gui' with: #('MyProject-Gui');\n\t\t\t\tgroup: 'Example' with: #('MyProject-Examples');\n\t\t\t\tgroup: 'All' with: #('Model' 'Tests' 'Gui' 'Example')\n```\n\n### Pre/post load actions\n\nBaselines provide some hooks to execute some code when loading a project.\n\nThose hooks are:\n\n- `#preLoadDoIt:` which is executed after the code and dependencies are resolved and fetched, but before the code is loaded.\n- `#postLoadDoIt:` which is executed when the project finishes loading.\n\nThose methods take a symbol as parameter, which should be the name of a method of the baseline that should be executed by the hook.\n\nThose methods can take two optional parameters:\n\n- A Metacello loader containing information on the current project to load\n- A Metacello spec containing information on the project spec\n\nExample:\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\tspec preLoadDoIt: #'preload:package:'.\n\t\t\tspec postLoadDoIt: #'postload:package:'.\n\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ]\n```\n\n```Smalltalk\npreload: loader package: packageSpec\n\n\tTranscript crLog: 'The fetch was finished. Now let''s load the project'\n```\n\n```Smalltalk\npostload: loader package: packageSpec\n\n\tTranscript crLog: 'Project loaded!'\n```\n\n### Loads different packages depending on the Pharo version\n\nIt might be useful to load some packages in specific Pharo versions only. For example, if we have a compatibility package for Pharo 6, we do not want to load it in Pharo 7.\n\nThis is possible with the different spec attributes.\n\nUp until now we defined everything in a spec for `#common`, which applies to all versions of Pharo. But it's possible to define a spec for specific Pharo versions or even other Smalltalk environments.\n\nWe can add in the baseline a special `#for:do:` command taking as parameter a specific attribute.\n\nEvery Pharo version contains some default attributes. For a Pharo version X.Y we have:\n\n- `#pharo`\n- `#pharoX.x`\n- `#pharoX.Y.x`\n\nFor example for Pharo 6.1:\n\n- `#pharo`\n- `#pharo6.x`\n- `#pharo6.1.x`\n\nThose attributes can be used to define a spec that will be executed only in the images containing the corresponding tags.\n\nExample:\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n\n\t\t\tspec\n\t\t\t\tfor: #'pharo6.x'\n\t\t\t\tdo: [ spec\n\t\t\t\t\tpackage: 'MyProject' with: [ spec requires: #('MyProject-Pharo6') ];\n\t\t\t\t\tpackage: 'MyProject-Pharo6' ].\n\t\t\tspec\n\t\t\t\tfor: #(#'pharo3.x' #'pharo4.x' #'pharo5.x' #'pharo6.x')\n\t\t\t\tdo: [ spec\n\t\t\t\t\tpackage: 'MyProject' with: [ spec requires: #('MyProject-Pharo3To6') ];\n\t\t\t\t\tpackage: 'MyProject-Pharo3To6' ] ]\n```\n\nThe `#includes:` method explained in section *[Define packages forming your project](#define-packages-forming-your-project)* is often useful when dealing with platform-specific requirements. Imagine your package `MyProject` will work in Pharo 6 only if `MyProject-Pharo6` is present, but `MyProject-Pharo6` depends on `MyProject`. This can be resolved like this:\n\nExample:\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n\n\t\t\tspec\n\t\t\t\tfor: #'pharo6.x'\n\t\t\t\tdo: [ spec\n\t\t\t\t\tpackage: 'MyProject' with: [ spec includes: #('MyProject-Pharo6') ];\n\t\t\t\t\tpackage: 'MyProject-Pharo6' with: [ spec requires: #('MyProject') ] ].\n\t\t\tspec\n\t\t\t\tfor: #(#'pharo3.x' #'pharo4.x' #'pharo5.x' #'pharo6.x')\n\t\t\t\tdo: [ spec\n\t\t\t\t\tpackage: 'MyProject' with: [ spec requires: #('MyProject-Pharo3To6') ];\n\t\t\t\t\tpackage: 'MyProject-Pharo3To6' ] ]\n```\n\n### Define custom attributes\n\nOn top of attributes from Pharo, it's also possible to define our own attributes.\n\nWe override the method `#customProjectAttributes` to return the custom attributes depending on the environment.\n\nFor example:\n\n```Smalltalk\ncustomProjectAttributes\n\tSmalltalk os isMacOS ifTrue: [ ^ #(#MacOS) ].\n\tSmalltalk os isUnix ifTrue: [ ^ #(#Unix) ].\n\tSmalltalk os isWindows ifTrue: [ ^ #(#Windows) ]\n```\n\nThen they can be used in the baseline.\n\n```Smalltalk\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests') ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ] ].\n\n\t\t\tspec\n\t\t\t\tfor: #(#'MacOS' #'Unix') do: [\n\t\t\t\t\tself osSubprocess: spec.\n\t\t\t\t\tspec package: 'MyProject' with: [ spec requires: #('OSSubprocess') ] ];\n\t\t\t\tfor: #'Windows' do: [\n\t\t\t\t\tself processWrapper: spec.\n\t\t\t\t\tspec package: 'MyProject' with: [ spec requires: #('ProcessWrapper') ] ]\n```\n\n```Smalltalk\nosSubprocess: spec\n\tspec\n\t\tbaseline: 'OSSubprocess'\n\t\twith: [ spec repository: 'github://pharo-contributions/OSSubprocess:v1.0.1/repository' ]\n```\n\n```Smalltalk\nprocessWrapper: spec\n\tspec \n\t\tconfiguration: 'ProcessWrapper'\n\t\twith: [\n\t\t\tspec\n\t\t\t\tversionString: '1.2';\n\t\t\t\trepository: 'http://smalltalkhub.com/mc/hernan/ProcessWrapper/main' ]\n```\n\n### Loading types\n\nBaselines support different loading types. The loading types define how Metacello loads the project.\n\n#### Linear loading\n\nBy default, a baseline uses linear loading, which means packages are loaded one by one with their requirements loaded before them.\n\n#### Atomic loading\n\nThis load type forces Metacello to load the full project in an atomic load. This is useful when a project has cyclic dependencies that cannot be resolved. For example it's useful to do an atomic load of Pharo's Kernel and Collections, since they depend on each other.\n\nTo define atomic loading, override the method `#project`:\n\n```Smalltalk\nproject\n\t^ super project\n\t\tloadType: #atomic;\n\t\tyourself\n```\n\n### Full example\n\nHere is an example with all previous features illustrated:\n\n```Smalltalk\n\"baseline\"\nbaseline: spec\n\t<baseline>\n\tspec\n\t\tfor: #common\n\t\tdo: [\n\t\t\tspec preLoadDoIt: #'preload:package:'.\n\t\t\tspec postLoadDoIt: #'postload:package:'.\n\n\t\t\t\"Dependencies\"\n\t\t\tself materialDesignLite: spec.\n\n\t\t\t\"Packages\"\n\t\t\tspec\n\t\t\t\tpackage: 'MyProject';\n\t\t\t\tpackage: 'MyProject-Tests' with: [ spec requires: #('MyProject') ];\n\t\t\t\tpackage: 'MyProject-Gui' with: [ spec requires: #('MyProject' 'MaterialDesignLiteExtensions' 'Magritte3') ];\n\t\t\t\tpackage: 'MyProject-Gui-Tests' with: [ spec requires: #('MyProject-Tests' 'MaterialDesignLite' \"We load the version containing MDL tests for our tests only\") ];\n\t\t\t\tpackage: 'MyProject-Examples' with: [ spec requires: #('MyProject-Gui') ].\n\n\t\t\t\"Groups\"\n\t\t\tspec\n\t\t\t\tgroup: 'Model' with: #('MyProject');\n\t\t\t\tgroup: 'Tests' with: #('MyProject-Tests' 'MyProject-Gui-Tests');\n\t\t\t\tgroup: 'Gui' with: #('MyProject-Gui');\n\t\t\t\tgroup: 'Example' with: #('MyProject-Examples');\n\t\t\t\tgroup: 'All' with: #('Model' 'Tests' 'Gui' 'Example') ].\n\n\t\t\tspec\n\t\t\t\tfor: #'pharo6.x'\n\t\t\t\tdo: [ spec\n\t\t\t\t\tpackage: 'MyProject' with: [ spec includes: #('MyProject-Pharo6') ];\n\t\t\t\t\tpackage: 'MyProject-Pharo6' with: [ spec requires: #('MyProject') ] ].\n\n\t\t\tspec\n\t\t\t\tfor: #(#'pharo3.x' #'pharo4.x' #'pharo5.x' #'pharo6.x')\n\t\t\t\tdo: [ spec\n\t\t\t\t\tpackage: 'MyProject' with: [ spec requires: #('MyProject-Pharo3To6') ];\n\t\t\t\t\tpackage: 'MyProject-Pharo3To6' ] ].\n\n\t\t\tspec\n\t\t\t\tfor: #(#'MacOS' #'Unix') do: [\n\t\t\t\t\tself osSubprocess: spec.\n\t\t\t\t\tspec package: 'MyProject' with: [ spec requires: #('OSSubprocess') ] ].\n\n\t\t\tspec\n\t\t\t\tfor: #'Windows' do: [\n\t\t\t\t\tself processWrapper: spec.\n\t\t\t\t\tspec package: 'MyProject' with: [ spec requires: #('ProcessWrapper') ] ]\n```\n\n```Smalltalk\nprojectClass\n\t^ MetacelloCypressBaselineProject\n```\n\n```Smalltalk\n\"dependencies\"\nmaterialDesignLite: spec\n\tspec\n\t\tbaseline: 'MaterialDesignLite' with: [ spec repository: 'github://DuneSt/MaterialDesignLite:v1.x.x/src' ];\n\t\tproject: 'MaterialDesignLiteExtensions' copyFrom: 'MaterialDesignLite' with: [ spec loads: #('Extensions') ]\n```\n\n```Smalltalk\n\"dependencies\"\nmagritte3: spec\n\tspec\n\t\tproject: 'Magritte3'\n\t\twith: [ spec\n\t\t\tclassName: #ConfigurationOfMagritte3;\n\t\t\tversionString: #'release3';\n\t\t\tloads: #('Seaside');\n\t\t\trepository: 'http://smalltalkhub.com/mc/Magritte/Magritte3/main/' ]\n```\n\n```Smalltalk\n\"dependencies\"\nosSubprocess: spec\n\tspec\n\t\tbaseline: 'OSSubprocess'\n\t\twith: [ spec repository: 'github://pharo-contributions/OSSubprocess:v1.0.1/repository' ]\n```\n\n```Smalltalk\n\"dependencies\"\nprocessWrapper: spec\n\tspec\n\t\tconfiguration: 'ProcessWrapper'\n\t\twith: [\n\t\t\tspec\n\t\t\t\tversionString: '1.2';\n\t\t\t\trepository: 'http://smalltalkhub.com/mc/hernan/ProcessWrapper/main' ]\n```\n\n```Smalltalk\n\"accessing\"\ncustomProjectAttributes\n\tSmalltalk os isMacOS ifTrue: [ ^ #(#MacOS) ].\n\tSmalltalk os isUnix ifTrue: [ ^ #(#Unix) ].\n\tSmalltalk os isWindows ifTrue: [ ^ #(#Windows) ]\n```\n\n```Smalltalk\n\"actions\"\npreload: loader package: packageSpec\n\n\tTranscript crLog: 'The fetch was finished. Now let''s load the project'\n```\n\n```Smalltalk\n\"actions\"\npostload: loader package: packageSpec\n\n\tTranscript crLog: 'Project loaded!'\n```\n\n```Smalltalk\n\"accessing\"\nproject\n\t^ super project\n\t\tloadType: #atomic;\n\t\tyourself\n```\n\n## How to load a git project using its baseline\n\nWhen you have a project with a *Baseline*, it is possible to load it in a Pharo image if the project is compatible with the Pharo version.\n\nHere we explain how to load a git project via its baseline.\n\n### From the playground\n\nThe first way to load a project is to create a *Metacello* request programmatically and to execute it. This request looks like this:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.x.x' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tload\n```\n\nNote the three steps:\n\n1. Create a new Metacello request\n2. Configure it (declare the repository of the project, specify the version, the baseline, optional options...)\n3. Launch the loading\n\nTo configure the request, some options are necessary and some are optional. We cover in the next two sub sections how to configure the loading of a project hosted via Monticello and git, and then we detail optional parameters.\n\n#### Project managed with Git\n\nTo load a project from git you need to execute an expression like this:\n\n```Smalltalk\nMetacello new\n\trepository: {repository};\n\tbaseline: {baselineName};\n\tload\n```\n\nThis command has two parameters:\n\n- `repository` defining the location of the git project, the version of the project to load and the subdirectory in which the project is stored.\n- `baselineName` is the name of the baseline to load. For example to load the `MaterialDesignLite` project, the baseline name is `MaterialDesignLite` to load the project with `BaselineOfMaterialDesignLite`.\n\nThe repository parameter is a string that can take different forms depending on if the project is local or hosted remotely.\n\n##### Project from github/gitlab/bitbucket\n\nThe repository parameter to load a project from github/gitlab/bitbucket takes this form:\n\n`{prefix}://{optionalHostname}:{owner}/{projectName}:{version}/{subFolder}`\n\nThis snippet should be configured with:\n\n- `{prefix}`: This is host-specific:\n  - `github` for github\n  - `bitbucket` for bitbucket\n  - `gitlab` for gitlab\n- `{optionalHostname}`: Optional server host, for private git servers\n- `{owner}`: Name of the user or organization hosting the project\n- `{projectName}`: Name of the project\n- `{version}`: This parameter is optional, and it defaults to master. It can be the name of a branch, a tag like `'v1.2.0'` or `'v1.x.x'`, or a the SHA of a commit\n- `{subfolder}`: This parameter is optional in case the code is at the root of the project. It should point to the sub-folder containing the code.\n\nExample: loading from Github.\n\n```Smalltalk\nMetacello new\n\trepository: 'github://DuneSt/MaterialDesignLite:v1.x.x/src';\n\tbaseline: 'MaterialDesignLite';\n\tload\n```\n\nExample: loading from a private Gitlab host.\n\n```Smalltalk\nMetacello new \n\tbaseline: 'Ghost';\n\trepository: 'gitlab://gitlab.inria.fr:RMOD/Ghost';\n\tload\n```\n\nMetacello also comes with some syntactic sugar to define the repository to github or bitbucket:\n\n- *Github*: `Metacello>>githubUser:project:commitish:path:`\n- *Bitbucket*: `Metacello>>bitbucketUser:project:commitish:path:`\n\nExample:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tload\n```\n\n##### Project from local repository\n\nTo load a project from a local repository you can use this form to declare the repository:\n\n`'{prefix}://{full/path/to/repository}/{subFolder}'`\n\nThis snippet should be configured with:\n\n- `{prefix}`: This is specific to the file format:\n  - `filetree` for a Filetree project\n  - `tonel` for a Tonel project\n- `{full/path/to/repository}`: is the path to the project on the file system\n- `{subfolder}`: This parameter is optional in case the code is at the root of the project. It should point to the subfolder containing the code.\n\nExample:\n\n```Smalltalk\nMetacello new\n\trepository: 'tonel://C:\\Users\\Cyril\\GitRepositories\\Native-Browser\\src';\n\tbaseline: 'NativeBrowser';\n\tload\n```\n\n#### Project managed with Smalltalkhub\n\nTo load a project from Smalltalkhub you need to execute an expression like this:\n\n```Smalltalk\nMetacello new\n\trepository: 'http://smalltalkhub.com/mc/{owner}/{repositoryName}/main';\n\tconfiguration: {configurationName};\n\tversion: {version};\n\tload\n```\n\nThis command has two parameters:\n\n- `owner`: Name of the team or user hosting the project\n- `repositoryName`: Name of the repository on SmalltalkHub\n- `configurationName` is the name of the configuration to load. For example to load the `MaterialDesignLite` project, the baseline name is `MaterialDesignLite` to load the project with `BaselineOfMaterialDesignLite`.\n- `{version}`: Name of the version you wish to reference. It can be something like `'development'`, `'stable'`, `'release1'`, `'1.2.6'`, `'1.0-baseline'`, etc.\n\nExample:\n\n```Smalltalk\nMetacello new\n\trepository: 'http://smalltalkhub.com/mc/Seaside/Seaside31/main';\n\tconfiguration: 'Seaside3';\n\tversion: #stable;\n\tload\n```\n\nYou can also use `Metacello>>smalltalkhubUser:project:`:\n\n```Smalltalk\nMetacello new\n\tsmalltalkhubUser: 'Seaside' project: 'Seaside31';\n\tconfiguration: 'Seaside3';\n\tversion: #stable;\n\tload\n```\n\n#### Project without repository\n\nIt is possible to use Metacello without specifying any repository. This can be useful for defining all project dependencies in a baseline and then loading them with Metacello.\n\n```Smalltalk\nMetacello new\n\tbaseline: #TinyBlog;\n\tload\n```\n\n#### Loading groups\n\nSometimes we want to load only specific groups of a project. This can be done be replacing the `load` selector by `load:`.\n\nThe `load:` selector takes a string or a collection of strings as parameter. Each string represents a group name from the baseline.\n\nExamples:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tload: 'Extensions'\n```\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tload: #('Extensions' 'Widgets')\n```\n\n#### Conflict, Upgrade and Downgrade resolution\n\nSometimes there can be conflicts, updates or downgrades while loading a project.\n\nFor example, imagine in an image the project `ProjA` at version v1.0.0. We want to load our project `ProjB` that depends on `ProjA` version v2.0.0., `ProjC` version v1.0.0, and `ProjD` that loads also `ProjC` version v2.0.0.\n\nIf we load `ProjB` in those conditions, we will have two problems:\n\n- The update of `ProjA` from v1.0.0 to v2.0.0\n- A conflict between `ProjC` v1.0.0 and v2.0.0\n\nTo manage conflicts we can use the options `onConflict:`, `onUpgrade:` and `onDowngrade:`.\n\nExample:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tonConflict: [ :ex | ex useIncoming ];\n\tonUpgrade: [ :ex | ex useIncoming ];\n\tonDowngrade: [ :ex | ex useLoaded ];\n\tload\n```\n\nA last conflicting situation happens if Pharo includes a project in the default distribution and you want to load a new version. To manage this case you have the `ignoreImage` option.\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tonConflict: [ :ex | ex useIncoming ];\n\tonUpgrade: [ :ex | ex useIncoming ];\n\tonDowngrade: [ :ex | ex useLoaded ];\n\tignoreImage;\n\tload\n```\n\nHere is a last example of conflict management. The Pharo community was previously on a version control system called Monticello. Most of the community has now migrated to GitHub. Some of the projects exist on Smalltalkhub (managed with Monticello) and on GitHub. It's not unusual to have conflict between the two.\n\nHere is a little script that loads the version managed with git when the project name is the same:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tonConflict: [ :ex :a :b | a projectName = b projectName ifTrue: [ a projectSpec isBaselineOfProjectSpec ifTrue: [ ex useLoaded ] ifFalse: [ ex useIncoming ] ] ifFalse: [ ex resume ] ];\n\tload\n```\n\n#### Manage warnings\n\nIn some cases a project has problems during the loading, for example, if a package loaded is missing a dependency. When this happen, Metacello will raise a warning. Most of the time the projects can still work, at least partially. If you do not want Metacello to open a warning, you can log them instead. To enable this option you can use the `onWarningLog` or `onWarning:` options.\n\nExamples:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tonWarning: [ :ex | Transcript crShow: ex ];\n\tload\n```\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'master' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tonWarningLog;\n\tload\n```\n\n### From Iceberg\n\nIn Pharo 7 a new tool to manage git repositories was introduced: *Iceberg*. This tool allows the developer to load a project via a user interface.\n\nThe first step is to add your git project to Iceberg. Then right-click on the project name to access a `Metacello` sub-menu to load the project.\n\n![Interface of Iceberg to load a project](Baselines_Image_LoadBaselineViaIceberg.png?raw=true \"Interface of Iceberg to load a project\")\n\n## Other features\n\nThis section covers other features of baselines and Metacello.\n\n### Metacello lock feature\n\nIn the normal course of loading and upgrading, you want the correct version of dependent projects loaded. However, there are some special cases where automatic upgrading isn't desirable:\n\n- You may be actively developing a particular version of a project and you don't want the project upgraded (or downgraded) out from under you.\n- You may be working with a git checkout of a project and you want to continue using the git checkout.\n- You may not want to have particular projects upgraded automatically.\n\nThe `lock` command forces a particular version.\n\nExample:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.1.0' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tlock\n```\n\nThis example will lock the project MaterialDesignLite to version v1.1.0.\n\nYou can check the list of locked projects via those snippets:\n\n```Smalltalk\nMetacello registry locked. \"Return the list of locked projects from the Metacello registry\"\n\nMetacello image locked. \"Return the list of locked projects loaded in the image.\"\n```\n\nIf you wish to unlock a project, you can use the `unlock` message.\n\nExample:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.1.0' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tunlock\n```\n\nDuring the loading of a project you can also do some specific actions when you encounter a lock. For this you can use the `onLock:` message.\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.1.0' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tonLock: [ :ex :loaded :incoming | loaded baseName = 'myProject' ifTrue: [ ex break ] ifFalse: [ ex honor ] ];\n\tload\n```\n\n### Metacello get feature\n\nMetacello includes a command to load the baseline of a project into the image. This is useful in two cases:\n\n- You want to load only the baseline of the project\n- You already have an obsolete baseline in your image and you want to update it before loading the project\n\nTo do that you can use the `get` command.\n\nExample:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.x.x' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tget\n```\n\n### Metacello fetch feature\n\nThe fetch command downloads all of the packages without loading them. This includes the packages of the project but also their dependencies.\n\nExample:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.x.x' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tfetch\n```\n\nYou can also specify a group:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.x.x' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tfetch: #('Extensions' 'Widgets')\n```\n\nThe fetch command duplicates what the load command would do, which means if a package is already loaded in the image, it will not be fetched. To fetch packages regardless of what is loaded in the image, use the `ignoreImage` option:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.x.x' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\tignoreImage;\n\tfetch\n```\n\n### Metacello record feature\n\nThe `record` command performs the same function as the `fetch` command, without actually downloading any files. As a consequence, it can give you a quick report of what packages will be loaded into your image. The recording will be produced in the `Transcript` (cmd + o + t).\n\nExample:\n\n```Smalltalk\nMetacello new\n\tgithubUser: 'DuneSt' project: 'MaterialDesignLite' commitish: 'v1.x.x' path: 'src';\n\tbaseline: 'MaterialDesignLite';\n\trecord\n```\n\n### Metacello listing feature\n\nThe `list` command lists projects in the image or Metacello registry:\n\n```Smalltalk\nMetacello image\n\tbaseline: [ :spec | true \"spec name beginsWith: 'Seaside'\" ];\n\tlist\n  \nMetacello registry\n\tbaseline: [ :spec | true \"spec name beginsWith: 'Seaside'\" ];\n\tlist\n```\n\nThis command needs to be inspected to see the list.\n\n## See also\n\n- Deep into pharo: [Chapter 9, Managing Projects with Metacello](http://files.pharo.org/books-pdfs/deep-into-pharo/2013-DeepIntoPharo-EN.pdf)\n- [Metacello documentation](https://github.com/Metacello/metacello/tree/master/docs)\n"
  },
  {
    "path": "General/CJKCharacter.md",
    "content": "# Using CJK (Chinese, Japanese, and Korean) characters\n\nPharo's default font settings for code (Source Code Pro) and UI (Source Sans Pro) are unable to handle [CJK characters](https://en.wikipedia.org/wiki/CJK_characters), this page explains how to display them properly in Pharo.\n\n![Preview string for chinese characters under Source Code Pro](CJKCharacter_Screenshot_1.png)\n\nOperating systems may come with fonts that support those characters but they are usually not monospaced which is not good for displaying code. If one need to display CJK characters in Pharo, it is recommended to install a monospace font which also covers CJK characters. Some of them are [`Noto Sans Mono CJK`](https://www.google.com/get/noto/) , `Microsoft YaHei Mono`, [`WenQuanYi Zen Hei Mono`](http://wenq.org).\n\nNote one must enable the option `Update fonts at startup` first and restart Pharo to make the font selection dialog below show all available fonts:\n1. Select menu `Pharo` -> `Settings` to show the `Settings Browser`.\n2. Enable `Appearance` -> `Use Free type...` -> `Update fonts at startup`, this can be disabled later after one changes the fonts.\n\n![Preview string for chinese characters under Microsoft YaHei Mono](CJKCharacter_Screenshot_2.png)\n\nNote that on Windows 10, one may need to manually copy font files to `C:\\Windows\\Fonts\\`.\n\nHere is a code sample:\n\n```Smalltalk\nStandardFonts \n\tdefaultFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9);\n\tcodeFont: (LogicalFont familyName: 'Microsoft YaHei Mono' pointSize: 10);\n\tlistFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9);\n\tmenuFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9);\n\tbuttonFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 9);\n\twindowTitleFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 10);\n\tballoonFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 8);\n\thaloFont: (LogicalFont familyName: 'Noto Sans CJK SC' pointSize: 8).\n```\n\n## Related links:\n\nhttps://www.samadhiweb.com/blog/2019.02.22.windows.multilingual.html  \nhttp://forum.world.st/Japanese-Fonts-td4928056.html  \nhttp://forum.world.st/im-using-pharo-7-with-linux-env-but-cannot-input-korean-td5095342.html\n"
  },
  {
    "path": "General/CJKInputMethod.md",
    "content": "# Using CJK (Chinese, Japanese, and Korean) Input Method\n\nIt's possible to use CJK input method in Pharo. Tested under Pharo8 on macOS, Linux and Windows.\n\n## Linux\n\nOn linux, you need add `-compositioninput` in VM args and make sure you are using Fcitx5.\n"
  },
  {
    "path": "General/CodingConventions.md",
    "content": "# Coding conventions\n\nPharo is full of implicit coding conventions. \n\nThis page aims to document all those conventions to help newcomers write Pharo code as per the community's idioms.\n\n## Tests conventions\n\nPharo has some conventions when it comes to tests. This section covers those.\n\n**Package name**\n\nIt is preferred to store tests in a separate package rather than in the package of the tested classes.\nThe name of this package should be `NameOfOriginalPackage-Tests`.\n\nFor example, if one wants to add tests to `Material-Design-Lite-Core`, the tests should be in a package called `Material-Design-Lite-Core-Tests`.\n\n**Class name**\n\nTests classes (subclasses of `TestCase`) should end with the suffix `Test` (and not `Tests` because a test class is a test case).\n\nIn the case of unit tests, the name of the class should be `MyClassTest`. For example, if one wants to add unit tests of `MDLButton`, the test class will be named `MDLButtonTest`.\n\n**Method name**\n\nTest method names in Pharo need to be prefixed with `test`. This is the way the test framework recognizes them as test methods. \n\nIn case of a unit test on a method of the tested class, the name should be prefixed by `test` followed by the name of the method to test.\n\nFor example:\n- The unit test for `#click` will be named `#testClick`\n- The unit test for `#clickElement:` will be named `#testClickElement`\n- The unit test for `#clickElement:withShiftPressed:` will be named `#testClickElementWithShiftPressed`\n\nBy doing that, a new icon next to your actual method name will appear in the system browser.\nThis icon allows one to launch the unit test of the method via a click.\n"
  },
  {
    "path": "General/CoolSnippets.md",
    "content": "# Cool Snippets\n\nThis file contains snippets of code that can be useful sometimes.\n\n- [Download a file with a progress bar](#download-a-file-with-a-progress-bar)\n- [Bench and profile a project from the tests](#bench-and-profile-a-project-from-the-tests)\n- [Automatic transformation of Pharo's methods source code](#automatic-transformation-of-pharo-s-methods-source-code)\n- [Browse all available icons](#browse-all-available-icons)\n- [Rename programatically methods](#rename-programatically-methods)\n- [Get all senders/implementors of a selector](#get-all-sendersimplementors-of-a-selector)\n- [Find dependencies on a package](#find-dependencies-on-a-package)\n- [Embed an image (picture) into Pharo](#embed-an-image-picture-into-pharo)\n\n## Download a file with a progress bar\n\n```Smalltalk\n| outputFileName url |\noutputFileName := './pharoLogo.png'.\noutputFileName asFileReference ensureDelete.\nurl := 'http://files.pharo.org/media/logo/logo-flat.png' asZnUrl.\n[ :bar | \n\tbar title: 'Download: ' , url asString , ' to ' , outputFileName.\n\t[ ZnClient new\n\t\turl: url;\n\t\tsignalProgress: true;\n\t\tdownloadTo: outputFileName ]\n\t\ton: HTTPProgress\n\t\tdo: [ :progress | \n\t\t\tprogress isEmpty ifFalse: [ bar current: progress percentage ].\n\t\t\tprogress resume ] ] asJob run\n```\n\n## Bench and profile a project from the tests\n\n```Smalltalk\npackageSelectionBlock := [ :e | e name beginsWith: 'Spec' ].\ntestSuite := TestSuite new.\n\t\n((RPackageOrganizer default packages select: packageSelectionBlock) flatCollect: #classes) select: [ :e | e inheritsFrom: TestCase ] thenDo: [ :e | e addToSuiteFromSelectors: testSuite ].\n\n\"Bench the test suite\"\t\n[ testSuite run ] bench.\n\n\"Profile the test suite\"\nTimeProfiler spyOn: [ testSuite run ]\n\n```\n\n## Automatic transformation of Pharo's methods source code\nDuring software maintenance, being able to transform source code automatically can be handy. It can be done easily in Pharo using the built-in code rewriting engine.\n\nFor example, let's say that we want to replace the occurences of `#symbolToReplace` symbol with occurences of `#replacedSymbol` in the following method:\n\n```Smalltalk\nExampleCodeTransformation>>#methodToTransform\n\t1 + 1 = 2\n\t\tifTrue: [ ^ #symbolToReplace ].\n\n\t^ #symbolToReplace , #symbolNotToReplace\n```\n\nIt can be done easily using the following code snippet:\n\n```Smalltalk\ncompiledMethod := ExampleCodeTransformation >> #methodToTransform.\n\nast := compiledMethod parseTree.\n\n\"Here we select only nodes holding the target symbol and we replace it with a node representing `#replacedSymbol`.\"\nast allChildren\n\tselect: [ :n | n class = RBLiteralValueNode and: [ n value = #symbolToReplace ] ]\n\tthenDo: [ :node |\n\t\trewriter := RBParseTreeRewriter new\n\t\t\treplaceTree: node\n\t\t\twithTree: (RBLiteralValueNode value: #replacedSymbol);\n\t\t\tyourself.\n\t\t(rewriter executeTree: ast)\n\t\t\tifTrue: [ node replaceWith: rewriter tree ] ].\n\t\t\n\"Serialize the new AST as Pharo source code.\"\nrewrittenSourceCode := (BIConfigurableFormatter format: ast).\n\n\"Recompile the method with transformed source code.\"\nExampleCodeTransformation compile: rewrittenSourceCode\n```\n\n## Browse all available icons\nThe following code snippet opens an inspector in which the 'Icons' tab allows to browse all icons available in the image.\n\n```\nSmalltalk ui icons inspect\n```\n\nTo get a specific icon, use `#iconNamed:` method as follow:\n\n```\nSmalltalk ui icons iconNamed: #arrowUp\n```\n\n## Rename methods programatically\n\nIn this section we will present a code snippet to rename all methods of a class by replacing one substring with another. First, we find all methods of a given class with names that contain a substring `A`, then we rename those methods to replace `A` with another substring `B`.\n\n```Smalltalk\n\"Class in which we want to rename the methods\"\nclass := EpApplyPreviewerTest.\n\"Substring to replace\"\nfrom := 'With'.\n\"Substring to use\"\nto := 'Without'.\n\nclass methods\n\tselect: [ :method | method selector includesSubstring: from ]\n\tthenDo: [ :method | \n\t\t| permutationMap |\n\t\t\"We want to keep the arguments in the same order\"\n\t\tpermutationMap := method numArgs = 0 ifTrue: [ #() ] ifFalse: [ (1 to: method numArgs) asArray ].\n\t\t\n\t\t(RBRenameMethodRefactoring\n\t\t\trenameMethod: method selector\n\t\t\tin: class\n\t\t\tto: (method selector copyReplaceAll: from with: to)\n\t\t\tpermutation: permutationMap) execute ]\n```\n\n> Be careful, this will also rename the senders of those methods and if you have two methods with the same name in the image, it might badly rename some of them. Use this only on methods with unique names.\n\n## Get all senders/implementors of a selector\nThe selector of a method is kind of the equivalent of the signature of a method or function in other programming languages.\nHowever, since Pharo is dynamically typed, this selector is only the name of the method, without the parameters.\nFor example, the selector of the method below is `#name:`\n\n```\nExample>>name: aString\n\tname := aString\n```\n\nFor a given `CompiledMethod` in the system, its selector is accessible via `#selector` message.\n\n```\n(Object>>#yourself) selector. \"#yourself\"\n```\n\n### Senders\nTo get all the senders of a selector accross the image, simply call `#senders` on the selector:\n\n```\n#yourself senders\n```\n\n### Implementors\nTo get all `CompiledMethod`s implementing a method having a selector, simply call `#implementors` on the selector:\n\n```\n#yourself implementors\n```\n\n## Find dependencies on a package\n\nIn Pharo it is easy to find the dependencies of one package through the `Dependency Analyzer`, but there is no tool to browse the dependencies *on* a single package. \n\nIt is possible to do it programatically via this snippet:\n\n```Smalltalk\nreport := DADependencyChecker new computeImageDependencies. \"This might take some time but it will run in background\"\nreport knownDependantsOf: 'Epicea' \"Replace Epicia by the name of your package.\"\n```\n\n## Embed an image (picture) into Pharo\nIf you want to add an image into Pharo, you will need to import it\n```Smalltalk\nImageReadWriter formFromFileNamed: 'test.png'\n```\nand you may store it into the image for further reuse. This is achieved by encoding the image into a base 64 String. Then, the String can be stored in a method.\n```Smalltalk\n(Base64MimeConverter mimeEncode: 'test.png' asFileReference binaryReadStream) contents\n```\nLet's say we store the image base64 String in `Foo>>#image`. To materialize a Form from this image, you can do:\n```Smalltalk\nForm fromBinaryStream: Foo image base64Decoded asByteArray readStream\n```\nHere is a shortcut available since Pharo 8.0:\n```Smalltalk\nForm fromBase64String: Foo image\n```\n"
  },
  {
    "path": "General/DeployYourPharoApplication.md",
    "content": "# How to deploy a Pharo application\n\n*This guide has for purpose to help developpers deploying a Pharo application. If something is missing to you, do not hesitate to open an issue.*\n\n**This guide is first written for Pharo 7. Some parts will not work in Pharo 6 and earlier.**\n\n- [How to deploy a Pharo application](#how-to-deploy-a-pharo-application)\n  * [Cruiser: A tool for app deployment?](#cruiser)\n  * [Clean your image before deployment](#clean-your-image-before-deployment)\n  * [Sources obfuscation](#sources-obfuscation)\n  * [Change the logo and window title of the application](#change-the-logo-and-window-title-of-the-application)\n  * [Deploy a Seaside application with Nginx](#deploy-a-seaside-application-with-nginx)\n\n## Cruiser\nCruiser is a tool to package Pharo applications. The idea is to quickly convert an application in a development environment to a production one.\n[https://github.com/VincentBlondeau/Cruiser](https://github.com/VincentBlondeau/Cruiser)\n\n\n## Clean your image before deployment\n\nIn this section we explain various ways to clean an image for deployment. All steps are not necessary and the benefits are given in each subsection.\n\n### Clean up the system\n\nA first step is to launch a cleanup of the image. Pharo already contains a system to cleanup divers part of the system by calling the `#cleanUp(:)` method of every class implementing it.\n\nIt can be done with this snippet:\n\n```Smalltalk\nSmalltalk cleanUp: true except: {} confirming: false\n```\n\nThe first parameter should be a boolean. If it's value is `true` it will launch a more aggresive cleanup and this will destroy resources, change sets, etc.\nThe second parameter allows the developper to exclude some classes of the cleanup by passing an array containing all the classes that should not execute their cleanup.\n\n### Ensure logins are removed from the image\n\nDuring the deployment of an application it might be a good idea to remove all login informations from the image.\n\nIn order to do that you can execute this script:\n\n```Smalltalk\n| store |\n\n\"Remove all repositories from Monticello VCS\"\nMCRepositoryGroup allSubInstancesDo: [ :group | group repositories do: [ :repo | group removeRepository: repo ] ].\n\n\"Remove projects and credentials from Git VCS (Tested in Pharo 7)\"\nIceRepository registry removeAll.\nstore := IceCredentialStore current.\nstore allCredentials do: [ :each | each removeFrom: store ]\n```\n\nWith this step done all the credentials should be removed from the image if you do not use an external project from Pharo that store some credentials.\n\n### Close all windows\n\nWhile deploying an application you might want to ensure every Morph is closed (to remove the Pharo welcome window for example).\n\nThis can directly be done via the command:\n\n```Smalltalk\nWorld closeAllWindowsDiscardingChanges\n```\n\n### Disable deprecation warning\n\nPharo contains a deprecation warning system to help the developers to keep their code up to date but in productions those warnings should be removed so that the user will not be bothered by them in case a deprecated method is called.\n\nYou can do that via:\n\n```Smalltalk\nDeprecation\n\traiseWarning: false;\n\tshowWarning: false\n```\n\n### Enable the run without sources and changes files\n\nIt is possible to run a Pharo image without `.changes` or `.sources` files.\n\nTo do that you can execute:\n\n```Smalltalk\nNoChangesLog install.\nNoPharoFilesOpener install\n```\n\nNote that FFI needs the sources to work properly. In Pharo 7 a pluggin to remove this need was introduced.\nIf your application uses FFI calls you will need to execute:\n\n```Smalltalk\nFFICompilerPlugin install\n```\n\n### Disable creation of STDio files on Windows\n\nOn Windows there is two way to launch a Pharo image. The first uses the `Pharo.exe` executable and the second `PharoConsole.exe`. The difference between those two methods is that the former will be launched without a terminal and will create files to write STDio outputs. The second will open a terminal with Pharo to manage STDio.\n\nIt is possible to disable the writing of the STDio files on Windows with this code:\n\n```Smalltalk\nStdio useNullStreams\n```\n\n### Remove tests and example packages\n\nIn production examples and tests packages are useless. You can find bellow a script to unload them. \n\n> Be careful, this script is based on a heuristic. If the naming convensions or dependencies are not well managed this might break your application. Please test you application after using such a script.\n\n```Smalltalk\n| substrings |\nsubstrings := #('Test' 'Example' 'Mock' 'Demo').\n\nRPackageOrganizer default packages\n\tselect: [ :p | substrings anySatisfy: [ :aString | p name includesSubstring: aString ] ]\n\tthenDo: #removeFromSystem\n```\n\n### Disable Monticello cache\n\nMonticello uses by default a cache when it is used. It is possible to disable this cache with this script:\n\n```Smalltalk\nMCCacheRepository uniqueInstance disable\n```\n\n### Disable Epicea\n\nPharo contains a record system to recover changes: *Epicea*. This system log a lot of events on disk.\n\nIt is possible to disable Epicea like this:\n\n```Smalltalk\nEpMonitor reset\n```\n\n### Garbage collect\n\nAs last step of the deployment I would recommand the user to launch a full garbage collection of the system to clean all dead instances from the image:\n\n```Smalltalk\n5 timesRepeat: [ Smalltalk garbageCollect ]\n```\n\n### Delete pharo-local folder\n\nPharo works with a local folder containing caches. This folder is called `pharo-local` and is next to the image since Pharo 7. It is recommanded to delete this folder, or to not include this folder in the distribution.\n\n## Sources obfuscation\n\nWhen deploying a commercial application on the customer's infrastructure, we might want to protect our code. This section will give some advice on how to protect the source code of your application.\n\n> WARNING: What will be describe here is not a perfect solution. We are aware it will still have some weakness, but at least it will make it much harder to get the source code of the application.\n\nThis section works with the previous section aswell. We recommand to:\n* Run without the sources file\n* Run without the changes file\n* Disable Epicea\n* Remove the loggins of your image\n\n### Force omission of startup preferences\n\nAt launch Pharo try to load preferences. Since the user can execute Smalltalk code via those preferences, we recommand to disable the preference mechanism with this code:\n\n```Smalltalk\nPharoCommandLineHandler forcePreferencesOmission: true\n```\n\n### Protect command lines by a password\n\nSince the user can intereact with Pharo via command line, we recommand to protect command lines with a password.\n\nThe password is not be saved in clear. It is hashed using pepper and iterations.\n\nIf you wish to define *application* command lines who does not need a password protection, implement the method `requireDeploymentPassword` on the class side of your command lines to return `false`.\n\n```Smalltalk\n\"Enable password protection\"\nCommandLinePasswordManager protectCommandLinesByPasswordWith: 'PharoPassword'.\n\n\"You can also customize the pepper and number of iterations for the hashing of the password.\"\nCommandLinePasswordManager protectCommandLinesByPasswordWith: 'PharoPassword' pepper: 'SomePepper' numberOfHashIterations: 10.\n\n\"Remove password protection\"\nCommandLinePasswordManager removePasswordProtection.\n```\n\n### Remove the decompiler\n\nWithout the sources and changes files the user does not have the source code shipped with the application, but he still has the byte code of the application. To make it harder to exploit if he succeed to get a part of the byte code, you can unload the decompiler from the image with the piece of code:\n\n```Smalltalk\nRPackageOrganizer default packages\n\tselect: [ :p | p name includesSubstring: 'Flashback' ]\n\tthenDo: #removeFromSystem\n```\n\n### Disable global shortcuts\n\nIf the customer has access to the Pharo image it is recommanded to disable global shortcuts that can help to open tools. \n\nIt is doable this way:\n\n```Smalltalk\n(KMRepository default globalCategories flatCollect: [ :each | each allEntries keymaps ]) do: #disable\n```\n\n### Disable WorldMenu, Menubar and Taskbar\n\nTo block the access to the tools it is possible to disable the world menu, the taskbar and the menu bar from Pharo with this piece of code:\n\n```Smalltalk\n\"Disable world menu and menubar\"\nWorldState desktopMenuPragmaKeyword: ''.\n\n\"Disable Menubar only\"\nMenubarMorph showMenubar: false.\n\n\"Disable WorldMenu only\"\nPasteUpMorph shouldShowWorldMenu: false.\n\n\"Disable taskbar\"\nTaskbarMorph showTaskbar: false.\n```\n\n### Disable progress bar interrupt button\n\nIf you show progresses in your application via a progress bar, the user can clic on the red cross to stop the action and open a debugger.\n\nIt is possible to remove this possibility executing:\n\n```Smalltalk\nJobProgressBarMorph isInterruptable: false\n```\n\n### Disable process interruption button\n\nIn Pharo, it is possible to disable the current process via the `cmd + .` shortcut. This feature can be disabled:\n\n```Smalltalk\nUserInterruptHandler cmdDotEnabled: false\n```\n\n### Disable drag and drop in Pharo\n\nIt is possible to drop files in Pharo to install code in it. It is recommanded to disable this feature to block users to inject code into the application. Since there is no setting to do that, you can recompile a part of the Pharo image to block it this way:\n\n```Smalltalk\nWorldMorph allowDropFiles: false\n```\n\n### Disable Morph's Halos\n\nTo remove the option to open Halos around the Morphs of Pharo you can execute:\n\n```Smalltalk\nMorph halosEnabled: false\n```\n\n### Disable Debugger\n\n#### Pharo 8\n\nSince Pharo 8, Pharo comes with new debuggers you can choose from.\n\nWhen deploying a private application you don't want the user to get a bug and access to the code through it. For that you can use the `NoDebugger`:\n\n```Smalltalk\nNoDebugger beCurrent\n```\n\n#### Pharo < 8 or specific debuggers\n\nIn case you are using Pharo < 8 or you want a special handling of the bug you can create your own debugger.\n\nFor that you need to create a object and implement a class side method called `#openOn:withFullView:andNotification:`.\n\nFor example for a `NoDebugger`:\n\n```Smalltalk\nNoDebugger class>>openOn: aDebugSession withFullView: aBool andNotification: aString\n\t\"Do nothing\"\n```\n\nFor a debugger exporting in a file the error:\n\n```Smalltalk\nopenOn: aDebugSession withFullView: aBool andNotification: aString\n\t'errors.log'\n\t\tensureCreateFile;\n\t\twriteStreamDo: [ :s |\n\t\t\ts\n\t\t\t\tsetToEnd;\n\t\t\t\t<< 'ERROR. Here is the stack:';\n\t\t\t\t<< OSPlatform current lineEnding.\n\t\t\taDebugSession interruptedContext shortDebugStackOn: s ]\n```\n\nYou then need to register the debugger:\n\n```Smalltalk\nSmalltalk tools register: NoDebugger as: #debugger\n```\n\n### Open a morph in full screen\n\nWhen deploying the application, while there is no real headless mode in Pharo or when the application contains a user interface embedded we can open a Morph in full screen to ensure the user cannot access to content behind it. \n\nTo do that we can create a Spec application (in case of headless application it can just contains a logo and a `quit` button) and open it in full screen with this command:\n\n```Smalltalk\nMyPresenter new openWorldWithSpec\n```\n\n## Change the logo and window title of the application\n\nIn Windows it is possible to change the title and the logo of the Pharo application. \n\nTo do that you can execute:\n\n```Smalltalk\nDisplayScreen setWindowTitle: 'MyApplication'.\n\nDisplayScreen hostWindowIcon: (FileLocator imageDirectory / 'testLogo.ico') asFileReference fullName.\n```\n\n## Deploy a Seaside application\n\nThis section will cover a specific kind of deployment: the deployment of a web application with Seaside.\n\n### Prepare the image\n\nIt is recommanded to prepare the image for deployment. This section will cover some possible configurations you can apply to your image.\n\n> Note: This is section only contains suggestions and it might be missing interesting options. If you have an idea of missing section do not hesitate to open an issue.\n\n#### Set server mode\n\nWhen deploying an application as a server, it is possible to change a setting to slow down the rendering cycle of the image and increase performances. It can be done like this:\n\n```Smalltalk\nWorldState serverMode: true\n```\n\n#### Unregister applications\n\nWhen building your seaside image it is possible that some Seaside application got registered (demos for examples). \n\nIt is possible to unregister them like this:\n\n```Smalltalk\napplicationsToUnregister := WAAdmin defaultDispatcher handlers keys \\ #('myApplication' 'files' 'myHandler' 'config').\napplicationsToUnregister do: [ :appName | WAAdmin defaultDispatcher unregister: (WAAdmin defaultDispatcher handlerAt: appName) ]\n```\n\n#### Set default application\n\nApplications must have a name in Seaside and the name should be in the URL. However, it is possible to define a default application which will be selected in case no application name is in the URL. \n\n```Smalltalk\nWAAdmin defaultDispatcher defaultName: 'myApplicationName'\n```\n\n#### Disable development toolbar\n\nIn case you load a version of Seaside containing development tools, your application will come with a development toolbar. \n\nIt is possible to remove it by executing:\n\n```Smalltalk\nWAAdmin applicationDefaults removeParent: WADevelopmentConfiguration instance ].\n```\n\nThen you need to initialize you application. \n\n#### Protect configuration by a password\n\nIn case you keep the configuration application available to the user, you might want to protect it by a password. It wan be done like this:\n\n```Smalltalk\n| application |\napplication := WAAdmin defaultDispatcher handlerAt: 'config'.\napplication configuration addParent: WAAuthConfiguration instance.\napplication\n\tpreferenceAt: #login put: 'admin';\n\tpreferenceAt: #passwordHash put: (GRPlatform current secureHashFor: 'seasideiscool').\napplication addFilter: WAAuthenticationFilter new\n```\n\n### Deploy with a Ngnix server\n\nThis section will cover the configuration needed to deploy an image with a nginx server.\n\n#### Launch the image\n\nIn general I (the author of this decumentation) use a Jenkins to generate my image and then I have a script to deploy the image.\n\nMy script looks like this:\n\n```bash\n#!/usr/bin/env bash\nset -vx\n\n# Where to deploy the application\nexport DEST=/srv/app/mdl\n# Pharo version for the deployment\nexport PHARO=61\n# Location of the zip containing the archive\nexport ARCHIVE_LOCATION=/var/lib/jenkins/workspace/MaterialDesignLite/PHARO/$PHARO/VERSION/master/\n\n# To launch an image I uses a screen, else the image will close with my ssh session. Here I ensure the session used is closed.\nscreen -S mdl -X quit\n\n# Remove the old version\nrm -rf $DEST/{MaterialDesignLite.*,pharo*,*.sources,Pharo*}\n\n# Copy the application\ncp ${ARCHIVE_LOCATION}MaterialDesignLite.zip $DEST/\ncd $DEST\n\n# Get a VM and unzip the application\nwget --quiet -O - get.pharo.org/vm${PHARO} | bash\nunzip MaterialDesignLite.zip\n\n# Launch the application and initialize it on a free and open port\n./pharo MaterialDesignLite.image eval --save \"\nMDLDemo initializeAs: 'mdl'.\n\nWAAdmin defaultDispatcher defaultName: 'mdl'.\n\nZnZincServerAdaptor startOn: 8088\"\n\n#Launch the image in a screen\nscreen -Sdm mdl ./pharo MaterialDesignLite.image --no-quit\n```\n#### HTTP deployment\n\nNow that the image is launched we need to dispatch it via nginx.\n\nIn order to do that over HTTP I uses this configuration:\n\n```nginx\nserver {\n  listen 80; #Since it's a web application, listen port 80\n  listen [::]:80; #Same for IPv6\n  server_name {Domaine name. Example mysite.com}; #Set your domaine name\n  server_tokens off;  #Do not display nginx version for security reasons\n\n  access_log /var/log/nginx/{log name}.log; #loging\n  error_log /var/log/nginx/{error log name}.log; #error loging\n\n  root {Path to the root. For example /srv/myApp/};\n\n  location = / {\n    try_files $uri $uri/index.html @proxy;\n  }\n\n  #use a proxy for your seaside application\n  location @proxy {\n    rewrite ^ /{Seaside application name. For example TelescopeDemo}$1 last;\n  }\n\n  location /{Seaside application name. For example TelescopeDemo} {\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_pass http://127.0.0.1:{Port on which your ZincServerAdaptor listen. For example 8080};\n  }\n\n  # This is for the file libraries\n  location /files {\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_pass http://127.0.0.1:{Port on which your ZincServerAdaptor listen. For example 8080};\n  }\n\n}\n```\n#### HTTPS deployment\n\nThe previous option works but is not secured. It is recommanded to generate a TLS certificate (with `let's encrypt` via `certbot` for example) and to deploy over HTTPS.\n\nThen the configuration will look like this:\n\n```nginx\nserver {\n  listen 80; #Since it's a web application, listen port 80\n  listen [::]:80; #Same for IPv6\n  server_name {Domaine name. Example mysite.com}; #Set your domaine name\n  server_tokens off;  #Do not display nginx version for security reasons\n  return 301 https://$server_name$request_uri; #Redirect HTTP -> HTTPS\n}\n\nserver {\n  listen 443 ssl http2; #Listen to port 443 for HTTPS\n  listen [::]:443 ssl http2; #Same for IPv6\n  server_name {Domaine name. Example mysite.com}; #Set your domaine name\n  server_tokens off;  #Do not display nginx version for security reasons\n  ssl_certificate {path to your public certificate key}.pem;\n  ssl_certificate_key {path to your private certificate key}.pem;\n\n  access_log /var/log/nginx/{log name}.log; #loging\n  error_log /var/log/nginx/{error log name}.log; #error loging\n\n  root {Path to the root. For example /srv/myApp/};\n\n  location = / {\n    try_files $uri $uri/index.html @proxy;\n  }\n\n  #use a proxy for your seaside application\n  location @proxy {\n    rewrite ^ /{Seaside application name. For example TelescopeDemo}$1 last;\n  }\n\n  location /{Seaside application name. For example TelescopeDemo} {\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_pass http://127.0.0.1:{Port on which your ZincServerAdaptor listen. For example 8080};\n  }\n\n  # This is for the file libraries\n  location /files {\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_pass http://127.0.0.1:{Port on which your ZincServerAdaptor listen. For example 8080};\n  }\n}\n```\n\n"
  },
  {
    "path": "General/Exceptions.md",
    "content": "# Exceptions\n\nAll applications have to deal with exceptional situations.\nArithmetic errors may occur (such as division by zero), unexpected situations may arise (file not found), or resources may be exhausted (network down, disk full, etc.).\nIn languages like C, the solution is to have operations that fail return a special error code; this means that client code must check the return value of each operation, and take special action to handle errors. This leads to brittle code.\n\nModern programming languages, including Pharo, offer a dedicated exception-handling mechanism that greatly simplifies the way in which exceptional situations are signaled and handled.\nThis mechanism is the **Exception** mechanism.\n\n- [Exceptions](#exceptions)\n  * [Basic Uses](#basic-uses)\n    + [Signaling an exception](#signaling-an-exception)\n    + [Handling exceptions](#handling-exceptions)\n    + [Creating your own exceptions](#creating-your-own-exceptions)\n    + [Ensure](#ensure)\n    + [IfCurtailed](#ifcurtailed)\n  * [Advanced Uses](#advanced-uses)\n    + [Return](#return)\n    + [Retry](#retry)\n    + [Resume](#resume)\n    + [Pass](#pass)\n    + [Outer](#outer)\n    + [Resignal](#resignal)\n  * [A deeper look at the exception mechanism](#a-deeper-look-at-the-exception-mechanism)\n  * [Credits](#credits)\n\n## Basic Uses\n\n### Signalling an exception\n\n**Syntax:**  \n`anException signal`  \nor:\n`anException signal: 'message with additional information'`\n\nImagine you have a method `potentiallyProblematicMethod`, that sometimes sets a variable to a bad value. When this happens (line 3), you want to signal this problem by **signalling** an exception (in this example an `Error` exception).\n\n```Smalltalk\npotentiallyProblematicMethod\n\tself doThings.\n\t(myVariable = badValue) ifTrue: [ ^ Error new signal: 'Oh my god no!'].\n\t^ myVariable.\n```\n\nIf you execute this code, the following window opens:\n![Image](./Exceptions_Image_ExamplePreDebugger.png)\n\nAnd if you click on \"Debug\", a debugger opens to help you understand why your application signalled an exception.\n![Image](./Exceptions_Image_ExampleDebugger.png)\n\n### Handling exceptions\n**Syntax:**  \n`protectedBlock on: anExceptionClass do: handlerBlock`.  \nHandling multiple exception classes:  \n`protectedBlock on: anExceptionClass, anotherExceptionClass, yetAnotherExceptionClass... do: handlerBlock`.  \nAccessing the exception in the handler block:  \n`protectedBlock on: anExceptionClass do: [:exceptionToHandle| yourCode]`.\n\nAs seen in the previous paragraph, if an exception is signalled and nothing else is done, a debugger opens. It is useful when developing, but in the end you probably want your application to catch these exceptions and handle them itself if possible (for example by displaying a nice pop-up informing the user of the problem). This is done with exception **handlers**.\n\nIn Pharo, an exception handler is of the form:  \n`protectedBlock on: anExceptionClass do: handlerBlock`.  \nHere's what happens (in English): *\"Evaluate `protectedBlock`. If it signals an exception of the class `anExceptionClass`, catch this exception and evaluate `handlerBlock` instead\"*.\n\nTo continue the previous example, let's say that `potentiallyProblematicMethod` is called by `solidMethod`. Now `solidMethod` is solid, so it does not want debuggers to open when it is executed. Instead, if an exception is signalled by `potentiallyProblematicMethod`, it will handle it, display a pop-up informing the user, and return `42` instead of the result of `potentiallyProblematicMethod`.\n\n```Smalltalk\nsolidMethod\n\t^ [self potentiallyProblematicMethod]\n\t\ton: Error\n\t\tdo: [UIManager default inform: 'There was an issue, but it`s ok'. 42.]\n```\n\nNow when `solidMethod` is executed, it either returns the result of `self potentiallyProblematicMethod` if no `Error` is signalled, or it displays a pop-up and returns 42 if an `Error` is signalled.\n\n![Image](./Exceptions_Image_InformationPopUp.png)\n\nWhen an exception is signalled, it walks the call stack (from the current method to its caller, then the caller of the caller, etc...) until it finds a handler that can handle it. If no handler is found, a debugger is opened.\n\n### Creating your own exceptions\n`Error` is not the only kind of exception that can be signalled, there are a lot more! The following picture shows a few examples.\n\n\n![Image](./Exceptions_Image_ExceptionSample.png)\n\nAn issue with writing handlers for generic exception types like `Error` is that these handlers will not only handle errors your application signals (which is fine), but they will also handle errors signalled by the libraries you use, or code that your application uses but that is not a part of it. This is potentially dangerous, as your application may not be doing the right thing for these errors.\n\nTo prevent this, you can define your own types of exceptions by creating subclasses of the `Exception` class, and signal and catch these.\n\nTo continue the example, we could create an `Exception` subclass named `MyVariableHasABadValue`, and update `potentiallyProblematicMethod` and `solidMethod` as follows:\n\n```Smalltalk\npotentiallyProblematicMethod\n\tself doThings.\n\t(myVariable = badValue) ifTrue: [ ^ MyVariableHasABadValue new signal: 'Oh my god no!'].\n\t^ myVariable.\n```\n\n```Smalltalk\nsolidMethod\n\t^ [self potentiallyProblematicMethod]\n\t\ton: MyVariableHasABadValue\n\t\tdo: [UIManager default inform: 'There was an issue, but it`s ok'. 42.]\n```\n\n### Ensure\n**Syntax:**  \n`aBlock ensure: ensuredBlock`.\n\nThe `ensure:` message can be sent to a block to make sure that, even if the block fails (e.g., signals an exception) the argument block will still be executed.  \n\nThis is useful to guarantee that `ensuredBlock` will be executed no matter what, for example to close files or clean up in case `aBlock` signals an exception, before the exception is transmitted.\n\n### IfCurtailed\n**Syntax:**  \n`aBlock ifCurtailed: curtailBlock`\n\nThe `ifCurtailed:` message is similar to `ensure:`, but its argument block is evaluated **only** if the receiver block signals an exception.  \n\n## Advanced Uses\nAfter catching an exception in a handler, there are a number of advanced things you can do with the exception.\n\n### Return\n**Syntax:**  \n`protectedBlock on: anExceptionClass do: [:ex | aValue ]`  \nor: `protectedBlock on: anExceptionClass do: [:ex | ex return ]`  \nor: `protectedBlock on: anExceptionClass do: [:ex | ex return: aValue ]`  \n\n**Synopsis:**  \nThis is the standard behavior of handler blocks. If an exception is caught, this handler returns an alternative value for the protected block (the execution continues as if the protected block has returned that value).\n\nHere is a picture of the context stack (a.k.a. call stack) explaining this operation.\n![Image](Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment1_return.png)\n\n### Retry\n**Syntax:**  \n`protectedBlock on: anExceptionClass do: [:ex | ex retry ]`  \nor: `protectedBlock on: anExceptionClass do: [:ex | ex retryUsing: aBlock ]`  \n\n**Synopsis:**  \nRe-execute the protected block (if using `#retry`), or replace the protected block with a different block and then re-execute it (if using `#retryUsing:`).\n\nHere is a picture of the context stack (a.k.a. call stack) explaining this operation.\n![Image](Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment2_retry.png)\n\n### Resume\n**Syntax:**  \n`protectedBlock on: anExceptionClass do: [:ex | ex resume ]`  \nor: `protectedBlock on: anExceptionClass do: [:ex | ex resume: aValue ]` \n\n**Synopsis:**  \nResume the execution of the protected block just after the call to #signal. The call to #signal is worth `nil` (if using `#resume`) or `aValue` (if using `#resume: aValue`).\n\n\nHere is a picture of the context stack (a.k.a. call stack) explaining this operation.\n![Image](Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment3_resume.png)\n\n### Pass\n**Syntax:**  \n`protectedBlock on: anExceptionClass do: [:ex | ex pass ]`  \n\n**Synopsis:**  \nSkip the current handler and keep looking for another handler to handle this exception.\n\n\n\n### Outer\n**Syntax:**  \n`protectedBlock on: anExceptionClass do: [:ex | ex outer ]`  \n\n**Synopsis:**  \nLike `ex pass`, but if another handler later calls `#resume` on the exception, the execution resumes where `#outer` was called instead of where the exception was signalled.  \nIf multiple `#outer` are executed on the same exception, they will form a sort of stack of positions to go back to, in case `#resume` is called multiple times on the exception.\n\nHere is a picture of the context stack (a.k.a. call stack) explaining this operation.\n![Image](Exceptions_Image_WhatCanYouDoWithAnExceptionYouCaught_fragment4_outer.png)\n\n### Resignal\n**Syntax:**  \n`protectedBlock on: anExceptionClass do: [:ex | ex resignalAs: anotherException ]`  \n\n**Synopsis:**  \nSignals `anotherException` as if it had been signalled at the same place the original exception (`ex`) was signalled.  \nThis can be used to catch generic exceptions and re-signal them as application-specific exceptions if they meet some criteria.\n\n## A deeper look at the exception mechanism\n\nThe following image gives a graphical view of what happens when an exception is signalled, and the different situations that can arise.\n![Image](Exceptions_Image_WhatHappensWhenAnExceptionIsSignalled.png)\n\n## Credits\nParts of this page are based on the **Handling Exceptions** chapter of the [Deep Into Pharo book](http://files.pharo.org/books-pdfs/deep-into-pharo/2013-DeepIntoPharo-EN.pdf).  \nPictures by Thomas Dupriez.\n"
  },
  {
    "path": "General/ExportFormats.md",
    "content": "# Source Code Export formats\n\nPharo stores its source code in memory (by default) or in a snapshot of the memory when we save a Pharo image. This makes it complicated to manage source code in the long term or to collaborate with others.\n\nIn order to be able to save some source code in readable files, Pharo includes some textual export formats. This page will explain the main export formats used to save code in VCS such as git.\n\nThis page will present formats from the most recommended for new projects to the less recommended.\n\n- [Comparisons](#comparisons)\n  * [Overview](#overview)\n  * [Supported Pharo versions](#supported-pharo-versions)\n- [Tonel](#tonel)\n  * [Tonel Pros and Cons](#tonel-pros-and-cons)\n  * [Tonel supported Pharo versions](#tonel-supported-pharo-versions)\n  * [Tonel versions](#tonel-versions)\n- [FileTree metadata less](#filetree-metadata-less)\n  * [FileTree metadata less Pros and Cons](#filetree-metadata-less-pros-and-cons)\n  * [FileTree metadata less supported Pharo versions](#filetree-metadata-less-supported-pharo-versions)\n- [FileTree metadata full](#filetree-metadata-full)\n  * [FileTree metadata full Pros and Cons](#filetree-metadata-full-pros-and-cons)\n  * [FileTree metadata full supported Pharo versions](#filetree-metadata-full-supported-pharo-versions)\n\n\n## Comparisons\n\n### Overview \n\n|| Tonel | FileTree metadata less | FileTree metadata full |\n| ------------- | ------------- |------------- |------------- |\n| Work out of the box since Pharo | 6.1 | 4 | 3 |\n| Older version supported after update | 4 | 4 | 3 |\n| Export granularity | Class | Method | Method |\n| Works well on windows | :white_check_mark: | :x: | :x: |\n| Easy to merge two branches | :white_check_mark: | :white_check_mark: | :x: |\n| Takes a reasonable space on file system | :white_check_mark: | :x: | :x: |\n| Works with Iceberg | :white_check_mark: | :white_check_mark: | :x: |\n| Works with Monticello | :white_check_mark: | :white_check_mark: | :white_check_mark: |\n\n### Supported Pharo versions\n\n| Pharo Version | FileTree metadata full | FileTree metadata less | Tonel |\n| ------------- | ------------- |------------- |------------- |\n3 |  :white_check_mark: | :x: | :x: |\n4 |  :white_check_mark: |  :white_check_mark: | Update Metacello + Install Tonel |\n5 |  :white_check_mark: |  :white_check_mark: | Update Metacello + Install Tonel |\n6.0 |  :white_check_mark: |  :white_check_mark: | Update Metacello + Install Tonel |\n6.1 | :white_check_mark: | :white_check_mark: | :white_check_mark: |\n7 | :white_check_mark: | :white_check_mark: | :white_check_mark: |\n8 | :white_check_mark: | :white_check_mark: | :white_check_mark: |\n\n## Tonel \n\nTonel ([https://github.com/pharo-vcs/tonel](https://github.com/pharo-vcs/tonel)) is an export format introduced in Pharo 6.1. \n\nIt creates one file by class or extended class and works well on Windows (compared to file tree).\n\n### Tonel Pros and Cons\n\nPros\n- Works well on Windows \n- Not much space lost because of small files\n- Export readable files\n- No problem during merge because of metadata\n\nCons\n- Works out of the box since Pharo 6.1.\n- Since the format is more recent than the others, some edges cases might cause trouble. (It rarely happens)\n\n### Tonel supported Pharo versions\n\nTonel works out of the box in Pharo 6.1 and higher. But it is possible to make it work in Pharo 4 to 6.0 by updating Metacello and installing Tonel.\n\n```Smalltalk\nMetacello new\n\tbaseline: 'Metacello';\n\trepository: 'github://Metacello/metacello:pharo-6.1_dev/repository';\n\tget.\nMetacello new\n\tbaseline: 'Metacello';\n\trepository: 'github://Metacello/metacello:pharo-6.1_dev/repository';\n\tonConflict: [:ex | ex allow];\n\tload.\nMetacello new \n\trepository: 'github://pharo-vcs/tonel';\n\tbaseline: 'Tonel';\n\tload.\n```\n\n### Tonel versions\n\nTonel got multiple versions over the years, each tweaking the export format:\n- version 1.0: original tonel export format\n- version 2.0: this version ensure that in the metadatas the keys are symbols and the values are strings. This change happened in order to be compatible with Gemstone. Note that this format was never used as a default export format of Pharo\n- version 3.0: this version has the changes of the 2.0 but it also adds the properties `package` and `tag` to replace the `category` property for class definitions. This is to remove same ambiguity in the class definitions. The `category` property is kept by default for backward compatibility, but the TonelWriter can be configured to not export this property. This format can also be improved to export more metadata. For example, it is planned to export a property `deprecatedAliases` to manage some class deprecations in the future.\n\nIf you want to change your export format and convert all the files of a repository at once to avoid to have multiple PR with format changes you can use the following script.\nTake a Pharo 12 or Pharo 13 images and run the following script. It will convert all the loaded packages in your image so you may load extra packages to prepare such operation. \n\n```st\n| projectName repository |\nprojectName := 'ProjectNameInIceberg'.\nrepository := IceRepository repositories detect: [ :repo | repo name = projectName ].\nrepository workingCopy packages do: [ :pkg |\nIceLibgitTonelWriter forInternalStoreFileOut: pkg latestVersion mcVersion on: repository ]\n```\n\n**NOTE: you must ensure all your project packages are loaded in the image (check in the Repository | Packages window, and right click load any that aren't).**\n\nOnce you have run this script, use the \"Repository, Project | Extra | Open in native file browser\" menu option to open an OS terminal and then run:\n```\ngit commit -a -m \"Update tonel formal to V3\"\ngit push\n```\n\nSince Pharo 12, it is also possible to indicate in a Tonel project which version of Tonel to use to export some code. The file to update is the `.properties` file that is in the source folder and it should look like this:\n\n```\n{\n    #format : #tonel,\n    #version: #'1.0' //could be 2.0 or 3.0\n}\n```\n\nThis is useful for example if a project has contributors on P11 using v1 format and contributors in P12 using v3 format since P11 is unable to export Tonel v3 format. \n\n## FileTree metadata less \n\nFileTree ([https://github.com/dalehenrich/filetree](https://github.com/dalehenrich/filetree)) is the first export format that was integrated in the goal to use Pharo with Git. The first version had a lot of metadata (see section Filetree metadata full), the second was a new version with metadata less format. \n\nThis format exports one file per method. This can cause trouble with Windows because Windows has a maximum path and file name length of 255 characters. This limit can easily be reached with FileTree. \n\nAnother problem of the FileTree format is that most Pharo's methods are short and creating one file by method waste a lot of space because the physical representation of files on a drive has a minimal size (4 KiB on NTFS file systems) that is reached by most of Pharo's method. \n\nIts advantage compared to FileTree metadata full is that there is no problem during the merge of the source code thanks to the absence of metadata.\n\n### FileTree metadata less Pros and Cons \n\nPros\n- Easy to browse the history of a method\n- Present since Pharo 4 out of the box\n- No problem during merge because of metadata\n\nCons\n- Cause trouble on Windows\n- Waste space on the file system\n\n### FileTree metadata less supported Pharo versions\n\nFileTree metadata less is supported out of the box since Pharo 4.0 and cannot easily be used in older Pharo versions. \n\n## FileTree metadata full\n\nFileTree metadata full ([https://github.com/dalehenrich/filetree](https://github.com/dalehenrich/filetree) )is the ancestor of FileTree metadata less and works in the same way but also export a lot of metadata relating to the commits such has a commit message (different from the one of the VCS), the timestamp of the method compilation, etc.\n\nThis simplifies the tooling because the tools can get some information from the metadata instead of the VCS but it also creates a lot of trouble while merging two branches using this format.\n\nMerges can be eased via this project: [https://github.com/ThierryGoubier/GitFileTree-MergeDriver](https://github.com/ThierryGoubier/GitFileTree-MergeDriver)\n\nThis format can be used via Monticello but not via Iceberg. Iceberg will ignore the format and export in FileTree metadata less.\n\n### FileTree metadata full Pros and Cons\n\nPros\n- Easy to browse the history of a method\n- Present in most Pharo versions out of the box\n\nCons\n- Cause trouble on Windows\n- Waste space on the file system\n- Hard to merge two branches because of metadata\n- Does not work with Iceberg, the default git tool since Pharo 7\n\n### FileTree metadata full supported Pharo versions\n\nThis format works out of the box in most Pharo versions.\n"
  },
  {
    "path": "General/Extensions.md",
    "content": "# Extensions\n\n- [Extensions](#extensions)\n  - [Use of Extension methods](#use-of-extension-methods)\n  - [Add a new extension method](#add-a-new-extension-method)\n    - [Define an extension method in versions prior to Pharo 7](#define-an-extension-method-in-versions-prior-to-pharo-7)\n    - [Define an extension method since Pharo 7](#define-an-extension-method-since-pharo-7)\n    - [Define an extension method programmatically](#define-an-extension-method-programmatically)\n  - [Find methods currently extending a class](#find-methods-currently-extending-a-class)\n    - [In versions prior to Pharo 7](#in-versions-prior-to-pharo-7)\n    - [Since Pharo 7](#since-pharo-7)\n    - [Find extensions programmatically](#find-extensions-programmatically)\n  - [Package loading order is important](#package-loading-order-is-important)\n\nPharo includes a system of extension methods. This feature allows the developer to add behavior (but not state) to existing objects in Pharo. \n\n> Note that it is only possible to add methods (behavior) as extension and not variables (state)\n\nThere is no syntactic difference between calling an extension method and calling a method declared in the class. The main difference between methods and extension methods is that extension methods are stored in a different package than the class they are implemented on.\n\n## Use of Extension methods\n\nExtension methods are useful when we want to use some behavior on an object, but it does not make sense to package it directly with the object. For example we might want to ask to a model object for information related to its display in a GUI, but to keep layers as cohesive as possible, we do not want display information stored in the code package of our application. In this case, we can add those methods to the model object but package those methods in a GUI package.\n\nAnother case might be when you want to enhance the behavior of a package that is simply not your own. You could add the methods to the class in the different package, but committing those changes to source control is not practical (i.e., you don't want to make a branch of the package, and doing a pull request would take a long time, etc.). With extension methods, the changes you make to the foreign package are stored in your own package, so they belong to you. \n\n## Add a new extension method\n\nInternally, an extension method is a method whose protocol has a pattern `*MyPackageExtendingMyClass`. \n\nHere is more detailed information about adding an extension method via Pharo's tooling.\n\n### Define an extension method in versions prior to Pharo 7\n\nIn the Pharo versions based on Nautilus system browser, extension methods are created when we categorize methods on a protocol beginning by a `*`.\n\n![Add an extension method via Nautilus 1](Extensions_Image_NautilusAddExtension1.png?raw=true \"Add an extension method via Nautilus 1\")\n\n![Add an extension method via Nautilus 2](Extensions_Image_NautilusAddExtension2.png?raw=true \"Add an extension method via Nautilus 2\")\n\n### Define an extension method since Pharo 7\n\nSince Pharo 7 the default system browser is Calypso. To add an extension method in Calypso you need to use the \"Move to package\" menu entry.\n\n![Add an extension method via Calypso](Extensions_Image_CalypsoAddExtension.png?raw=true \"Add an extension method via Calypso\")\n\nIf you already have extensions in this package, you can also select the package in the list of extending packages in the protocol pane before adding a method.\n\n### Define an extension method programmatically\n\n```Smalltalk\nExistingClass compile: 'myMethod\n\t^ true' classified: '*MyPackage'\n```\n\n## Find methods currently extending a class\n\nThere are two ways to find which methods are extensions where they are located:\n\n- Browse a class and check the protocols pane. (See examples below)\n\n- Look at a package and check the bottom of the class pane. The last classes will appear in grey and will be the classes extended in that package.\n\n### In versions prior to Pharo 7\n\n![See an extension method via Nautilus](Extensions_Image_NautilusSeeExtensions.png?raw=true \"See an extension method via Nautilus\")\n\n### Since Pharo 7\n\n![See an extension method via Calypso](Extensions_Image_CalypsoSeeExtensions.png?raw=true \"See an extension method via Calypso\")\n\n### Find extensions programmatically\n\nTo find extension methods programmatically you can do something like:\n\n```Smalltalk\n(Number methods select: #isExtension) groupedBy: #package\n```\n\n> **TODO: Add example of refactoring to an extension?**\n\n\n## Package loading order is important\n\nOne thing developers should take into account when using extensions is to have clean dependencies between its packages. A package extending classes from another package should be loaded *after* this package.\n\nFor example, if my package `MyProject-GUI` extends `MyProject-Model`, `MyProject-Model` should always be loaded *before* `MyProject-GUI` is. For more details, see the dependencies sections in the [baseline guide](Baselines.md).\n"
  },
  {
    "path": "General/Files.md",
    "content": "# Files\nTODO: explain how to manipulate files, paths, file systems, etc...\n"
  },
  {
    "path": "General/GithubActions.md",
    "content": "# Setting up your continuous integration via GitHub Actions\n\nPreviously, the Pharo community was heavily relying on Travis CI for the continuous integration of projects hosted on GitHub.\nBut Travis becoming pay-to-use service, the community created some tooling to manage the CI via GitHub Actions. \n\nThis guide will get you through the process to set up your own integration.\n\n> Note: In order to do anything for the CI of your project, you will need a `Baseline` to manage its dependencies. If it is not the case yet, you can check the [guide on baselines](Baselines.md).\n\n- [Setting up your continuous integration via Github Actions](#setting-up-your-continuous-integration-via-github-actions)\n  * [Simple case: Run tests on master branch](#simple-case-run-tests-on-the-master-branch)\n  * [SmalltalkCI options](#smalltalkci-options)\n    + [Load spec options](#load-spec-options)\n    + [Testing options](#testing-options)\n    + [Code Coverage](#code-coverage)\n    + [Using custom scripts](#using-custom-scripts)\n  * [Testing multiple versions of Pharo at once](#testing-multiple-versions-of-pharo-at-once)\n  * [Testing on multiple OS](#testing-on-multiple-os)\n  * [Manage the workflow target (branchs, PR, ...)](#manage-the-workflow-target-branchs-pr-)\n    + [Target branches](#target-branches)\n    + [Target pull requests](#target-pull-requests)\n    + [Target releases](#target-releases)\n    + [Target scheduled workflow](#target-scheduled-workflow)\n    + [Other targets](#other-targets)\n  * [Managing multiple workflows and SmalltalkCI configurations](#managing-multiple-workflows-and-smalltalkci-configurations)\n  * [Continuous releases](#continuous-releases)\n  * [Save releases artifacts](#save-releases-artifacts)\n  * [Depending on resources of your repository with GitBridge](#depending-on-the-resources-of-your-repository-with-gitbridge)\n  * [Add your build artifacts to PharoLauncher](#add-your-build-artifacts-to-pharolauncher)\n  * [External ressources](#external-ressources)\n\n## Simple case: Run tests on the master branch\n\nLet's start simple! This section will explain how to set up a workflow to launch the tests of the project on every commit done on the master branch.\n\nTo load our Pharo project in the CI and execute the tests, we'll use [SmalltalkCI](https://github.com/hpi-swa/smalltalkCI).\nThis project needs a configuration file to fetch information on your project. This file should be at the root of your project under the name of `.smalltalk.ston`. \n\nHere is the most simple configuration:\n\n```ston\nSmalltalkCISpec {\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'MyProject',\n      #directory : 'src'\n    }\n  ]\n}\n```\n\nThis configuration tells smalltalkCI two things:\n- The baseline to use to load the project is BaselineOf`MyProject`\n- The sources of the project are in /src\n\nNow that smalltalkCI configuration file is created, we just need to define your GitHub workflow file.\nThis file should be located in `.github/workflows/` folder. Let's call ours `testing.yml`.\n\n```yml\nname: CI\n\non:\n  push:\n    branches:\n      - 'master'\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-image: Pharo64-10\n      - run: smalltalkci -s ${{ matrix.smalltalk }}\n        shell: bash\n        timeout-minutes: 15\n```\n\nLet's see a little about what is happening here. \n\nThe #name parameter allows one to give a name to the workflow. This is useful because you might have more than one workflow for your project. \nFor example:\n\n![Example of different workflows](GitHubActions_workflows.png)\n\nIn this image, we can see a CI that has 3 different workflows:\n- CI\n- continuous\n- Release\n\nThen we have:  \n\n```yml\non:\n  push:\n    branches:\n      - 'master'\n```\n\nThis is used to define when the workflow should enter into action. In our case, we want it when we `push` on `master` branch.\n\nThen we have:\n\n```yml\n    runs-on: ubuntu-latest\n```\n\nWith this, the workflow will run in the latest version of Ubuntu.\n\n\n```yml\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\nThis step adds en environment variable needed by smalltalkCI.\n\nLast but not least, we have the actions to execute:\n\n```yml\n    steps:\n      - uses: actions/checkout@v3\n```\n\nUsing the \"checkout\" action to checkout the project on the CI worker.  \n\n```yml\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-image: Pharo64-10\n```\n\nUsing the \"setup-SmalltalkCI\" action to prepare the setup.\n\n```yml\n      - run: smalltalkci -s ${{ matrix.smalltalk }}\n        shell: bash\n        timeout-minutes: 15\n```\n\nLoads the project and executes the tests of the project with a 15min timeout.  \n\nThis timeout can be increased in case your project tests are longer.  \n\nOnce you commit these two files, your project will have a working CI !  \nEach time you commit to master, a new build should happen.  \nYou will be able to see the resulting build in the `Actions` tab in your project.\n\n## SmalltalkCI options\n\nWe have seen in the previous section that [SmalltalkCI](https://github.com/hpi-swa/smalltalkCI) relies on a configuration file. \nWe did a simple one to start, but there are more options available. We will cover them in this section.  \nThe full and up-to-date list is available in the [SmalltalkCI's README file](https://github.com/hpi-swa/smalltalkCI/blob/master/README.md).\n\n### Load spec options\n\nIn the previous example, we declared a loading spec with a baseline and a code directory. But it is also possible to add more options:\n\n```ston\nSCIMetacelloLoadSpec {\n  #baseline : 'MyProject',                            // Define MC Baseline\n  #directory : 'src',                                 // Path to packages, if packages are on root do not use #directory : '', just don't add this option\n  #failOn : [ #OCUndeclaredVariableWarning ],         // Fail build on provided list of Warnings\n  #ignoreImage : true,                                // If true, Metacello will force a load of a package, overriding a previously existing one\n  #load : [ 'default' ],                              // Define some specific groups to load\n  #onConflict : #useIncoming,                         // When there is a conflict between loaded sources and incoming sources (can be #useIncoming|#useLoaded)\n  #onUpgrade : #useIncoming,                          // When loaded sources are an older version than incoming sources (can be #useIncoming|#useLoaded)\n  #onWarningLog : true,                               // Log Warning messages to Transcript\n  #platforms : [ #squeak, #pharo, #gemstone ],        // Define compatible platforms\n  #usernameEnvVar : 'GITHUB_USER',                    // Environment variable containing the username used for authentication\n  #passwordEnvVar : 'GITHUB_TOKEN',                   // Environment variable containing the password used for authentication\n  #registerInIceberg : true                           // Pharo Only | Register the tested repository in Iceberg (false by default)\n}\n```\n### Testing options\nIt is also possible to customize the testing of the project:\n\n```ston\nSmalltalkCISpec {\n  ...\n  #testing : {\n    // Include specific TestCases\n    #include : {\n      #classes : [ #AnotherProjectTestCase ],\n      #categories : [ 'AnotherProject-Tests' ],\n      #packages : [ 'AnotherProject.*' ],\n      #projects : [ 'BaselineOfMyProject' ]\n    },\n\n    // Exclude specific TestCases from testing\n    #exclude : {\n      #classes : [ #AnotherProjectTestCase ],\n      #categories : [ 'AnotherProject-Tests' ],\n      #packages : [ 'AnotherProject.*' ],\n      #projects : [ 'ConfigurationOfMyOtherProject' ]\n    },\n\n    #allTestCases : true, // Run all TestCases in image\n\n    // Define TestCases explicitly\n    #classes : [ #MyProjectTestCase ],\n    #categories : [ 'MyProject-*' ],\n    #packages : [ 'MyProject.*' ],\n    #projects : [ 'BaselineOfMyProject' ],\n\n    // Other options\n    #defaultTimeout : 30, // In seconds (Squeak, and Pharo 6 or later)\n    #failOnSCIDeprecationWarnings : false, // Fail if a deprecated smalltalkCI API is used\n    #failOnZeroTests : false, // Pass builds that did not run any tests\n    #hidePassingTests : true, // Hide passing tests when printing to stdout\n    #serializeError: false // (default: true) Disable serialization of failing test case (e.g. with Fuel in Pharo)\n  }\n}\n```\n\n### Code Coverage\n\nIt is possible to see the coverage of our project via SmalltalkCI with [Coveralls](https://coveralls.io/).\n\nTo enable this, you need to add a \"coverage\" section in your configuration:\n\n```ston\nSmalltalkCISpec {\n  ...\n  #testing : {\n    ...\n    #coverage : {\n      #packages : [ 'SomePackage', 'SomePack*' ],\n      #classes : [ #ClassToCover ],\n      #categories : [ 'SomeClassCategory', 'SomeClassCat*' ],\n      #format : #coveralls\n    }\n  }\n}\n```\n\nFor example our project could look like:\n\n```ston\nSmalltalkCISpec {\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'Myproject',\n      #directory : 'src'\n    }\n  ],\n  #testing : {\n    #coverage : {\n      #packages : [ 'MyProject-*' ]\n    }\n  }\n}\n```\n\nThis configuration will execute all the tests loaded by the `BaselineOfMyProject` and build the coverage of all packages starting by `MyProject-` for [Coveralls](https://coveralls.io/).\nIf you enabled your repository in coveralls ([https://coveralls.io/repos/new](https://coveralls.io/repos/new)), the results would be uploaded automatically.\n\n![Coveralls screenshot](GithubActions_coveralls.png)\n\nFor more information, check: [SmalltalkCI guide on coverage](https://github.com/hpi-swa/smalltalkCI/blob/master/docs/COVERAGE.md).\n\n### Using custom scripts\n\nSmalltalkCI offers some hooks to be able to run some Pharo scripts at different moments of the project loading and testing.\nFour hooks are available:\n- `preLoading` : Executed before loading the project\n- `postLoading` : Executed after loading the project\n- `preTesting` : Executed before testing the project\n- `postTesting` : Executed after testing the project\n\nThose parameters can take 3 different parameters. \n\nThe first one is a single script:\n\n```ston\nSmalltalkCISpec {\n  #preLoading : 'scripts/preLoading.st',\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'Myproject',\n      #directory : 'src'\n    }\n  ]\n}\n```\n\nThe second one is a collection of scripts:\n\n```ston\nSmalltalkCISpec {\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'Myproject',\n      #directory : 'src'\n    }\n  ],\n  #postLoading : [\n    'scripts/postLoading1.st',\n    'scripts/postLoading2.st'\n  ]\n}\n```\n\nAnd the third one is an instance of SCICustomScript that allows running script only on certain platforms:\n\n```ston\nSmalltalkCISpec {\n  #preLoading : 'scripts/preLoading.st',\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'Myproject',\n      #directory : 'src'\n    }\n  ],\n  #postLoading : [\n    SCICustomScript {\n      #path : 'scripts/postLoadingSqueak.st',\n      #platforms : [ #squeak ]\n    },\n    SCICustomScript {\n      #path : 'scripts/postLoadingPharo.st',\n      #platforms : [ #pharo ]\n    }\n  ]\n}\n```\n\nHere is a full example:\n\n```ston\nSmalltalkCISpec {\n  #preLoading : 'scripts/preLoading.st',\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'Myproject',\n      #directory : 'src'\n    }\n  ],\n  #postLoading : [\n    'scripts/postLoading1.st',\n    'scripts/postLoading2.st'\n  ],\n  #preTesting : SCICustomScript {\n    #path : 'scripts/preTesting.st',\n    #platforms : [ #squeak, #pharo, #gemstone ]\n  },\n  #testing : ...,\n  #postTesting : [\n    SCICustomScript {\n      #path : 'scripts/postTestingSqueak.st',\n      #platforms : [ #squeak ]\n    },\n    SCICustomScript {\n      #path : 'scripts/postTestingPharo.st',\n      #platforms : [ #pharo ]\n    }\n  ]\n}\n```\n\nFor more informations on SmalltalkCI in general check: [SmalltalkCI documentation](https://github.com/hpi-swa/smalltalkCI).\n\n## Testing multiple versions of Pharo at once\n\nIt is rare to have a project working only on one version of Pharo. Thus, it is often useful to have our workflows run on multiple versions. \n\nThis can be achieved this way:\n\n```yml\nname: CI\n\non:\n  push:\n    branches:\n      - 'master'\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    strategy:\n      matrix:\n        smalltalk: [ Pharo64-9.0, Pharo64-10, Pharo64-11 ]\n    name: ${{ matrix.smalltalk }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-image: ${{ matrix.smalltalk }}\n      - run: smalltalkci -s ${{ matrix.smalltalk }}\n        shell: bash\n        timeout-minutes: 15\n```\n\nHere we declared a matrix with multiple versions of Pharo as axes:\n\n```yml\n    strategy:\n      matrix:\n        smalltalk: [ Pharo64-9.0, Pharo64-10, Pharo64-11 ]\n```\n\nEach axe will use the name of the Pharo version as name:\n\n```yml\n    name: ${{ matrix.smalltalk }}\n```\n\nBut this could also be another name, such as:\n\n```yml\n    name: MyProject-${{ matrix.smalltalk }}\n```\n\nThen the builds would be: `MyProject-Pharo64-9.0`, `MyProject-Pharo64-10` and `MyProject-Pharo64-11`.\n\nThe names will then be used to display the different builds on Github:\n\n![Screenshot of matrix](GithubActions_matrix.png)\n\nThe list of possible Pharo versions are:\n\n| 64bits           | 32bits           |\n| ---------------- | ---------------- |\n| `Pharo64-alpha`  | `Pharo32-alpha`  |\n| `Pharo64-stable` | `Pharo32-stable` |\n| `Pharo64-11`     | `Pharo32-11`     |\n| `Pharo64-10`     | `Pharo32-10`     |\n| `Pharo64-9.0`    | `Pharo32-9.0`    |\n| `Pharo64-8.0`    | `Pharo32-8.0`    |\n| `Pharo64-7.0`    | `Pharo32-7.0`    |\n| `Pharo64-6.1`    | `Pharo32-6.1`    |\n| `Pharo64-6.0`    | `Pharo32-6.0`    |\n|                  | `Pharo32-5.0`    |\n|                  | `Pharo32-4.0`    |\n|                  | `Pharo32-3.0`    |\n\n> Note: This list is from February 2023. More versions will be added in the future\n\n## Testing on multiple OS\n\nUsually, our Pharo projects are not influenced by the OS on which it runs. But in some cases, it can be important to test on multiple OS.\n\nThis can be achieved this way: \n\n```yml\nname: CI\n\non:\n  push:\n    branches:\n      - 'master'\n\njobs:\n  build:\n    strategy:\n      matrix:\n        os: [ macos-latest, windows-latest, ubuntu-latest]\n        smalltalk: [ Pharo64-9.0, Pharo64-10]\n    runs-on: ${{ matrix.os }}\n    name: ${{ matrix.smalltalk }} on ${{ matrix.os }}\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-image: ${{ matrix.smalltalk }}\n      - run: smalltalkci -s ${{ matrix.smalltalk }}\n        shell: bash\n        timeout-minutes: 15\n```\n\nAs we can see here:\n\n```yml\n        os: [ macos-latest, windows-latest, ubuntu-latest]\n    runs-on: ${{ matrix.os }}\n```\n\nWe declare that our project will be run on the latest macos, windows and ubuntu to covers the 3 major OS. \n\nTo distinguish the builds, we use the Pharo version and the OS name to name our builds:\n\n```yml\n    name: ${{ matrix.smalltalk }} on ${{ matrix.os }}\n```\n\n![Screenshot of ci matrix](GithubActions_os.png)\n\nYou can find more information on the available OS here: [https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners)\n\n## Manage the workflow target (branchs, PR, ...)\n\nIn our simple example at the beginning, we were launching the CI on the master branch, but you will often need to execute the CI on multiple branches.\n\n### Target branches\n\nIt is possible to target multiple branches at once. For example:\n\n```yml\non:\n  push:\n    branches:\n      - 'master'\n      - 'development'\n      - 'feature/**\n```\n\nThis will launch your workflow for every commit on `master`, `development` or any branch starting with `feature/`. \n\nYou can also target all branches in two ways. The first is by not specifying any:  \n\n```yml\non: [ push ]\n```\n\nThe second is to use `'**'`:\n\n```yml\non:\n  push:\n    branches:\n      - '**'\n```\n\nThis second way of declaring \"all branches\" is useful when you want to execute your workflow on all branches except some of them.\nIn that case, you can use:\n\n```yml\non:\n  push:\n    branches:\n      - '**'\n      - '!doc/**'\n```\n\nThis template will launch the CI for every commit on any branch except the ones starting with `doc/`.\n\n### Target pull requests\n\nIt is also possible to target others kinds of events.\nParticularly pull requests made to your project:\n\n```yml\non: [ push, pull_request ]\n```\n\nAnd be even more precise on the kinds of PR that should execute a workflow:  \n```yml\non:\n  pull_request:\n    types: [assigned, opened, synchronize, reopened]\n```\n\n\nNote that this can be done by addition of other targets:\n\n```yml\non:\n  push:\n    branches:\n      - '**'\n      - '!master'\n  pull_request:\n    types: [assigned, opened, synchronize, reopened]\n```\n\nHere the workflow runs on every pull request and every commit of any branch except `master`.\n\n### Target releases\n\nIt is also sometimes useful to have a workflow targeting releases. We'll exploit that later in this documentation.\nIn that case you can use:\n\n```yml\non:\n  release:\n    types: [created, edited]\n```\n\n### Target scheduled workflow\n\nIn some cases, it might be useful to target the workflow at specific times. \nFor example, it happens that some projects are \"meta project\". Their goal is to load a bunch of other projects. In that case, it's rare that a commit is made direcly in them.\nBut we want to run the CI on a regular basis to be sure our project still works. In that case, we can use a cron to schedule the workflow:\n\n```yml\non:\n  push:\n    branches:\n      - 'master'\n  schedule:\n    - cron:  '0 0 * * *'\n```\n\nSome utils will help you to configure the parameter of this target such as [Crontab.guru](https://crontab.guru/).\n\n### Other targets\n\nGitHub actions have way more options than the options presented here. The most useful ones were presented here, but you can find more information in [Github documentation](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on)\n\n## Managing multiple workflows and SmalltalkCI configurations\n\nUntil now, we managed only one workflow file, but it is possible to manage multiple of them.\n\nTo demonstrate this, let's imagine that our project has two groups in its configuration.\nThe first group loads the core of the project and is the default group of our baseline. \nA second group loads the full projects with additional features. \n\nWe would now like to have two workflows:\n- A first workflow launched on all branches and PR to test the core in Pharo 9, 10 and 11\n- A second workflow launched on master branch and PR to test the full project in Pharo 11\n\nThe first step is to get two smalltalkCI configurations.\n\nA first one will be the default `.smalltalk.ston`.\n\n```ston\nSmalltalkCISpec {\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'MyProject',\n      #directory : 'src'\n    }\n  ]\n}\n```\n\nAnd a second one loads the group `all` and is named `.smalltalkFull.ston`.\n\n```ston\nSmalltalkCISpec {\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'MyProject',\n      #directory : 'src',\n      #load : [ 'all' ]\n    }\n  ]\n}\n```\n\nNow that we have our two configurations, we can create our two workflow files. \n\nThe first one is close to what we have seen until here in this documentation:\n\n```yml\nname: CI Core\n\non: [ push, pull_request ]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        smalltalk: [ Pharo64-9.0, Pharo64-10, Pharo64-11 ]\n    name: ${{ matrix.smalltalk }}\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-image: ${{ matrix.smalltalk }}\n      - run: smalltalkci -s ${{ matrix.smalltalk }}\n        shell: bash\n        timeout-minutes: 15\n```\n\nIn the second, we change the targets, and we give one more parameter to the smalltalkCI launch command to specify the path to our specific Smalltalk configuration.\n\n```yml\nname: CI Full\n\non:\n  push:\n    branches:\n      - 'master'\n  pull_request:\n    types: [assigned, opened, synchronize, reopened]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    name: ${{ matrix.smalltalk }}\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-image: Pharo64-11\n      - run: smalltalkci -s ${{ matrix.smalltalk }} .smalltalkFull.ston\n        shell: bash\n        timeout-minutes: 15\n```\n\nEach file uses a different configuration file.\nThe first workflow file is named `CI` uses the default file `smalltalk.ston` implicitly.\nThe second workflow file is named `CI full` uses `smalltalkFull.ston` explicitly.\n\n\n```yml\n      - run: smalltalkci -s ${{ matrix.smalltalk }} .smalltalkFull.ston\n        shell: bash\n        timeout-minutes: 15\n```\n\n> Note: If we wanted to run on the same targets with two smalltalkCI configurations, we could also have used another matrix axis and avoid needing of different workflows.\n\nExample:\n\n```yml\nname: CI\n\non: [ push, pull_request ]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    strategy:\n      matrix:\n        smalltalk: [ Pharo64-9.0, Pharo64-10, Pharo64-11 ]\n        config: [ .smalltalk.ston, .smalltalkFull.ston ]\n    name: ${{ matrix.smalltalk }} - ${{ matrix.config }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-image: ${{ matrix.smalltalk }}\n      - run: smalltalkci -s ${{ matrix.smalltalk }} ${{ matrix.config }}\n        shell: bash\n        timeout-minutes: 15\n```\n\nHaving multiple workflows can have other usages that we explore in the next sections.\n\n## Continuous releases\n\nUntil now, we have used Github actions to test our project.  \nBut Github Actions has more features.  \nFor instance, we are able to realease our projects.  \n\nIn this section, we see how to save the result of the builds of our master branch in a github release.\n\nTo do that, we can first remove the master branch from the targets of our test workflow because we will handle the master branch in another workflow.\n\n```yml\non:\n  push:\n    branches:\n      - '**'\n      - '!master'\n  pull_request:\n    types: [assigned, opened, synchronize, reopened]\n```\n\nThen we will create another workflow called `.github/workflows/continuous.yml`.\n\n```yml\nname: continuous\n\non:\n  push:\n    branches:\n      - 'master'\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    env:\n      PROJECT_NAME: MyProject-${{ matrix.smalltalk }}\n    strategy:\n      matrix:\n        smalltalk: [ Pharo64-10, Pharo64-11 ]\n    name: ${{ matrix.smalltalk }}\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-version: ${{ matrix.smalltalk }}\n      - run: smalltalkci -s ${{ matrix.smalltalk }}\n        shell: bash\n        timeout-minutes: 15\n        \n      # Here we zip the result of the build to be able to keep the artefacts\n      - name: package\n        run: |\n          mv /home/runner/.smalltalkCI/_builds/* .\n          mv TravisCI.image $PROJECT_NAME.image\n          mv TravisCI.changes $PROJECT_NAME.changes\n          echo ${${{ matrix.smalltalk }}} | sed -e 's/.*\\-//g ; s/\\..*//g ; s/$/0/' > pharo.version\n          zip -r $PROJECT_NAME.zip $PROJECT_NAME.image $PROJECT_NAME.changes *.sources pharo.version\n          ls\n        \n      #Save the artefact of the build under \"continuous\" tag\n      - name: Update release\n        uses: johnwbyrd/update-release@v1.0.0\n        with:\n          release: 'continuous'\n          token: ${{ secrets.GITHUB_TOKEN }}\n          files: ${{ env.PROJECT_NAME }}.zip\n```\n\nThis workflow starts to like what we have seen until now. It checkout our project, install smalltalkCI and runs it. \nBut it also adds three steps to the process. \n\nThe first step is to give a name to our project. We will use that name to name our build artifact:\n\n```yml\n    env:\n      PROJECT_NAME: MyProject-${{ matrix.smalltalk }}\n```\n\nIn the second step, we rename the image produced by SmalltalkCI. We generate a version file that is useful in tools such as the `PharoLauncher`. And we zip the files in the archive to save.\n\n```yml\n      # Here we zip the result of the build to be able to keep the artefacts\n      - name: package\n        run: |\n          mv /home/runner/.smalltalkCI/_builds/* .\n          mv TravisCI.image $PROJECT_NAME.image\n          mv TravisCI.changes $PROJECT_NAME.changes\n          echo ${${{ matrix.smalltalk }}} | sed -e 's/.*\\-//g ; s/\\..*//g ; s/$/0/' > pharo.version\n          zip -r $PROJECT_NAME.zip $PROJECT_NAME.image $PROJECT_NAME.changes *.sources pharo.version\n          ls\n```\n\nThe last step is to publish the artifact in the continuous tag. For that we are using the action `johnwbyrd/update-release@v1.0.0`.\n\n```yml\n      #Save the artefact of the build under \"continuous\" tag\n      - name: Update release\n        uses: johnwbyrd/update-release@v1.0.0\n        with:\n          release: 'continuous'\n          token: ${{ secrets.GITHUB_TOKEN }}\n          files: ${{ env.PROJECT_NAME }}.zip\n```\n\n> Note: The name of the continuous release can be changed\n\nOnce this is done, each commit on master will result in updating the assets of the `continuous` release on GitHub to save the latest one.\n\n![Screenshot of continuous release](GithubActions_continuous.png)\n\n## Save releases artifacts\n\nWe have seen how to save the last artifact of a branch in a `continuous` release, but another case needs to be taken into account: the real releases.\n\nIt is useful when we release a project to save a Pharo image of this project with the version of the release.\n\nThis can be done with a new workflow file that will target releases:\n\n```yml\nname: Release\n\non:\n  release:\n    types: [created, edited]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    env:\n      PROJECT_NAME: MyProject-${{ matrix.smalltalk }}\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n    strategy:\n      matrix:\n        smalltalk: [ Pharo64-10, Pharo64-11 ]\n    name: ${{ matrix.smalltalk }}\n    steps:\n      - uses: actions/checkout@v3\n      - uses: hpi-swa/setup-smalltalkCI@v1\n        with:\n          smalltalk-version: ${{ matrix.smalltalk }}\n      - run: smalltalkci -s ${{ matrix.smalltalk }}\n        shell: bash\n        timeout-minutes: 15\n        \n      # Here we zip the result of the build to be able to keep the artefacts\n      - name: package\n        run: |\n          mv /home/runner/.smalltalkCI/_builds/* .\n          mv TravisCI.image $PROJECT_NAME.image\n          mv TravisCI.changes $PROJECT_NAME.changes\n          echo ${${{ matrix.smalltalk }}} | sed -e 's/.*\\-//g ; s/\\..*//g ; s/$/0/' > pharo.version\n          zip -r $PROJECT_NAME.zip $PROJECT_NAME.image $PROJECT_NAME.changes *.sources pharo.version\n          ls\n        \n      - name: Release\n        uses: softprops/action-gh-release@v1\n        with:\n          files: ${{ env.PROJECT_NAME }}.zip\n```\n\nThis file looks a lot like the one we wrote in the previous section.\n\nA few changes are to be noted. The is the name of the workflow to identify it easily in the Actions tab of Github.\nThe second is the target to build only on releases.\n\n```yml\non:\n  release:\n    types: [created, edited]\n```\n\nAnd the last change is the action used after creating our Pharo archive.\n\n```yml\n      - name: Release\n        uses: softprops/action-gh-release@v1\n        with:\n          files: ${{ env.PROJECT_NAME }}.zip\n```\n\nThis action will add the files matching the $files: property to the assets of the release.\n\n![Screenshot of releases](GithubActions_releases.png)\n\n## Depending on the resources of your repository with GitBridge\n\nIt happens in some projects that we need resources to do some tests. In the past, it was common to save those resources as a string or a byte array directly in a method of the project.\nThis makes can have multiple drawbacks like making the management of the project harder, dropping Pharo's performances in code management, no real versioning of those resources…\n\nNow that we can store our projects on git, an alternative is possible: Save your resources in your git repository and use file references in Pharo to access them.\n\nTo help with that, the project [GitBridge](https://github.com/jecisc/GitBridge) was created. \nThis project helps one to access resources from the git repository and information from git directly from the Pharo image.\n\nThis project can be added as a dependency of your project with this spec:\n\n```Smalltalk\n    spec\n    \tbaseline: 'GitBridge'\n    \twith: [ spec repository: 'github://jecisc/GitBridge:v1.x.x/src' ]\n```\n\nIn order to create a GitBridge to your project, you first need to subclass `GitBridge` and to store your bridge in a package of your project.\n\n```Smalltalk\nGitBridge subclass: #MyProjectBridge\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'MyProject'\n```\n\nThis new bridge needs a class initialization like this one:\n\n```Smalltalk\nMyProjectBridge class>>initialize\n\tSessionManager default registerSystemClassNamed: self name\n```\n\nThis will allow the bridge to reset some cache at the image startup.\n\nNow that your bridge is created, if it finds an Iceberg repository associated with its local clone containing the package in which the bridge is defined, you will be able to use the bridge to access some resources.\n\nFor example, you can get a file reference to the git folder like this:\n\n```Smalltalk\nMyProjectBridge root\n```\n\nAnd this allows you to access your test resources.\n\nOnce your project is using `GitBridge`, you just need to be sure of two things in order for the CI to work. \nThe first is to have the option `#registerInIceberg` to true in your smalltalkCI configuration.\n\n```ston\nSmalltalkCISpec {\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'MyProject',\n      #directory : 'src',\n      #registerInIceberg : true\n    }\n  ]\n}\n```\n\nAnd the second is to add a parameter to the checkout action of your workflow file in order to fetch the full history of git:\n\n```yml\n  steps:\n    - uses: actions/checkout@v3\n      with:\n        fetch-depth: '0'\n```\n\nOnce those steps are set up, your tests should be able to run and fetch resources from your git repository without trouble.\nFor more information, you can look at the [documentation of GitBridge](https://github.com/jecisc/GitBridge).\n\n## Add your build artifacts to PharoLauncher\n\n[Pharo launcher](https://pharo-project.github.io/pharo-launcher//) is a great tool to manage Pharo images, and here we are going to explain how to be able to get images of your project from it. \n\n> Note: In order to do this, you will need to have a continuous release and/or a release workflow setup as we explained earlier in this documentation.\n\nPharo launcher comes with a default set of sources to fetch Pharo images. It also allows one to add its own sources, and we will show here how to add your project as one of your own source.\n\nIt is doable thanks to the `mysources.list` of pharo-launcher file located in the `PhLUserTemplateSources sourcesFile` folder. If present, this file defines additional template sources beyond the official list of templates. At this time, there is no UI to add them.\n\nTo find the right folder:\n\n* Open the Pharo Launcher\n* Open a Playground (Ctrl + O, Ctrl + W)\n* Execute `PhLUserTemplateSources sourcesFile`\n\nYou can now edit `mysources.list` in this folder to add the images of your project you wish to have in your Pharo launcher.\n\nHere is how to add images from your continuous release:\n\n```st\n[\n\tPhLTemplateSource {\n\t\t#type : #URLGroup,\n\t\t#name : 'MyProject',\n\t\t#templates : [\n\t\t\tPhLTemplateSource {\n\t\t\t\t#type : #URL,\n\t\t\t\t#name : 'MyProject Pharo 10 - master',\n\t\t\t\t#url : 'https://github.com/MY_USERNAME/MY_PROJET_NAME/releases/download/continuous/MyProject-Pharo64-10.zip'\n\t\t\t},\n\t\t\tPhLTemplateSource {\n\t\t\t\t#type : #URL,\n\t\t\t\t#name : 'MyProject 11 - master',\n\t\t\t\t#url : 'https://github.com/MY_USERNAME/MY_PROJET_NAME/releases/download/continuous/MyProject-Pharo64-11.zip'\n\t\t\t}\n\t\t]\n\t}\n]\n```\n\nAnd here is how to add images from a specific release, lets say `v1.4.3`:\n\n```st\n[\n\tPhLTemplateSource {\n\t\t#type : #URLGroup,\n\t\t#name : 'MyProject',\n\t\t#templates : [\n\t\t\tPhLTemplateSource {\n\t\t\t\t#type : #URL,\n\t\t\t\t#name : 'MyProject Pharo 10 - v1.4.3',\n\t\t\t\t#url : 'https://github.com/MY_USERNAME/MY_PROJET_NAME/releases/download/v1.4.3/MyProject-Pharo64-10.zip'\n\t\t\t},\n\t\t\tPhLTemplateSource {\n\t\t\t\t#type : #URL,\n\t\t\t\t#name : 'MyProject Pharo 11 - v1.4.3',\n\t\t\t\t#url : 'https://github.com/MY_USERNAME/MY_PROJET_NAME/releases/download/v1.4.3/MyProject-Pharo64-11.zip'\n\t\t\t}\n\t\t]\n\t}\n]\n```\n\nYou can then adapt those sources to what you need. Once it is done, you can click on the `New` button of the launcher and see a new source named `MyProject`.\n\n## External ressources\n\nHere are some resources on GitHub actions and Pharo:\n- [https://badetitou.fr/blog/2020-11-30-Testing_pharo_with_github_actions](https://badetitou.fr/blog/2020-11-30-Testing_pharo_with_github_actions/)\n- [https://badetitou.fr/blog/2022-10-28-test-your-moose-code-using-ci](https://badetitou.fr/blog/2022-10-28-test-your-moose-code-using-ci)\n- [https://modularmoose.org/posts/2021-07-19-automatic-metamodel-documentation-generation](https://modularmoose.org/posts/2021-07-19-automatic-metamodel-documentation-generation)\n\nDo not hesitate to do a PR to add more resources ;)\n"
  },
  {
    "path": "General/Glossary.md",
    "content": "# Pharo vocabulary\nThe Pharo community uses specific vocabulary to designate object oriented concepts, Pharo concepts and Pharo tools.\n\nThis page aims to provide disambiguation for the words belonging to this vocabulary.\n\n## $a \nThe character a. In Pharo strings are composed of characters, a character starts with a $. For unprintable characters such as tab, just send the message to the class e.g., `Character tab`.\n\n## Binary message\nA binary message is a [message](#message) composed of special character(s) where two objects are involved (the [receiver](#receiver) and one argument), which is the reason it is call binary. This is mostly used for arithmetic, comparison, and logical operations. For example, `+` is a binary message involving the receiver and the argument in parameter.\n\n## Bootstrap\nAccording to [wikipedia](https://en.wikipedia.org/wiki/Bootstrapping),\n\n> \"Bootstrapping usually refers to a self-starting process that is supposed to proceed without external input.\"\n\nIn the case of Pharo, [images](#image) are bootstrapped from the sources. Anyone can download the sources and [create their own custom Pharo image](https://github.com/carolahp/pharo/tree/candle). The Pharo [continuous integration server](https://ci.inria.fr/pharo-ci-jenkins2/job/Test%20pending%20pull%20request%20and%20branch%20Pipeline/) launch the bootstrap process each time a pull-request is merged into [pharo repository](https://github.com/pharo-project/pharo).\nThis seems to be a natural process but one has to know that up to Pharo 7.0, images were not bootstrapped. This means that, each version of Pharo was in fact a copy of the previous image with some additional changes.\n\n## Browser\nThe browser is the tool for browsing and editing packages, classes and methods. In Pharo 6.1 and greater, the browser is called Calypso.\n\n## Candidates\nIn the context of a method-call the candidates are the potential classes in the system that can receive the call. This list is computed from a static analysis of the source code.\n\n## Changes (file)\nThe changesfile logs all source code modifications (especially all the changes you did while programming) since the [sources file](#sources) was generated. This facilitates a per-method history for diffs or reverting. It means that even if you did not manage to save the image file on a crash or you just forgot to, you can recover your changes from this file. A changes file is always coupled with an image file. They work as a pair.\n\n> Note: Since Pharo 5, a project called Epicea implementing a new logging system has been introduced in the system. The long term goal of Epicea is to replace the changes file, but this objective has not been reached yet.\n\n## Class-side\nThe class-side of a class refers to its meta-class. This meta-class contains methods that can be sent to the class directly.\nFor example, `#x:y:` method (which creates an instance of `Point` with arbitrary x and y coordinates) is held by the meta-class of `Point`.\n\nIn Pharo, both `Class` and `Metaclass` understand `#classSide` method.\nFor example:\n\n```Smalltalk\nPoint classSide. \"Point class\"\nPoint class classSide. \"Point class\"\nPoint includesSelector: #x:y:. \"false\"\nPoint class includesSelector: #x:y:. \"true\"\n```\n\nThe best way to understand what the class-side is, is to have a look at `#classSide` methods implementations:\n\n```Smalltalk\nClass>>#classSide\n\t^ self class\n```\n\n```Smalltalk\nMetaclass>>#classSide\n  ^ self\n```\n\n## Cog\nCog is the name of the [virtual machine](#virtual-machine) used by Pharo.\nIt is also used by other programming languages such as [Squeak](#squeak), Newspeak and Cuis.\n\n## Context\nA *Context* represent a program execution. It will store, for example, the `CompiledMethod` being currently executed, the receiver and arguments of the message that invoked this `CompiledMethod`, the temporary variables, the stack of calls until the moment of the execution, ...\nIn Pharo, you can use the keyword `thisContext` to interact with the current context of your code. It will return the `Context` object at the moment of the execution. This object is different on each method call.\n\n## Debugger\nThe *Debugger* is a tool opened by the system when an exception is raised and never got caught. This tool allows the developer to interact with the execution [context](#context) that raised the error and its previous contexts. It lets the users inspect the objects present in this context and updates the code to fix the bug using the execution information as help.\n\n## Dispatch\nDispatch is a technique used in object-oriented programming to delegate behavior using [polymorphism](#polymorphism). The goal is to define a concept that will change depending on the context. For example we can have an application with commands. When we need to execute the commands, instead of creating a switch/case, each object will implement its own behaviour on a method of the same name and we just need to call this method. \n\n## DNU\nSee [DoesNotUnderstand](#doesnotunderstand).\n\n## DoesNotUnderstand\nThis name is used to describe the error that arises when a [message](#message) is sent to an object but the object does not understand it. It also happens that people use the \"DNU\" shortcut.\n\n## Iceberg\n*Iceberg* is git client integrated in the system since Pharo 7 (Pharo 6.1 contained a technical preview of the tool). It is a set of tools that allows one to handle git repositories directly from a Pharo image. Iceberg is the default repository manager for Pharo, allowing for smoother and faster integration of contributions, as well as better branch and version management.\n\n## Image\nA Pharo image is a snapshot of Pharo memory at any given moment.\nThis is the file where all objects are stored and as such, it’s a cross platform format.\nAn image file contains the live state of all objects of the system (including classes and compiled methods, since they are objects too) at a given point.\nIt can bee seen as a virtual object container.\n\n## Implementors\nFor a given selector in the system, implementors are classes that have a method with this selector (they implement the selector). For example the implementors of the method `#banana` are all the classes containing a method named `#banana`.\n\n## Inspector\nThe *Inspector* is a Pharo tool which allows one to inspect objects, see their current state, interact with them and display specific information depending on the object. It offers multiple views and it uses a Finder as a navigation. One particular feature is that you can use the evaluator tab to enter code, and evaluating it results in the opening of another pane to the right.\n\n## Instance\nAn instance is a concrete realisation of a class.\nOne can send [messages](#message) to an instance.\nThese messages correspond to methods defined by the class related to the instance.\nAll instances of a class share the behaviour (methods) and structure ([slots](#slot)) defined by the class but two instances can hold different data in their [slots](#slot).\n\n## Instance-side\nThe instance-side of a meta-class refers to its class. This class contains methods that can be sent to its instances.\nFor example, `#x` method (which returns the x coordinate of a point) is held by the class `Point`.\n\nIn Pharo, both `Class` and `Metaclass` understand `#instanceSide` method.\nFor example:\n\n```Smalltalk\nPoint instanceSide. \"Point\"\nPoint class instanceSide. \"Point\"\nPoint includesSelector: #x. \"true\"\nPoint class includesSelector: #x. \"false\"\n```\n\nThe best way to understand what the instance-side is, is to have a look at `#instanceSide` methods implementations:\n\n```Smalltalk\nClass>>#instanceSide\n\t^ self\n```\n\n```Smalltalk\nMetaclass>>#instanceSide\n  ^ self soleInstance\n```\n\n## Instance variable\nSee [slot](#slot).\n\n## Keyword message\nA keyword message is a [message](#message) where two or more objects are involved (the [receiver](#receiver) and the arguments). A message is composed of alphanumeric characters. The arguments are injected inside the message selector and must be preceded by a colon (`:`). For example, `between:and:` is a keyword message with a receiver and two arguments. It can be used like this: `13 between: 12 and: 14`.\n\n## Late binding\n*Late binding* (or *dynamic binding*) is a general mechanism in which methods or functions called are [looked up](#lookup) at run-time. This mechanism is the opposite of *early binding* that does the lookup at compilation-time and fixes all types of variables during that time.\nMore concretely, it means that in Pharo, when you send a [message](#message) to an object, the lookup of the method to execute is performed and then the method found by the lookup is executed. This simplifies the use of reflectivity since the user can invoke new methods without recompiling the whole application.\n\n## Lookup\nMethod lookup is the name of the technique Pharo uses to find the method to execute when an object receives a [message](#message). It proceeds as follows: When a message is sent, methods in the [receiver](#receiver)'s class are searched for a matching method. If no match is found, the superclass is searched, and so on up the class chain. In the end, if no method is found, the object calls the method [`#doesNotUnderstand:`](#doesnotunderstand) with the message as a parameter.\n\n## Message\nA message represents an interaction between two objects.\nA [sender](#sender) sends a message to a [receiver](#receiver) which will start a [lookup](#lookup).\nA message is composed of two elements: the selector, which is the name of the method to lookup, and argument values which are the values of each argument of the method to execute once found by the lookup.\nThree kinds of messages exists: [unary messages](#unary-message), [binary messages](#binary-message) and [keyword messages](#keyword-message).\n\n## Message-send\n\n## Monticello\n*Monticello* is a distributed versioning system for [Squeak](#squeak) and Pharo code. It was the main versioning system until Pharo 6. It is now recommended to use [Iceberg](#iceberg).\n\n## Object\nThe word object is used to refer to a particular [instance](#instance) of a [class](#class). \"Object\" and \"instance\" words are synonyms.\n\n## Playground\nThe playground / workspace designate a code editor allowing one to run Smalltalk code that is not contained in a method.\nThis tool is useful to run small scripts that can be thrown after the execution.\nIf one needs to write a script that needs to be kept for a long time, it is better to right it as a class-method with the `<script>` pragma.\n\n## Polymorphism\n\n## Pragma\nPragmas are annotations on methods. They are used to attach additional properties to the methods to make those methods easily collectable through reflectivity and to ease the creation of special handlings.\nA page dedicated to pragmas is available [here](Pragmas.md).\n\n## Primitive\nA primitive is a method for which the source code is not written in Smalltalk but directly in C code. From the inside of the image, those methods contain a `<primitive:>` pragma.\n\nSome methods holding this primitive pragma also contain source code written in Smalltalk. For these methods, first the C version of the method is tried but if the implementation in C is not provided by the VM for some reason, Pharo falls back to the Smalltalk implementation.\n\n## Protocol\nIn Pharo, each method belongs to a protocol. A protocol has a name and allows one to group methods that are related. For example, the protocol `accessing` is widely used in the system to hold accessor and mutator methods.\n\n## Receiver\nThe receiver of a [message](#message) send is the instance of a class implementing the method corresponding to the message sent receiving this message.\n\n## Selector\nA selector corresponds to the signature of a method in the system. Since Pharo is not statically typed, the selector of a method is simply a Symbol. On a CompiledMethod, it is possible to send the `#selector` message to retrieve this Symbol.\n\n## Self\nSelf is the [receiver](#receiver) of a [message](#message) an object sends to itself. This means that the [lookup](#lookup) of a method send will start by the sender of this message then, if not found, it will proceed with its superclass.\n\n## Sender\nThe sender of a [message](#message) is the object that will send a message to another object. In case the [receiver](#receiver) of a message is [self](#self), then the sender is equal to the receiver.\n\n## Senders\nFor a given selector in the system, senders are the methods sending a message with this selector. For example, the senders of the method `#banana` are all the methods sending the message `#banana` in their code.\n\n## Sista \nSista is the name of a [virtual machine](#virtual-machine) with adaptive optimisations such as speculative inlining (meaning that the Virtual machine tries to guess the type of receiver and the arguments. Based on this, it heavily optimises the code at runtime, in case of a wrong guess it de-optimises the code). It showed better performance but is still currently under development. It is not yet production-ready.\n\n## Slang\nThe term \"Slang\" refers to a subset of the Smalltalk language that can be translated to C (or other language, such as Javascript). It is mainly used to develop the [Cog](#cog) virtual machine. It allows one to develop the virtual machine using Pharo tools and generates C.\n\n## Slot\nInstance variables are reified in Pharo, which means they are real objects that can be manipulated just like any other object.\nBecause of that, the name *slot* has been given to the general concept of an instance variable in Pharo.\nIn practice, most of the slots in classes of the system are `InstanceVariableSlot`.\nOne can create a new kind of slot by subclassing `Slot` class (see [this blogpost](https://medium.com/@juliendelplanque/typed-slots-for-pharo-98ba5d5aafbe) as an example).\n\n## Smalltalk\nSmalltalk is an object-oriented, dynamically typed reflective programming language with multiple implementations. Some implemenations include [Squeak](#squeak), VisualWorks, Gemstone, VA Smalltalk and many others. Pharo started as an implementation of Smalltalk and is still very close to it.\n\n## Sources (file)\nThe sources file contains source code of Pharo. Sources file is important because the image file format stores only objects including compiled methods and their bytecode and not their source code. Originally, a new sources file was generated once per major release of Pharo. Now, Pharo changed its production mechanism to be [bootstraped](#bootstrap) and generates a new sources file for each Pharo image produced.\n\n## Spur\nSpur is the name of the current object representation in memory of Pharo used by the [virtual machine](#virtual-machine). This representation is used since Pharo 5 and was introduced to improve performances (by 30% compared to the previous implementation) and prepare Pharo to run in 64bits.\n\n## Squeak\nSqueak is a dialect of [Smalltalk](#smalltalk). Pharo started as a fork of Squeak and both still share the same [virtual machine](#virtual-machine).\n\n## Super\nSuper is the [receiver](#receiver) of a [message](#message) an object send to itself, but on the contrary of [self](#self), the method lookup will start in the superclass of a receiver. Super is a unique way for the class to add behavior to the inherited methods and not just replace them.\n\n## Traits\nTraits are pure units of behavior that can be composed to form classes or other traits. The trait composition mechanism is an alternative to multiple or mixin inheritance in which the composer has full control over the trait composition. It enables more reuse than single inheritance without introducing the drawbacks of multiple or mixin inheritance.\nA page dedicated to traits is available [here](Traits.md).\n\n## Unary message\nAn unary message is a [message](#message) where only the [receiver](#receiver) of the message will be required, which is the reason it is called unary. This means that the message will have no argument. For example, `#factorial` is an unary message that will only require the number receiving the message.\n\n## VM\nSee [virtual machine](#virtual-machine).\n\n## Virtual Machine\nThe virtual machine of Pharo is the execution engine. It takes Pharo bytecode that is generated each time the user compiles a piece of code, converts it to machine code and executes it. The VM is different for each platform running Pharo (windows, OSX, linux, arm, 32/64bits) and allows the other part of Pharo to be platform independent.\n\n## Workspace\nWorkspace is the previous name of the [Playground](#playground).\n"
  },
  {
    "path": "General/HowToRunPharoFromCommandLine.md",
    "content": "# Getting Pharo running from the command line\n\nHere are some simple steps to get Pharo ready from the command line. The script \nassumes that you have a bin folder in your home directory. \n\nThe following script downloads the stable vm version of Pharo 80. Check the web page [https://get.pharo.org/64/](https://get.pharo.org/64/)\nto get the possible choices. \n\n```bash\nmkdir bin\ncd bin\ncurl https://get.pharo.org/64/vm80 | bash\n```\n\nThis script creates two scripts, pharo-ui and pharo-vm both using the contents of the Pharo folder that is also created. \n\nOnce installed you can execute pharo as follows: \n\n```bash\n./pharo-ui Pharo8.image \n```\n\nIf you do not want Pharo displaying a user interface as a pop-up, you can invoke it as follows: \n\n```bash\n./pharo Pharo8.image \n```\n"
  },
  {
    "path": "General/IcebergOnWindows.md",
    "content": "# Iceberg on Windows Workaround\n\n- [Make path to the Pharo Image shorter](#make-path-to-the-pharo-image-shorter)\n- [Convert the repository to the Tonel format](#convert-the-repository-to-the-tonel-format)\n\nLong file names in Windows raise the error message  “Failed to stat file ‘filename’: The filename or extension is too long”.\n\nThe Windows problem with long filenames is a constraint of [libgit](https://libgit2.org/libgit2/#HEAD) library that is used in Pharo (Iceberg accesses git through this exact library). It occurs because FileTree format tends to have long paths and was one of the main drivers in creating the Tonel format. This error can occur, for example, when you are trying to clone your Pharo fork on Github into Pharo local. There are two possible ways to fix it:\n\n1. Make path to Pharo Image short.\n2. Convert repo to Tonel format — in Iceberg there is a menu item under one of the Extras menus.\n\nHere’s more about them:\n\n## Make path to the Pharo Image shorter\n\nIf you are simply using a standalone Pharo [download](http://pharo.org/download/#standalone), you can just move your image and VM a few folders up. However, if you are using [Pharo Launcher](http://pharo.org/download/), you have to access the settings, to change where it stores images it will create in the future, as well as move all the existing images and VMs up. Here’s how to do it.\n\nIn Pharo Launcher, in the bottom right corner you can see a button ‘open settings’ — click on it.\n\n![alt text](https://github.com/myroslavarm/pharo-wiki/blob/patch-1/General/win_2.png)\n\nIn the settings, if you expand the ‘Pharo Launcher’ tab you can see the following options:\n\n![alt text](https://github.com/myroslavarm/pharo-wiki/blob/patch-1/General/win_3.png)\n\nIn the first, third and fourth options, change directories without disrupting the dependencies (images in ‘images’, template sources one folder up, etc). When you change the paths, the upper right corner of each of the text boxes will be yellow, which means unsaved changes (that is also the logic inside Pharo). You have to position your cursor in each of the text boxes and press (ctrl+s) to save the changes.\n\nDon’t forget that this section only means images and VMs it will create in the future, so you should also manually move your already existing images and VMs to the same folder you listed. \n\nNow, everything should work!\n\n## Convert the repository to the Tonel format\n\nNote re FileTree/Tonel: A FileTree represents a hierarchy of files. [Tonel](https://github.com/pharo-vcs/tonel) is a file-per-class format — class and all methods are stored in a single file, which is better than having a file for each method because the code is easier to read outside of Pharo and it creates less files on the hard drive. Tonel also prevents some trouble with git on Windows due to number of files and subdirectory depth that create path exceeding windows limit.\n\nIf you are using an older version of Pharo, you need to download Tonel by running the code below in a playground (in Pharo 7 and 8 it comes by default):\n\n```Smalltalk\nMetacello new\n  baseline: 'Tonel';\n  repository: 'github://pharo-vcs/tonel:v1.0.12';\n  load.\n```\n\n> Note: In Pharo 7 and 8 you don’t need any kind of script to convert to Tonel — there’s a UI option available. But in Pharo 6.1 you need to upgrade Iceberg first, and Tonel will come with it. Link with the script [here](https://github.com/pharo-vcs/iceberg/#for-pharo-61).\n\nWith Tonel loaded, if you go to Iceberg repositories and right-click on the specific repository, you can go to ‘extra’ category and click on ‘convert repository sources to tonel’ button. It will migrate the code for you.\n\n![alt text](https://github.com/myroslavarm/pharo-wiki/blob/patch-1/General/win_4.png)\n\n> Note: this option is only possible if the repository isn’t already in the Tonel format. So if your problem is cloning the Pharo fork (Pharo repo is partially Tonel, partially Filetree), then the only option that will actually solve it, is  shortening the path.\n\n\n"
  },
  {
    "path": "General/ImageFileFormat.md",
    "content": "# Image file format\nPharo image is a binary file containing a snapshot of the runtime.\nHowever, there is only a little documentation about its structure (how information is encoded as bytes).\nThis page is an early work to document the binary format of Pharo images.\n\n- [Determinate the format of an image](#determinate-the-format-of-an-image)\n- [Image format accross Pharo versions](#image-format-accross-pharo-versions)\n\n## Determinate the format of an image\nEach image has a format. The format can be retrieved by reading the 4 first bytes of an image file.\nThese bytes encode an integer from least significant to most significant byte (little-endian).\n\nOn MacOS, you can use `od` shell command to show these 4 bytes:\n\n```bash\nod -t x1 -N 4 Pharo.image\n```\n\nYou will get an output as follow:\n\n```\n0000000    b5  09  01  00                                                \n0000004\n```\n\nWhich correspond to `68021` in decimal.\n\n## Image format accross Pharo versions\n\n| Pharo version                | Image format code | Image first 4 bytes (hex) |\n|:-----------------------------|:------------------|:--------------------------|\n| version <= 1.3               | 6504              | 68  19  00  00            |\n| 1.3 < version <= 5.0-preSpur | 6505              | 69  19  00  00            |\n| version (32bits) >= 5.0      | 6521              | 79  19  00  00            |\n| version (64bits) >= 5.0      | 68021             | b5  09  01  00            |\n"
  },
  {
    "path": "General/Inspector.md",
    "content": "# Inspector\n\n*Written based on Pharo 12.0.0 - Build information: Pharo-12.0.0+build.710.sha9e02d19b14a8ecb9cbd45d6ba0166d3b92202c3c (64 Bit)*\n\nThe Inspector is a tool that is used to look at an object. In Pharo, inspecting an object means opening this tool. It allows to navigate the object structure and look at the state of the variables, but can show other information.\n\nYou can inspect the result of an execution by selecting the code and using the shortcut`Cmd/ctrl + i` or `right-clic + \"Do & inspect it\"`. This will execute the code and open an inspector on the result. \n\n\nThe  [🐥 Learn Keyboard Shortcuts \\[W1-Live D\\]](https://www.youtube.com/watch?v=7YTsys2qxMU&list=PL2okA_2qDJ-kCHVcNXdO5wsUZJCY31zwf&index=10&t=133s) video from the [Pharo MOOC](https://mooc.pharo.org/) demonstrate how to open it.\n\nBy inspecting `1/3` we get the following inspector :\n\n![Raw tab](Inspector_raw_tab.png)\n\n\n## A first look at the inspector\n\n![Raw tab areas](Inspector_raw_tab_areas.png)\n\nThe tree framed areas in the next pictures are :\n1. This text starts with the **class** of the inspected object. Here we have an instance of Fraction.\n2. This is the raw view object. It shows the internal state of the object. Here the fraction as a `numerator` instance variable holding the value 1, and a `denominator` instance variable holding the value 3. \n\nThis is a tree list. When you see the small grey triangle on the left side, by clicking it you can unfold the state of the object inside the instance variable. \nBy clicking on an instance variable you can also open a new inspector pane.\n\nThis is recursive : if you click on more variables, more pane will open. By default only the last two panes are visible at any time. You can use the small rectangles at the bottom of the window to navigate in the opened pane. You can also choose how many panes and showing at the same times and which one. \n\nHere is a small demonstration :\n![Navigating in the inspector](Inspector_pane_navigation.gif)\n\n3. This last area is the evaluator. In this area you can write expression and evaluate them like you would do it in the playground. In a given evaluator, `self` is referring to the inspected object. This can be seen in the raw view above the evaluator showing the value of the `self` variable.\n\n## The pane tool bar\n\nEach inspector pane has the following toolbar :\n\n\n![Raw tab areas](Inspector_pane_toolbar.png)\n\n- The **last button** allows one to open a browser on the class of the inspected object. It can be used to check for available methods to use in the evaluator\n- The **green glasses** button opens another inspector window on the current object\n- The **circling arrows** button allow to refresh the crurent view of the object. Fields of an object are not updated live, so if the object is modified from elsewhere, the new values will only show if the refresh button is used.\n- The **triangle button** is related to object-centric debugging. It allows one to put breakpoints on state access (read and/or write) of a specific object.The following animation shows how to put a breakpoint on writing an instance variable, the `Breakpoints` tab listing breakpoints on the current object and how to deactivate one :\n\n![Breakpoints](Inspector_breakpoints.gif)\n\n## The Meta tab : searching for methods and class hierarchy\nThe `Meta` tab is the last one that is available on most objects.\nOn the left it shows the class hierarchy of the current object's class and on the right the methods available. Clicking on parent classes in the hierarchy will show methods implemented in this class on the right. Selecting a method will display its source code at the bottom of the tab.\n\n\n![Meta tab](Inspector_meta_tab.png)\n\n## Creating custom tabs\n\nIf you used the inspector a bit, you might have noticed that some objects have additional tabs showing up in the inspector.\nFor example both Floats and Integer have their first tabs showing different representations of the numbers :\n\n![Inspecting numbers](Inspector_numbers_tabs.png)\n\nAnother example is the `FileReference` class. When a file reference is inspected, according to the type of the file, different tab show up with relevant information.\n\nCreating a new tab requires being able to build UI elements called presenters with spec 2. For more explanation on how to build a spec 2 presenters, please see the [Spec 2 documentation](https://github.com/SquareBracketAssociates/BuildingApplicationWithSpec2/tree/master).\n\nFor people building visualisation, [Roassal 3](https://github.com/ObjectProfile/Roassal3) visualisations can be embedded in a spec 2 presenter by sending the `asPresenter` message to an instance of RSCanvas.\n\nThe following sections will explain how to add a few additional tabs to instances of `OrderedCollection`. This class already as a custom tab showing the list of its items which is defined by its superclass `Collection`.\n\n### Adding a tab with text\n\nLet's add a first tab containing a text describing the first element of the collection. Define the following method :\n\n```Smalltalk\nOrderedCollection << inspectionFirstElement\n\n\t<inspectorPresentationOrder: 1 title: 'First Element'>\n\n\t^ SpTextPresenter new text: 'The first element is ', self first asString; beNotEditable; yourself\n```\n`<inspectorPresentationOrder: 1 title: 'First Element'>` is a pragma that is detected when creating an inspector on an object. When creating an inspector on an instance of `OrderedCollection`, this method will now be used to generate a tab. The title of the tab will be `First Element`, it will be in position 1 in the order of tabs.\n\nThe content of the tab is returned by the method. Here we are creating a text presenter with the content we want and we specify it should not be editable.\n\nThis gives us the following result :\n\n![First element tab](Inspector_expension_first_element.png)\nWe notice that our new tab is in second position. This is because in `Collection<<inspectionItems:` (the method defining the Items tab) the order parameter is 0.\n\n### Adding a tab with a table and conditions on when to display it\n\nLet's create a new tab that will display a table only when the collection contains only numbers. It will show each number and the results of 2 times that number.\n\nFirst let's create the tab with the table:\n```Smalltalk\nOrderedCollection << inspectionMultipliedByTwo\n\n\t<inspectorPresentationOrder: 10 title: 'Multiply by 2'>\n\t| presenter |\n\tpresenter := SpTablePresenter new\n\t\t             addColumn:\n\t\t\t             ((SpStringTableColumn\n\t\t\t\t               title: 'Item'\n\t\t\t\t               evaluated: #yourself)\n\t\t\t\t              width: 30;\n\t\t\t\t              yourself);\n\t\t             addColumn: (SpStringTableColumn\n\t\t\t\t              title: 'Multiply by 2'\n\t\t\t\t              evaluated: [ :each | each * 2 ]);\n\t\t             items: self;\n\t\t             beResizable;\n\t\t             yourself.\n\t^ presenter\n```\nIf we inspect a collection of numbers we get the following tab :\n![Mutliplied by 2 tab](Inspector_expension_multiplied_by_two.png)\n\nHowever if the collection contains elements that are not numbers, the tab crashes and looks like a red rectangle. By defining a method with the name `<name of the method defining the tab>Context:` we can specify when we want to activate a given tab.\nFor example :\n```Smalltalk\nOrderedCollection << containsOnlyNumbers \n\t^ self allSatisfy: [ :each | each isNumber  ]\n\n\nOrderedCollection << inspectionMultipliedByTwoContext: aContext\n\t^ aContext active: self containsOnlyNumbers.\n```\nWill ensure that the tab will be displayed only when there is only number in the collection.\n\n\n\n## Adding a raw view of a specific element of the collection and removing the evaluator\n\nWe can also add a tab showing the raw view of the max value :\n```Smalltalk\nOrderedCollection << inspectionIMaxValue\n\t<inspectorPresentationOrder: 5 title: 'Max Value'>\n\t^ StRawInspectionPresenter on: self max.\n\nOrderedCollection << inspectionIMaxValueContext: aContext\n\t^ aContext active: self containsOnlyIntegers.\n```\n![Inspect max value tab](Inspector_expension_max.png)\n\nHowever as we can see above, the self in the evaluator does not match the self in the max value which is confusing so we will hide the evaluator.\n\n```Smalltalk\nOrderedCollection << inspectionIMaxValueContext: aContext\n\taContext withoutEvaluator.\n\t^ aContext active: self containsOnlyIntegers.\n```\nBy reinspecting the same collection we get :\n![Removing the evaluator](Inspector_expension_max_without_evaluator.png)\n\n### How to add Roassal charts ?\nAs said above, Roassal, allow one to build visualisations.\nThe library includes some common graphs like the histogram for example.\nLet's add a histogram of the values if there are only numbers in the collection :\n\n```Smalltalk\n\nOrderedCollection << inspectionIntegerHistogram\n\n\t<inspectorPresentationOrder: -1 title: 'Histogram'>\n\t| plot |\n\tplot := RSHistogramPlot new x: self.\n\t^ plot asPresenter\n\n\nOrderedCollection << inspectionIntegerHistogramContext: aContext \n\n\taContext active: self containsOnlyIntegers.\n\taContext withoutEvaluator.\n```\nBy inspecting `{ 1 . 1 . 3 . 2 . 5 . 2. 2 . 1. 9. 3 . 2. 2. 5 . 7 . 7 . 8  } asOrderedCollection` we get :\n![Histogram tab](Inspector_expension_histogram.png)\n\n\n"
  },
  {
    "path": "General/InterestingsToKnowForBeginners.md",
    "content": "# Interesting things to know for beginners\n\nThis page will expose different things that might be interesting to know for beginners. Tools, API, shortcuts...\n\nThe goal is to ease the use of Pharo for beginners.\n\n- [API](#api)\n- [Evaluatable objects (Blocks and Symbols)](#evaluatable-objects--blocks-and-symbols-)\n- [Tools](#tools)\n  * [Calypso System Browser](#calypso)\n- [Flags](#flags)\n- [Useful pragmas](#useful-pragmas)\n  * [Modify IDE](#modify-ide)\n  * [Influence execution of methods](#influence-execution-of-methods)\n  * [Influence Debugger](#influence-debugger)\n\n## API\n\nThe Pharo API is extensive. In this section we will explain various methods existing in Pharo that have proven to be useful in our experience.\n\n**String class>>#streamContents:**\n\nString concatenation can be costly because it will create a new string instance and copy the content of the two strings at each concatenation. To make it more efficient, Pharo includes a method to create a String via a stream:\n\n```Smalltalk\n'This is a ', 'string concatenation ' , 'that is not really' , ' ' , ' efficient'.\n\nString streamContents: [ :aStream | aStream << 'This is a '<< 'string concatenation ' << 'that is ' << ' ' << ' efficient' ]\n```\n\n## Evaluatable objects (Blocks and Symbols)\nPharo's Blocks and Symbols have an interesting property: they are polymorphic through `#value:` and `#cull:` methods.\n\nFor example, the two code snippets below are equivalent:\n\n```Smalltalk\n#class value: Object new\n```\n\n```\n[ :o | o class ] value: Object new\n```\n\nThey both return the class of an object.\n\nThis means that for methods taking a one-argument block as a parameter, this block can be replaced by a symbol. The effect is that the unary method named by the symbol will be executed with the object as the receiver.\n\nThe difference between `#value:` and `#cull:` is that `#value:` requires a parameter when `#cull:` can work with or without a parameter.\n\nThe common usage of this feature is via iterators. For example, if you want to collect the result of the `name` method of all objects in a collection you can either do:\n\n```\nobjectCollection collect: [ :o | o name ].\n```\n\nor\n\n```\nobjectCollecton collect: #name\n```\n\nThe second way is shorter and often more readable.\n\n## Tools\n\n### Calypso (System browser)\n\n- Display the differences between two methods\n\t* Click on a method\n\t* Hold down the `SHIFT` key\n\t* Click on the second method\n\t* Click on the tab Diff to see the differences\n\t\n- Editing multiple methods side by side\n\t* Click on a method\n\t* Hold down the `CTRL` key\n\t* Click on all the methods you want to edit. \n\t* Tabs are displayed with the source code of the methods selected.\n\n## Flags\n\nIt is possible to \"flag\" methods in Pharo in order to be able to retrieve them later. This can be done by sending the `#flag:` message to self with a symbol as parameter which is the flag to be used.\n\nCommonly used flags are:\n- `#todo` to mark code that needs work to be done.\n- `#hack` to mark hackish code.\n- `#broken` to mark broken code.\n- `#clean` to mark code that needs cleaning.\n- `#toCheck` to mark code that should be checked later.\n- `#pharoX` to mark code present for compatibility with `X` being the version of Pharo.\n\nFlags will not modify the execution of a method. Flags are just used to tag methods.\n\nFor example, the method below will return `42` if executed as if there was no call to `#flag:` method.\n\n```\nmyUnfinishedMethod\n\tself flag: #TODO. \"Some process to be done here.\"\n\t^ 42\n```\n\nTo retrieve methods for which you set flag(s), just search for senders of your flag. For example, to retrieve methods flagged with `#todo`, either inspect the result of the following script: `#todo senders` or just select the symbol and press Meta+N (shortcut for \"Browse senders\").\n\n## Useful pragmas\n\nPragmas allow one to tag methods. They are similar to Java's annotations. Some pragmas allow the developer to modify the IDE or to influence execution of methods. This section presents some of these useful pragmas.\n\n### Modify IDE\n\n- `<script>` for class-side methods, adds a button next to the method name in the IDE. This button, when clicked, executes the method.\n- `<script: 'Smalltalk code to run'>` is similar to `<script>` but the button executes the Smalltalk code held by the string provided as parameter to the pragma.\n- `<sampleInstance>` for class-side methods, adds a button next to the method name in the IDE. When clicked, the method is executed and an inspector is opened on its result.\n- `<worldMenu>` for class-side methods, add a menu entry in the Pharo menu. The method with this pragma should take a builder as a parameter. You can browse the senders of the `worldMenu` pragma to find the API.\n- `<systemsettings>` for class-side methods, add an entry in the Pharo settings. The method with this pragma should take a builder as a parameter. You can browse the senders of the `systemsettings` pragma to find the API.\n- `<haltOrBreakpointForTesting>` should be used in methods using breakpoints that should not be listed in the Breakpoint browser. For example, it can be used in examples using breakpoints to highlight a feature of the example.\n\n### Influence execution of methods\n\n- `<expectedFailure>` for instance-side methods of subclasses of `TestCase`, will make the test green when it is failing. But, although we expect that the test will fail, a success of the test (i.e. not assertion missed) will show as a failure.\n\n### Influence Debugger\n- `<debuggerCompleteToSender>` allows one to tell the debugger to open itself on the method that sends the message corresponding to the method holding the `<debuggerCompleteToSender>` pragma.\n\nFor example, let us consider these two methods:\n```st\nfoo\n\t<debuggerCompleteToSender>\n\tError signal: 'foo'\n```\n\n```st\nfooCaller\n\tself foo\n```\n\nBecause of the `<debuggerCompleteToSender>`, when `#fooCaller` is executed, the debugger will show `#fooCaller` method source code.\nIf the pragma was not there, the debugger would show `#foo` method source code.\n"
  },
  {
    "path": "General/Layout.md",
    "content": "# Mohpic's Layouts\n\nThe Morphic Library of Pharo is a low level UI framework. This page aims at describing how to layout morphes together.\n\n- [Mohpic's Layouts](#mohpic-s-layouts)\n  * [Row layout](#row-layout)\n  * [Table Layout](#table-layout)\n  * [Stack Layout](#stack-layout)\n  * [Proportionnal layout](#proportionnal-layout)\n  * [Annexe](#annexe)\n\n\n## Row layout\n\nThis layout displays a morph's submorphs horizontally aligned.\nBy default, the submorphs display start at the topLeft corner of the morph.\nWith this layout, the submorphs are display in a array. This array associate a submorph with a cell of the array.\nThe size of a cell in Y depends of the max size of the morph in Y. However, the length in X of a cell depends of the size of the submorph who are displayed in this cell.\nWe modify the display of the submorph with several attribut :\n- `cellPositioning` takes several values : center, bottomLeft, bottomRight, topLeft, topRight. This value allow to modify the display of the submorphs.\n- `cellInset` : set a space between each cell of the morph, it takes an integer.\n- `extent` : set the size of the morph, it takes a point.\n- `hResizing` : allows to modify a morph horizontally. It takes several value : shrinkWrap, spaceFill, rigid.\n  - `rigid` allows to not modify the morph\n  - `shrinkWrap` resizes the morph to fit the frame of his submorph\n  - `spaceFill` fills the empty space with this morph\n- `vResizing`: allows to modify a morph vertically. It takes the same value as hResizing.\n\nExample 1 : Row layout with two morphs\n\n![alt text](layout_screenshot/RowLayoutExampleWithTwoMorph.png)\n```st\n| m1 m2 m3|\nm1 := Morph new layoutPolicy: RowLayout new; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.`\n```\nExample 2 : Row layout with three morphs\n\n![alt text](layout_screenshot/RowLayoutExampleWithThreeMorph.png)\n```st\n| m1 m2 m3 m4|\nm1 := Morph new layoutPolicy: RowLayout new; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow.\nm4 := Morph new color: Color purple.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 addMorph: m4.\nm1 openInWorld.\n```\nExample 3 : Row layout with two morphs with cellPositioning : bottomLeft\n\n![alt text](layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionBottomLeft.png)\n```st\n| m1 m2 m3|\nm1 := Morph new color: Color blue; layoutPolicy: RowLayout new;extent: (200@200);cellPositioning: #bottomLeft; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; extent: (100@100); yourself.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld .\n```\nExample 4 : Row layout with two morphs with cellPositioning : center\n\n![alt text](layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionCenter.png)\n```st\n|m1 m2 m3|\nm1 := Morph new color: Color blue; layoutPolicy: RowLayout new; extent: (200@200); cellPositioning: #center; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; extent: (100@100); yourself.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld .\n```\n\nExemple 5 : Row layout example with two morphs with cellPositioning : topLeft\n\n![alt text](layout_screenshot/RowLayoutExampleWithTwoMorphCellPositionTopLeft.png)\n```st\n|m1 m2 m3|\nm1 := Morph new color: Color blue; layoutPolicy: RowLayout new; extent: (200@200); cellPositioning: #topLeft; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; extent: (100@100); yourself.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld .\n```\n\nExemple 6 : Row layout with hResizing and vResizing : spaceFill\n\n![alt text](layout_screenshot/RowLayoutwithvResizingAndhResizingAtSpacefillForOneMorph.png)\n```st\n| m1 m2 m3|\nm1 := Morph new layoutPolicy: RowLayout new; yourself.\nm1 extent: 250@250.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color purple.\nm2 vResizing: #spaceFill.\nm2 hResizing: #spaceFill.\nm3 extent: 100@100.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExemple 7 : Row layout with hResizing and vResizing : shrinkWrap\n\n![alt text](layout_screenshot/RowLayoutwithvResizingAndhResizingAtshrinkWrap.png)\n```st\n| m1 m2 m3|\nm1 := Morph new layoutPolicy: RowLayout new; yourself.\nm1 vResizing: #shrinkWrap.\nm1 hResizing: #shrinkWrap.\nm1 extent: 250@250.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color purple.\n\nm3 extent: 100@100.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\n## Table Layout\n\nThe layout is processed like this:\nFor computing the new layout for the children of any morph, we start with an initial rectangle which is provided as a reference.\n\nStep 1: The first step of this layout computation is to compute the minimum extent each of our children can have. The minimum extent is mapped through both the local layout frame of the morph (for relative positioning) and the global layout frame (for insets, such as cursor indication) to obtain the minimal size required for each cell.\n\nStep 2: Based on the cell sizes, the number of cells we can put into each row and column is computed. For equal spacing, the maximum size of the cells is taken into account here.\n\nStep 3: Based on the row/column sizes, we compute the extra space which should be added to each row/column. For:\n- `#leftFlush/#topFlush` - we add all extra space add the end\n- `#rightFlush/#bottomFlush` - we add all extra space at the start\n- `#centering` - we add 1/2 of the extra space at start and end\n- `#justified` - we distribute the space evenly between the morphs\n> NOTE: If any #spaceFill morphs are encountered during this step, #justified is implied and the space is exclusively and equally distributed between those #spaceFill morphs. This is for backward compatibility and should *never* be necessary in the new regime.\n\nStep 4: The morphs are placed in the computed cells and the extra space is distributed as necessary. Placing the submorphs is done by mapping through the global and the local layout frame as requested.\n\nStart point:\n=> bounds: new rectangle for the morph.\n\nCompute basic arrangement of morphs:\n=> For each submorph compute minExtent\n- if global layout frame inset in global layout frame\n- if local layout frame inset in local layout frame\n=> Compute number of morphs per, width and height of row/column\n- if equal spacing based on max size\n=> Compute extra space per row/column\n- if centering = #justified; distribute space equally\n- if centering #leftFlush/#topFlush (-1) add start extra\n- if centering #rightFlush/#bottomFlush (1) add end extra\n- if centering #centered add 1/2 extra to start/end\n<extra space must be float and rounded accordingly!>\n=> Place morphs in appropriate cells\n- if global layout frame inset in global layout frame\n- if local layout frame inset in local layout frame\n<will likely cause #layoutChanged by submorphs>\n\nDistribute morphs in row/column:\n\n=> Compute the max length of each row/column\n\nExample 1 : Table layout with two morphs\n\n![alt text](layout_screenshot/TableLayoutExampleWithTwoMorph.png)\n```st\n|m1 m2 m3|\nm1 := Morph new layoutPolicy: TableLayout new; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExample 2 : Table layout with three morphs\n\n![alt text](layout_screenshot/TableLayoutExampleWithThreeMorph.png)\n```st\n|m1 m2 m3 m4|\nm1 := Morph new layoutPolicy: TableLayout new; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow.\nm4 := Morph new color: Color purple.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 addMorph: m4.\nm1 openInWorld.\n```\n\nExemple 3 : Table layout with two morphs with cellPositioning : center\n\n![alt text](layout_screenshot/TableLayoutExampleWithTwoMorphWithCenteringMorph.png)\n```st\n|m1 m2 m3|\nm1 := Morph new color: Color blue; layoutPolicy: TableLayout new; extent: (200@200); cellPositioning: #center; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; extent:  (100@100); yourself.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExemple 4 : Table layout with two morphs with cellPositioning : topLeft\n\n![alt text](layout_screenshot/TableLayoutExampleWithTwoMorphWithTopLeftMorph.png)\n```st\n|m1 m2 m3|\nm1 := Morph new color: Color blue; layoutPolicy: TableLayout new; extent: (200@200); cellPositioning: #topRight; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; extent: (100@100); yourself.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExemple 5 : Table layout with two morphs with cellPositioning : topRight\n\n![alt text](layout_screenshot/TableLayoutExampleWithTwoMorphWithTopRightMorph.png)\n```st\n|m1 m2 m3|\nm1 := Morph new color: Color blue; layoutPolicy: TableLayout new; extent: (200@200); cellPositioning: #topLeft; yourself.\nm2 :=  Morph new color: Color green.\nm3 := Morph new color: Color yellow; extent: (100@100); yourself.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExemple 6 : Table layout with vResizing and hResizing : shrinkWrap.\n\n![alt text](layout_screenshot/TableLayoutWithverticalandHorizontalShrinkwrapResizing.png)\n```st\n| m1 m2 m3 m4|\nm1 := Morph new layoutPolicy: TableLayout new; yourself.\nm1 vResizing: #shrinkWrap.\nm1 hResizing: #shrinkWrap.\nm1 extent: 1500@1500.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow.\nm4 := Morph new color: Color purple.\nm4 extent: 100@100.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 addMorph: m4.\nm1 openInWorld.\n```\n\nExemple 7 : Table layout with vResizing and hResizing : spaceFill\n\n![alt text](layout_screenshot/TableLayoutWithVResizingAndhResizingAsSpacefill.png)\n```st\n| m1 m2 m3|\nm1 := Morph new layoutPolicy: TableLayout new; yourself.\nm1 extent: 250@250.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color purple.\nm2 vResizing: #spaceFill.\nm2 hResizing: #spaceFill.\nm3 extent: 100@100.\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExemple 8 : Table layout with wrapCentering : center\n\n![alt text](layout_screenshot/TableLayoutWithWrapCenteringCenter.png)\n```st\n| m1 m2 m3 |\nm1 := Morph new layoutPolicy: TableLayout new; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; layoutPolicy: TableLayout new; yourself.\nm1 extent: 200@200.\nm1 wrapCentering: #center.\nm1 addMorph: m2.\nm3 extent: (100@100).\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExemple 9 : Table layout with wrapCentering : bottomRight\n\n![alt text](layout_screenshot/TableLayoutWithWrapCenteringbottomRight.png)\n```st\n| m1 m2 m3 |\nm1 := Morph new layoutPolicy: TableLayout new; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; layoutPolicy: TableLayout new; yourself.\nm1 extent: 200@200.\nm1 wrapCentering: #bottomRight.\nm1 addMorph: m2.\nm3 extent: (100@100).\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExemple 10 : Table layout with wrapCentering : topLeft\n\n![alt text](layout_screenshot/TableLayoutWithWrapCenteringtopLeft.png)\n```st\n| m1 m2 m3 |\nm1 := Morph new layoutPolicy: TableLayout new; yourself.\nm2 := Morph new color: Color green.\nm3 := Morph new color: Color yellow; layoutPolicy: TableLayout new; yourself.\nm1 extent: 200@200.\nm1 wrapCentering: #topLeft.\nm1 addMorph: m2.\nm3 extent: (100@100).\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\n## Stack Layout\n\nUnstack the submorphs at the center of the morph in default.\nIt could be a problem if the last submorph unstack was bigger than the other submorph, because the last one was display on the other.\nIt takes several attribut but the most relevant attribut was :\n- cellPositioning\n- extent\ncellPositioning set the point of reference to display morph. For example, if the value was center, the morphs were gonna display with the center, if the value was : topRight, they gonna stack on the top right corner of parent morph\n\nExample 1 : Stack layout with two morphs with lower morph extent\n\n![alt text](layout_screenshot/StackLayoutExampleWithTwoMorphWithLowerMorphExtent.png)\n ```st\n|m1 m2 m3|\nm1 := Morph new layoutPolicy: StackLayout new; yourself.\nm2 :=  Morph new color: Color green; extent: (100@100); yourself.\nm3 := Morph new color: Color yellow .\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n```\n\nExample 2 : Stack layout with two morphs with upper morph extent\n\n![alt text](layout_screenshot/StackLayoutExampleWithTwoMorphWithUpperMorphExtent.png)\n ```st\n|m1 m2 m3|\nm1 := Morph new layoutPolicy: StackLayout new ; yourself.\nm2 :=  Morph new color: Color green.\nm3 := Morph new color: Color yellow; extent: (100@100); yourself .\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n ```\nExemple 3 : Stack layout with two morphs with cellPositioning : topRight\n\n![alt text](layout_screenshot/StackLayoutExampleWithTwoMorphCellPositioningTopRight.png)\n```st\n|m1 m2 m3|\nm1 := Morph new layoutPolicy: StackLayout new; cellPositioning: #topRight; yourself.\nm2 :=  Morph new color: Color green; extent: (100@100); yourself.\nm3 := Morph new color: Color yellow .\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.  \n```\n\nExemple 4 :  Stack layout with two morphs with cellPositioning : bottomRight\n\n![alt text](layout_screenshot/StackLayoutExampleWithTwoMorphCellPositioningBottomRight.png)\n```st\n|m1 m2 m3|\nm1 := Morph new layoutPolicy: StackLayout new; cellPositioning: #bottomRight; yourself.\nm2 :=  Morph new color: Color green; extent: (100@100); yourself.\nm3 := Morph new color: Color yellow .\nm1 addMorph: m2.\nm1 addMorph: m3.\nm1 openInWorld.\n ```\n\n## Proportionnal layout\n\nThis layout allows to modify the relative size of a submorph when the size of the container change.\nThe goal is to change proportionnaly to the size of the morph.\nFor doing this, the submorph need a frame where it will be display.\nThis frame is a percentage of the morph.\nFor example: if we give a frame of (0 @ 0 corner: 0.5 @ 0.5) to a submorph, it occupies 25% of the morph.\nAnd if we resize the container, the size of the submorph will be resize proportionaly to stay with a occupied frame of 25%.\n\nExemple 1 : Proportionnal layout with 25% of the morph area.\n\n![alt text](layout_screenshot/ProportionnalLayoutWithLeftTop50perX50perY.png)\n```st\n|frame sub|\nm1 :=SystemWindow new.\nm1 layoutPolicy: ProportionalLayout new.\nframe := (0 @ 0 corner: 0.5 @ 0.5) asLayoutFrame .\nsub := Morph new color: Color red.\nm1 addMorph: sub fullFrame: frame.\nm1 extent:300@300.\nm1 openInWorld.\n```\nExemple 2 : Proportionnal layout with 50% of the morph area.\n\n![alt text](layout_screenshot/ProportionnalLayoutWithLeftTop50perY.png)\n```st\n|frame sub|\nm1 :=SystemWindow new.\nm1 layoutPolicy: ProportionalLayout new.\nframe := (0 @ 0 corner: 1.0 @ 0.5) asLayoutFrame .\nsub := Morph new color: Color red.\nm1 addMorph: sub fullFrame: frame.\nm1 extent:300@300.\nm1 openInWorld.\n```\nExample 3 : Proportionnal layout with 100% of the morph area.\n\n![alt text](layout_screenshot/ProportionnalLayoutExampleWithSystemWIndowWithFulllWindow.png)\n```st\n|frame sub|\nm1 :=SystemWindow new.\nm1 layoutPolicy: ProportionalLayout new.\nframe := (0 @ 0 corner: 1.0 @ 1.0) asLayoutFrame .\nsub := Morph new color: Color red.\nm1 addMorph: sub fullFrame: frame.\nm1 extent:300@300.\nm1 openInWorld.\n```\nExample 4 : Proportionnal layout with 2 Morph, each Morph was display on 50% of the morph area.\n\n![alt text](layout_screenshot/ProportionnalLayoutExampleWithSystemWIndowWithTwoMorph.png)\n```st\n|frame sub|\nm1 := SystemWindow new.\nm1 layoutPolicy: ProportionalLayout new.\nframe := (0 @ 0 corner: 1.0 @ 1.0) asLayoutFrame .\nsub := Morph new layoutPolicy: TableLayout new.\nm3 := Morph new color: Color green; yourself.\nm2 := Morph new color: Color red; yourself.\nsub addMorph: m2 fullFrame: frame.\nsub addMorph: m3 fullFrame: frame.\nm1 addMorph: sub fullFrame: frame.\nm1 extent: 300@300.\nm1 openInWorld.\n```\n\nExample 5: Proportional layout with scrollbar\n![alt text](layout_screenshot/ProportionnalLayoutWithScrollBar.png)\n```st\n| window scrollPane pasteUpMorph |\n\twindow := Morph new layoutPolicy: ProportionalLayout new.\n\twindow extent: (500@500).\n\tscrollPane := ScrollPane new.\n\tpasteUpMorph := Morph new color: Color yellow .\n\tpasteUpMorph extent: 1000@1000.\n\tscrollPane scroller addMorph: pasteUpMorph.\n\twindow addMorph: scrollPane fullFrame: (0@0 corner: 1@1).\n\n\twindow openInWorld.\n```\n\n## Annexe\n\nNo minimal size in particular\n"
  },
  {
    "path": "General/MenuBar.md",
    "content": "# Menubar and World menu\n\nIn Pharo, to open tools or execute actions a Menubar (At the top of the screen) and a WorldMenu (Appears on a left click in the world) are present.\n\nThis page will document some aspects of those features. \n\n- [Disable the Menubar/WorldMenu](#disable-the-menubarworldmenu)\n- [Add your own entries](#add-your-own-entries)\n  * [Add a simple entry](#add-a-simple-entry)\n  * [Add a sub menu](#add-a-sub-menu)\n- [Change the menu](#change-the-menu)\n\n![MenuBar_Image_WhatIsMenuBarAndWorldMenu.png](./MenuBar_Image_WhatIsMenuBarAndWorldMenu.png)\n\n## Disable the Menubar/WorldMenu\n\nIn some case, we want to hide the menubar and/or the world menu. For example, when releasing a new version of a project to deploy, the development tools need to be hidden. \n\nIt is possible to do that with some settings.\n\n**Disable Menubar**\n\nThis option is named `Show menubar` in the setting browser and is equivalent of executing:\n\n```Smalltalk\nMenubarMorph showMenubar: false\n```\n\n**Disable the WorldMenu**\n\nIt is not possible to disable this feature alone (without disabling the Menubar) in Pharo <= 7. \n\nIn Pharo 8 it is possible to disable the WorldMenu alone with the setting named `Show world menu` or by executing:\n\n```Smalltalk\nPasteUpMorph shouldShowWorldMenu: false\n```\n\n**Disable WorldMenu and Menubar**\n\nTo disable both the menubar and the world menu it is possible to disable each of them individually, or to change the setting `World menu pragma` to set an empty pragma. Programmatically, it can be done this way:\n\n```Smalltalk\nWorldState desktopMenuPragmaKeyword: ''\n```\n\n## Add your own entries\n\nIt is possible to add entries to the world menu and menu bar.\n\nTo build the menu, Pharo uses a pragma mecanism. Each class method containing a pragma `<worldMenu>` will be executed with a menu builder as parameter. The method should then configure the builder to add the needed entries.\n\n### Add a simple entry\n\nTo add a simple entry, one need to create and configure a new item in the builder.\n\nHere is a minimal example of a new entry toogling the `Show deprecation warnings` setting:\n\n```Smalltalk\nMyClass class>>toggleDeprecationWorldMenuOn: aBuilder\n\t<worldMenu>\n\t(aBuilder item: #ToggleDeprecation)\n\t\taction: [ Deprecation raiseWarning: (Deprecation raiseWarning) not ]\n```\n\nThen multiple things can be configured. \n\n- `order:` : Takes a number as parameter and sort the entries with those values from the minimal to the maximal value.\n- `help:` : Takes a string as parameter and display at is a tooltip on a long mouse over the menu entry.\n- `iconName:` : Takes a symbol as parameter and display an icon correspongding to the name next to the menu entry. (See [this page for more infos](CoolSnippets.md#browse-all-available-icons))\n- `icon:` : Takes a `Form` as parameter and use it to display next to the menu entry.\n- `label:` : Takes a string as parameter and replace the display text of the menu entry from the item name to the string.\n- `action:` : Takes a block as parameter and execute it when the entry is clicked.\n- `withSeparatorAfter` : Add a separator in the UI after this entry.\n\n```Smalltalk\ntoggleDeprecationWorldMenuOn: aBuilder\n\t<worldMenu>\n\t(aBuilder item: #ToggleDeprecation)\n\t\torder: 10;\n\t\thelp: 'Toggle the show deprecation setting';\n\t\ticonName: #tools;\n\t\tlabel: 'Toggle deprecation';\n\t\taction: [ Deprecation raiseWarning: (Deprecation raiseWarning) not ];\n\t\twithSeparatorAfter\n```\n\n### Add a sub menu\n\nIt is possible to have submenus in the Menubar. This can be achieve in two ways. \n\nThe first way is to create a new menu and add the children in a `#with:` block.\n\nExample:\n\n```Smalltalk\nextensionsWorldMenuOn: aBuilder\n\t<worldMenu>\n\t(aBuilder item: #Extensions)\n\t\torder: 5;\n\t\ticonName: #add;\n\t\twith: [ (aBuilder item: #ToggleDeprecation)\n\t\t\t\torder: 10;\n\t\t\t\thelp: 'Toggle the show deprecation setting';\n\t\t\t\ticonName: #tools;\n\t\t\t\tlabel: 'Toggle deprecation';\n\t\t\t\taction: [ Deprecation raiseWarning: Deprecation raiseWarning not ];\n\t\t\t\twithSeparatorAfter ]\n```\n\nThe second way is to define the submenus in a different place and to use the `#parent:` method to link it to its menu.\n\nExample:\n\n```Smalltalk\nextensionsWorldMenuOn: aBuilder\n\t<worldMenu>\n\t(aBuilder item: #Extensions)\n\t\torder: 5;\n\t\ticonName: #add\n```\n\n```Smalltalk\ntoggleDeprecationWorldMenuOn: aBuilder\n\t<worldMenu>\n\t(aBuilder item: #ToggleDeprecation)\n\t\tparent: #Extensions;\n\t\torder: 10;\n\t\thelp: 'Toggle the show deprecation setting';\n\t\ticonName: #tools;\n\t\tlabel: 'Toggle deprecation';\n\t\taction: [ Deprecation raiseWarning: Deprecation raiseWarning not ];\n\t\twithSeparatorAfter\n```\n\n## Change the menu\n\nIt is also possible to totally change the Menubar and WorldMenu in case you do not like the current one, or if you want to create a menu for your application. \n\nIn order to do so, you need to define your own pragma to use by executing this code:\n\n```Smalltalk\nWorldState desktopMenuPragmaKeyword: 'myOwnMenu'\n```\n\nThen you can follow the previous section replacing the `<worldMenu>` pragma by `<myOwnMenu>` in the examples.\n"
  },
  {
    "path": "General/MustKnowForBeginners.md",
    "content": "# Must know for beginners\n\nThis page includes knowledge about thing the Pharo community think important to know as a Pharo beginner.\n\n\n- [Navigate into the code](#navigate-into-the-code)\n  * [Browse, Senders and Implementors](#browse-senders-and-implementors)\n  * [Method source with it](#method-source-with-it)\n- [Interrupt the Pharo process](#interrupt-the-pharo-process)\n- [Debugging facilities](#debugging-facilities)\n\n## Navigate into the code\n\nPharo offers a lot of ways to navigate into the code, and most of those are used daily by Pharo developers. This section will highlight the most important ones.\n\n### Browse, Senders and Implementors\n\nWhen reading code we often need to open an entity or to check who is using an entity. To do that, Pharo has different commands:\n* **Browse** (`CMD/CTRL + b`): This command will open a new system browser on the class you are currently focusing on\n* **Senders/References** (`CMD/CTRL + n`): This command will open a message browser with all the methods calling the method/symbol you are currently focusing on, or, in the case where you are focusing on a class, the references to this class. \n* **Implementors** (`CMD/CTRL + m`):  This command will open a message browser with all the methods whose name is the name of the method/symbol you are currently focusing on, or, in the case where you are focusing on a class, the references to this class like `browse`. \n\nAlternatively, it is possible to navigate the code using the mouse and the keyboard. In most text editors of Pharo you can use the shortcut `CMD + (Shift +) click` on OSX or `Alt + (Shift +) right click` on Windows/Linux to browse senders, implementors, classes and references. \n\nUsing `CMD + click` on OSX or `Alt + right click` on Windows/Linux allows one to:\n- Browse the implementors when you click on a method.\n- Browse the class when you click on a class.\n- Browse the class or implementors of a method represented by a symbol when you click on a symbol. \n\nUsing `CMD + (Shift +) click` on OSX or `Alt + (Shift +) right click` on Windows/Linux allows one to:\n- Browse the senders when you click on a method.\n- Browse the references to a class when you click on a class.\n- Browse the references to a class or senders of a method represented by a symbol when you click on a symbol. \n\n> Warning: The click shortcuts on symbols are only working starting from Pharo 9. In the previous version, it will browse the ByteSymbol class. \n\n### Method source with it\n\nIt often happens that we want to see how a feature is done, or we want to edit something but we do not know *where* the implementation is. If we have the name of a menu, for example we can use it to find every location in the image where the name of the menu is written. \n\nTo do that we need to open a playground and type the text (or select some text in an editor) then select on a right click `Code search...` then `Method source with it`.\n\nThis will open a message browser with all the methods/class comments containing the string of code we are looking for.\n\n## Interrupt the Pharo process\n\nPharo currently runs in one native thread. If you launch a method taking a lot of time to run, or if you have an infinite loop in your code, you might want to interrupt the process. \n\nIt is possible to do that in Pharo with the shortcut `CMD/ALT + .`.\n\n> This feature will work in most cases. However, sometimes it might not work, e.g. when faulty code would have taken up too much memory, or when a process is executing outside of the VM (FFI calls).\n\n## Debugging facilities\n\nPharo includes multiple ways to help with debugging. This section gives some of them.\n\n`Object` implements multiple debugging messages that are useful. They can be sent to any object in your code:\n\n- `#halt` : This method will stop the execution of your code when it is called and will open a debugger. (/!\\ Do not use it in a code called multiple times in a fork, or system critical loops or you can regret it by breaking your image. In this case, it is advisable to not save your image in this kind of unstable state)\n- `#haltOnce` : This method stops the execution and raises a debugger only on the first time it is called. To enable it once more, use `Menubar -> Debbuging -> Enable all break/inspect once`.\n- `#haltIf:` : This method takes a block as a parameter. It will stop the execution and open the debugger if the block as parameter returns `true`.\n- `#haltOnCount:` : This method takes a number as an argument, it will stop the execution and open the debugger when it will be called at least the number of times given as argument. Reset the counter via `Menubar -> Debbuging -> Reset Counters`.\n- `#inspect` : This message can be called on any object and will open an inspector for the receiver.\n- `#inspectOnce` : This message works like #haltOnce for inspecting.\n\n**Example**\n\n``` Smalltalk\n\nmyMethod\n\t\n\t| temp |\n\tself doSomething.\n\n\t\"If you think an infinite loop might happen here, #haltOnCount: might help\"\n\tself haltOnCount: 1000.\n\n\ttemp := self doSomethingElse.\n\t\n\t\"Inspect the first value of #temp\"\t\n\ttemp inspectOnce.\n\n\t\"Debug only in certain conditions\"\n\tself  haltIf: [ temp isKindOf: ObjectIShouldNotGetHere ].\n\n\t1 to: 1000 do: [ :e | \n\t\n\t\"I want to stop only one time here to check something.\"\n\tself haltOnce.\n\n\tself doSomethingWith: e ]\n\n```\n\n"
  },
  {
    "path": "General/Playground.md",
    "content": "# Playground\n\n- [Basic usage](#basic-usage)\n  * [Do it](#do-it)\n  * [Print it](#print-it)\n  * [Do it and go](#do-it-and-go)\n  * [Inspect it](#inspect-it)\n  * [Basic inspect it](#basic-inspect-it)\n  * [Debug it](#debug-it)\n  * [Profile it](#profile-it)\n  * [Code search](#code-search)\n- [Some Advices](#some-advices)\n  * [Doing vs. Printing](#doing-vs-printing)\n- [Advance usage](#advance-usage)\n  * [Variables bindings](#variables-bindings)\n  * [Remote publishing](#remote-publishing)\n  * [Get back previous playground contents](#get-back-previous-playground-contents)\n  * [Give a name to a playground to get it back](#give-a-name-to-a-playground-to-get-it-back)\n  * [Sharing playgrounds content in multiple local images](#sharing-playgrounds-content-in-multiple-local-images)\n\n\nPlayground is a tool that is most often used for typing Pharo expressions and executing them but it can be used as a scratchpad area where fragments of Pharo code can be entered, stored, edited and evaluated.\n\nYou can open Playground with the shortcut `cmd/ctrl + o + w` or using the menu entry from the menubar: \n\n![open playground from the image](Playground_open_from_image.png)\n\n## Basic usage\nThe Playground can be used to quickly execute Pharo code. You can write something and then do operations on the code, such as:\n\n### Do it \nShortcut: `cmd/ctrl + d` It Executes the code/expression\n\n![Do it command on playground](Playground_do_it.png)\n\n### Print it\nShortcut: `cmd/ctrl + p` It Compiles the expression, executes it, sends the message `printString` to the result and displays the resulting string.\n\n![Print it command on playground](Playground_print_it.png)\n![Print it result on playground](Playground_print_result.png)\n\n### Do it and go\nShortcut: `cmd/ctrl + g` It executes the code and opens a navigable inspector on the side of the playground. It allows us to browse the object structure.\n\n![Do it and go on the playground](Playground_do_it_and_go.png)\n\n### Inspect it\nShortcut: `cmd/ctrl + i` It executes the code and opens a navigable inspector outside of the playground. It allows us to browse the object structure.\n\n![Inspect on Time now](Playground_inspect_on_Time_now.png)\n\n> The title tells us that `11:55:11.561177 am` is an instance of the class `Time`. The top panel allows us to browse the instance variables of an object and their values. The bottom panel can be used to write expressions to send messages to the object. \n\n### Basic inspect it\nShortcut: `cmd/ctrl + shift + i` It opens a minimal inspector on the result of the expression. (Might be useful if you work on the Inspector, for example)\n### Debug it\nShortcut: `cmd/ctrl + shift + d` It opens a debugger on the code with the context at the start of the snippet.\n\n![Debug it on Time now](Playground_debug_it.png)\n\n>The Debugger is a tool that not only lets you inspect the run-time stack of your program when an error is raised, but it also enables you to interact with all of the objects in your application, including the source code. In many cases you can modify your source code from the debugger and continue executing. The debugger is especially effective as a tool to support test-first development in tandem with SUnit.\n\n### Profile it\nProfiles the code with the Pharo profile tool which shows how much time is spent for each message sent.\n### Code search\nOffers several options provided by System Browser, such as browsing the source code of an expression, searching for senders and implementors, and so on.\n\nYou can also use the playground for typing any text that you would like to remember, such as to-do lists or instructions for anyone who will use your image.\n\n![Text on the playground](Playground_with_only_text.png)\n\n## Some Advices\n### Doing vs. Printing\nThe difference between these two actions is visual. try to execute something like `1+5` with `Do it`. Maybe you think that nothing happened because there isn't a visual cue about the execution but in fact, something did happen. You sent the message `+` with argument `5` to the number `1`.\n\nNow try to do it with Print it, the same will happen but you will now see the result printed on the side:\n\n![Print the sum using the playground](Playground_print_sum.png)\n\nThat could be useful if you want to understand the result value.\n\n## Advance usage\n\nIn this section, we will cover some advanced usages of the Playground. \n\n![Overview of the Playground](Playground_overview.png)\n\nThe previous figure highlights different parts of the playground and we will refer to these in this explanation.\n\n1. The playground name tab\n2. The run button\n3. The remote publishing button\n4. The bindings table\n5. The pages history\n\nOut of those, the simplest feature is the run button that will just execute the content of the playground and open an embedded inspector in the playground with the result of the expression. It is the equivalent of `Do it and go` (cmd/ctrl + g).\n\n### Variables bindings\n\nThe playground is able to manage variables in two ways. The first way is the classic Smalltalk way of declaring temporary variables (`| varName |`) at the beginning of the playground and using them later. \n\nExample:\n\n```Smalltalk\n| result |\nresult := 1 + 2.\nresult := result + 3.\n```\n\nUsing these kind of variables will work as temporary variables of methods. During the execution they will be initialized with nil. They will be used during the current execution and then they will be discarded. \n\n> Note: If you select a piece of code to execute, do not forget to select the temporary variables declaration line.\n\nThe second way to manage variables in the playground is to use them without declaring them. \n\nExample:\n\n```Smalltalk\nresult := 1 + 2.\nresult := result + 3\n```\n\nBy doing so, during its first use, the playground creates and initializes the new variable to nil, then stores it. This means that the variable will still exist and will still contain its value after the execution. If you execute the previous piece of code in a playground and then select `result` to inspect it, you will find the value `6`.\n\nThis feature is useful while playing with some code. For example, if you need to work on a model, instead of recreating the model at each run you can just initialize it one time and reuse the variable containing the model for the entire playground session.\n\nIf at some point you don't remember the content of some variables, you can find all the variables bound to the playground in the binding table button (4 on the previous overview screenshot). This table also allows you to unbind variables by clicking on the cross next to their name.\n\n### Remote publishing\n\nIn case you want to share some code with someone, the Playground includes a remote publishing service. \n\nBy clicking the button 3 from the overview screenshot previously displayed, you will publish the content of your playground on the cloud and get a link to it. \n\nYou can then share this link and everyone with it will be able to see the content of your playground.\n\n### Get back previous playground contents\n\nWhilst working, the playground will occasionally save the code in a local file. Using those saved files you have the ability to open a new playground containing the code of a previously closed playground. \n\nIn order to get a previous playground back, you need to open a new playground and use button 5 from the overview, the *page history button*. You will see the start of the code from your previous playgrounds and you need to double click on the one you want to get it back.\n\n### Give a name to a playground to get it back\n\nAnother feature of the playground is the ability to give a name to a playground in order to get its content back easily once closed.\n\nIn order to name a playground, you need to double click the page name (1 on the overview screenshot) and type the name of your choice. Once this is done, the playground will save this name locally. \n\nIf you close the playground and want to get it back, you can open a `Spotter` (`shift + enter`) and type the name of the closed playground. In the list of results of the spotter, you should find a section named `Playground named pages` containing the name of your playground. By selecting this entry, a new playground with the code of your named playground will open.\n\n### Sharing playgrounds content in multiple local images\n\nOne last feature to highlight is the ability to share playground code between multiple local Pharo images.\n\nWe have seen in the previous sections that it is possible to get back the content of the previous playgrounds via the `page history button` and the ability of the Spotter to find named playground pages. By updating some settings of the playground, it is possible to share that history through all your images.\n\nAs explained before, when using the playground and naming playgrounds, the content is stored in local files. In order to share the playgrounds through different images, they need to use the same folders to store their content. Two settings are available for that and can be found in the setting browser under `Tools` -> `Glamourous Toolkit`. \n\n![Settings around the playground](Playground_settings.png)\n\nThe two interesting settings are:\n\n- `Local Playground cache directory`: this setting allows one to choose a specific folder to store the unnamed playground contents.\n- `Local Playground stash directory`: this setting allows one to choose a specific folder to store the named playground contents.\n\nSharing this setting with multiple images will allow one to share playground history across all those images.\n"
  },
  {
    "path": "General/Pragmas.md",
    "content": "# Pragmas\n\n- [Description](#description)\n- [How to declare a new pragma](#how-to-declare-a-new-pragma)\n- [Collect pragmas](#collect-pragmas)\n  * [Find pragmas in the IDE](#find-pragmas-in-the-ide)\n  * [Get the pragmas of a CompiledMethod](#get-the-pragmas-of-a-compiledmethod)\n  * [Collect pragmas in a hierarchy](#collect-pragmas-in-a-hierarchy)\n  * [Collect pragmas in the image](#collect-pragmas-in-the-image)\n- [Act on collected pragmas](#act-on-collected-pragmas)\n- [Examples of pragma usage](#examples-of-pragma-usage)\n  * [Pragmas used in the IDE](#pragmas-used-in-the-ide)\n- [See also](#see-also)\n\n## Description\n\nPragmas in Pharo are annotations on `CompiledMethods`. They are used to attach additional properties to the methods to make those methods easily collectable through reflectivity and to ease the creation of special handlings.\n\nPragmas are part of Pharo's syntax and are declared like this: `<aPragma>`. They should be placed at the beginning of a method, after the method selector.\n\nThis documentation illustrates the use of pragmas by describing how to use them to annotate an application's parameters and generate documentation from those parameters comments.\n\n## How to declare a new pragma\n\nTo declare a new pragma, you only need to add it to, at least, one method in the system.\n\nFor example, annotating an application parameter can be done as follow:\n\n```Smalltalk\nisInAdminMode\n  \"If this parameter is true, the application will allow one to access all the administration panels.\"\n  \n  <applicationParameter>\n  ^ isAdminMode\n```\n\nPragmas can take literals as a parameter in order to configure their future handling.\n\nIn our example, we might want to declare which parameters are optional.\n\n```Smalltalk\nisInAdminMode\n  \"If this parameter is true, the application will allow the user to access all the administration panels.\"\n  \n  <applicationParameterOptional: false>\n  ^ isAdminMode\n```\n\n## Collect pragmas\n\nOnce defined, we need to be able to collect the pragmas either to modify them during the development or to use them to handle a feature of the application.\n\nWe will explore these possibilities in the following sections.\n\n### Find pragmas in the IDE\n\nDuring the development of the application, the developer might need to browse the currents senders of a pragma. This can be done in the same way we browse method selectors in Pharo.\n\nYou can:\n- Select a symbol is the name of the pragma and type `CMD + n` (or `CTRL + n` depending on your operating system).\n- Select a symbol which is the name of the pragma and right click on it then select `Browse senders` in the search menu.\n- Type the name of the pragma in the Spotter (`SHIFT + ENTER` to open Spotter) followed by `#p`.\n- Use the `Finder` (accessible via the menu through path: `Menubar -> Tools -> Finder`) and select the `Pragmas` mode.\n- Send the message `senders` to a symbol which is the name of the pragma.\n\n### Get the pragmas of a CompiledMethod\n\nIf you have a compile method you can directly ask it his pragmas via the `#pragmas` method.\n\nFor example, you can get all methods with a pragma like this:\n\n```Smalltalk\nSystemNavigation new browseAllSelect: [ :method | method pragmas isNotEmpty]\n```\n\n### Collect pragmas in a hierarchy\n\nWhen you want to use the pragmas in your application you have two ways to collect them. If you want to find the pragmas in one class or one hierarchy of class, you can use the `Pragma` class to collect them.\n\nThe Pragma class implements different ways to get to pragmas depending on your requirements.\n\nYou can use:\n- `allNamed: aSymbol from: aSubClass to: aSuperClass`\n- `allNamed: aSymbol from: aSubClass to: aSuperClass sortedByArgument: anInteger`\n- `allNamed: aSymbol in: aClass`\n- `allNamed: aSymbol in: aClass sortedByArgument: anInteger`\n...\n\nIn our example, we might want to use this way of accessing our pragmas if all parameters are defined in a configuration object.\n\nIn that case, we can access them this way:\n\n```Smalltalk\nPragma allNamed: #applicationParameterOptional: in: MyConfiguration\n```\n\nOr if we have a hierarchy of configurations:\n\n```Smalltalk\nPragma allNamed: #applicationParameterOptional: from: MyConfiguration to: MyAbstractConfiguration\n```\n\n### Collect pragmas in the image\n\nYou can also use the Pragma class to collect pramgas in the entire image by using:\n- `allNamed: aSymbol `\n  \nA second, now less reccomended way to collect pragmas, is to use the PragmaCollector. This class can be configured with a query and will return all the pragmas matching the query.\n\nTo configure the PragmaCollector we need to send implement a filter block. If we want to collect the `primitive:` pragmas:\n\n```Smalltalk\nPragmaCollector filter: [:prg | prg selector = #'primitive:' ]\n```\n\nOnce configured we can execute the collection of the pragmas by sending the method #reset to the pragma collector:\n\n```Smalltalk\n(PragmaCollector filter: [:prg | prg selector = #'primitive:' ]) reset\n```\n\nThen you can iterate on the result using `#do:`, `#collect:`, `#reject:`, etc or use them directly through `#collected`. \n\nIn our example we might want to access them this way:\n\n```Smalltalk\n(PragmaCollector filter: [:prg | prg selector = #'applicationParameterOptional:' ]) reset collected\n```\n\nOr we can select only non optional parameters this way:\n\n```Smalltalk\n(PragmaCollector filter: [:prg | prg selector = #'applicationParameterOptional:' and: [ (prg argumentAt: 1) not ] ]) reset collected\n```\n\n## Act on collected pragmas\n\nOnce collected, we need use the pragmas to implement the feature we want.\n\nFor that, the pragmas can answer diverse messages to get their context. For example, they can answer to:\n- `#method` : Returns the CompiledMethod in which the pragmas is.\n- `#arguments` : Returns the arguments of the pragmas.\n- `#argumentAt:` : Returns the value of the n-th argument of the pragma instance.\n- `#argumentNamed:`: Returns the value of the arguemnts following a subpart of the pragma selector. This is available since Pharo 8.\n- `#selector` : Returns the pragma selector.\n- `#methodClass` : Returns the class in which the method containing the pragma is.\n\nWith that information, we can then build our handler.\n\nThe next snippet will collect the senders of our example pragma and generate user documentation about them:\n\n```Smalltalk\nString\n    streamContents: [ :stream | \n        stream\n            << 'Documentation';\n            lf;\n            lf.\n        (PragmaCollector filter: [ :prg | prg selector = 'applicationParameterOptional:' ]) reset\n            do: [ :pragma | \n                stream\n                    << '- ';\n                    << pragma methodSelector.\n                (pragma argumentAt: 1) ifTrue: [ stream << ' (Optional)' ].\n                stream\n                    << ': ';\n                    << pragma method comment;\n                    lf ] ]\n```\n\nHere is an example on how to use `#argumentNamed:`:\n\n```Smalltalk\n(PragmaCollector filter: [:prg | prg selector = #'loaderNamed:priority:' and: [ (prg argumentNamed: #priority) > 0 ] ]) reset collected\n```\n\n## Examples of pragma usage\n\nPragmas are used for many things in Pharo and you can find examples of their usage by browsing Pharo code using them.\n\nFor example, the setting framework is built with pragmas. The pragma `<systemSetting>` is used to register new settings the setting browser.\n\nAnd other examples can be found in the world menu registration and is explain if the page [Menubar and World menu](MenuBar.md).\n\n### Pragmas used in the IDE\n\nSome pragmas are interesting to know in Pharo IDE. You can find information on them on [this page](InterestingsToKnowForBeginners.md#useful-pragmas)\n\n## See also\n\n- [Pragmas: Literal Messages as Powerful Method Annotations](https://rmod-files.lille.inria.fr/Team/Texts/Papers/Duca16a-Pragmas-IWST.pdf)\n"
  },
  {
    "path": "General/Profiling.md",
    "content": "# Profiling\nProfiling a program is the act of measuring, for example, the time or space it takes to execute.\n\n- [Time Profiling](#time-profiling)\n  * [Programmatically open a Time Profiler](#programmatically-open-a-time-profiler)\n  * [Utility methods on blocks to profile](#utility-methods-on-blocks-to-profile)\n  * [Interactively open a Time Profiler](#interactively-open-a-time-profiler)\n- [Space Profiling](#space-profiling)\n\n## Time Profiling\n### Programmatically open a Time Profiler\nIf `SimpleGridExample new open` is the program you want to profile, run:\n```Smalltalk\nTimeProfiler spyOn: [ SimpleGridExample new open ]\n```\nResult: a breakdown of the methods in which the program spent time.\n\n![image](Profiling_Image_TimeProfilerFromCommandLine.png)\n\n> If your block execution time is too fast (~ < 3ms), the time profiler will not display any result.\n\nThe time profiler UI is composed of multiple parts:\n- *Tallies tree* displays a tree of all the nested method calls of the execution with the percentage of time spent in each call. The tree stops at primitive calls or calls that are too fast to be benchmarked (~ < 3ms)\n- *Code* displays the code of the selected method in the `tallies tree`\n- *Statistics* displays memory and garbage collection statistics. Those informations may be useful if too much execution time is spent in the full or incremental garbage collection. This may signal that the code executed create too many temporary objects. The code can then be reviewed to create less copies or temporary objects. If it is not possible, consider changing the parameter of the VM to do less garbage collection during the execution of some algorithms.\n- *Full report* displays textual informations such as the tallies tree and statistics, but also informations on leaf methods where most of the time is spent. (Section `**Leaves**`) This can be a good source of information to find bottlenecks where the time is spent.\n\n### Utility methods on blocks to profile\nIf `SimpleGridExample new open` is the program you want to profile, **inspect** or **print**:\n\n```Smalltalk\n[ SimpleGridExample new open ] bench.\n```\n\nResult: the number of times the profiler was able to run the program per second.\n\n![image](Profiling_Image_Bench.png)\n\nYou can also check the execution time of a set of instructions by inspecting or printing the result of the `timeToRun` method on blocks like this:\n\n```Smalltalk\n[ SimpleGridExample new open ] timeToRun\n```\n\n### Interactively open a Time Profiler\nYou can access a UI for the time profiler tool via the menu bar.\n\n![image](Profiling_Image_TimeProfilerMenuItem.png)\n\nResult: type your code in the top box and click \"Profile it\".\n\n![image](Profiling_Image_TimeProfilerToolUI.png)\n\n## Space Profiling\nImagine you want to know how much instances of the classes Point and TextMorph there are in the system, and how much space they occupy. **Inspect**:\n```Smalltalk\n((SpaceTally new spaceTally: (Array with: TextMorph with: Point)) \n\tasSortedCollection: [:a :b | a spaceForInstances > b spaceForInstances])\n```\nResult:\n\n![image](Profiling_Image_SpaceTally.png)\n"
  },
  {
    "path": "General/ProgressBar.md",
    "content": "# Progress bar\n\nThis document covers different ways to display a progress bar during code execution.\n\n## Progress bar on iterators\n\nThe easiest way to create a progress bar is to use the method `do:displayingProgress:`. This method is available on Collections and adds a progress bar automatically updated during iterations.\n\n```Smalltalk\n(1 to: 100) do: [ :each | each logCr. 100 milliSecond wait. ] displayingProgress:  [ :each | 'Iterating step ' , each asString ]\n```\n\nRefresh time can also be customized if better performances are needed. For example, the following code will update the progress bar every 2 seconds:\n\n```Smalltalk\n(1 to: 100) do: [ :each | each logCr. 100 milliSecond wait. ] displayingProgress:  [ :each | 'Iterating step ' , each asString ] every: 2000\n```\n\n## Use Jobs\n\nAn other way to display a progress bar is to use Jobs.\n\n```Smalltalk\n[:job | job title: 'Let us get started'.\n\t1 to: 10 do: [:each |\n\t\tjob\n\t\t\tprogress: (0.1 * each);\n\t\t\ttitle: 'Youpi ', each printString.\n\t\t(Delay forMilliseconds: 100) wait.\n\t\t] ]  asJob run\n```\n\nOr using UIManager:\n\n```Smalltalk\nUIManager default\n\tdisplayProgress: 'Let us get started'\n\tfrom: 1\n\tto: 10\n\tduring: [ :bar | \n\t\t1 to: 10 do: [:each |\n\t\t\tbar\n\t\t\t\tvalue: each;\n\t\t\t\ttitle: 'Youpi ', each printString.\n\t  (Delay forMilliseconds: 100) wait.\n\t]  ]\n```\n\nBe careful while using this method. It might cause performance issues when time between two steps is short.\n\nHowever, the following code shows a way to avoid these issues.\n\n```Smalltalk\nUIManager default\n\tdisplayProgress: 'Let us get started'\n\tfrom: 1\n\tto: 40\n\tduring: [ :bar | | lastUpdate | \n\t\tlastUpdate := 0.\n\t\t1 to: 40 do: [:each |\n\t\t\t((Time millisecondsSince: lastUpdate) >= 500) ifTrue: [ \n\t\t\t\tbar\n\t\t\t\t\tvalue: each;\n\t\t\t\t\ttitle: 'Youpi ', each printString.\n\t\t\t\tlastUpdate := Time millisecondClockValue\n\t\t\t\t ].\n\t  (Delay forMilliseconds: 100) wait.\n\t]  ]\n```\n\nThe trick is to leave at least 500 milliseconds between two updates instead of updating the bar each time we call `value:` or `title:`.\n"
  },
  {
    "path": "General/Refactorings.md",
    "content": "# Refactoring in Pharo 8.0\n\n## Introduction\n\nPharo offers many automatic refactoring tools. This tutorial presents what refactorings are, when and how to apply them and to show any possible inconvenience before using them.\n\n## What is refactoring?\n\nMartin Fowler defines refactoring as: \"... It is a disciplined technique to restructure an existing body of code, altering its internal structure without changing its external behavior\" [1](#references). This means that before carrying out any type of refactoring in the code it is important to have complete test coverage to demonstrate that the code behavior does not change during the refactoring process.\n\n## The most popular refactorings supported by Pharo 8.0\n\n| Refactoring | Supported in |\n| ---------- | ---------- |\n| [Rename](#rename)   | Package, Class, Method, Instance and Temporary Variable |\n| [Extract](#extract)   | Method and Temporary Variable  |\n| [Remove](#remove)| Package, Class, Method and Instance Variable |\n| [Copy](#copy) | Class |\n| [Move](#move) | Class and method |\n| [Inline](#inline) | Method and Temporary Variable |\n| [Push up / Push down](#push-up-and-push-down) | Method and Instance Variable |\n| [Replace](#replace) | Method |\n| [Other refactorings](#other-refactorings) |  Class, Method, Instance and Temporary Variable |\n\n# Rename\n\nRenaming seems like a trivial refactoring however it can lead to many complications because this action can lead to involuntary changes of elements not related to the same name. The Pharo's rename tool has can minimize these errors.\n\n## When should we rename?\n\n1. When the name is not descriptive enough.\n2. The name of the class / method / variable does not match what it really is.\n3. Something new was introduced that requires the existing code to have a new more specific name.\n \n> This refactoring can be done for classes, methods and variables.\n>\n>1. Select the `class / variable / method `.\n>2. Press **Meta+R** or from the menu, select **Rename**.\n>3. Fill the input of dialog with the new name and press **Ok** button.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/tHdt11WDq2o/0.jpg)](http://www.youtube.com/watch?v=tHdt11WDq2o)\n\n# Extract\n\nThe extraction Pharo's tools allow developers to reshape their code when they have duplicate code or when they want to change the design.\n\nPharo can perform this refactoring to extract methods and extract temporal variables.\n\n## Extract temporary variable\n\n#### Before\n``` Smalltalk\nExample >> method\n    | a b c|\n    a := 1.\n    b := a + list size.\n    c := b + list size.\n```\n#### After\nSelecting `list size` on source code\n``` Smalltalk\nExample >> method\n    | a b c d|\n    a := 1.\n    d := list size.\n    b := a + d.\n    c := b + d.\n```\n\n>1. Select the section of `source code` you want to convert in temporary variable.\n>2. Press **Meta+T** or from the menu, select **Source code**.\n>3. Select **Extract temp** option.\n>4. Fill dialog's input with the name of the variable and press **Ok** button.\n\n## Extract method\n\n#### Before\n``` Smalltalk\nExample >> method\n    | a b c d|\n    a := 1.\n    b := 2.\n    c := a + b.\n    d := a + c.\n```\n#### After\nSelecting `a + b` on source code\n``` Smalltalk\nExample >> method\n    | a b c d|\n    a := 1.\n    b := 2.\n    c := self add: a to: b.\n    d := self add: a to: c.\n\nExample >> add: a to: b\n    ^ a + b\n```\n\n>1. Select the section of the `source code` you wish to extract.\n>2. Press **Meta+T** or from the menu, select **Source code**.\n>3. Select **Extract method** option.\n>4. Fill the input of dialog with the name of method and press **Ok** button.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/LfyN3bo4b0A/0.jpg)](http://www.youtube.com/watch?v=LfyN3bo4b0A)\n\n# Remove\n\nSometimes when the code is refactored it can end with code that is no longer used, or that should no longer be used. Therefore, it is necessary to eliminate all the unused code since this affects the developers who work and try to understand the source code.\n\n>This refactoring can be done for packages, classes, methods and variables.\n>\n>1. Select the `package / class / variable / method`.\n>2. Press **Meta+X**\n\n# Copy\n\nMany times we want to change or add some functionalities to our code, however this entails major changes which makes it dangerous to do it on the original class. That is why it may be necessary to copy the classes to have a backup in case you want to reverse the changes.\n\n>Currently this tool only applies to classes and to use it you just have to follow the following steps:\n>\n>1. Select `class`.\n>2. Press **Meta+C** or from the menu, select **Copy**.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/wgeVyFltKXY/0.jpg)](http://www.youtube.com/watch?v=wgeVyFltKXY)\n\n# Move\n\nMove allows you to move classes and methods from one package to another, and move methods to class / instance side or even move them to another class.\n\n## Move to package\n\n> ### Class\n>\n>1. Select `class or classes` that you want to move.\n>2. Press **Meta+MC** or from the menu, select **Refactorings** and then select **Move to package** option.\n>3. Select the package and press **Ok** button\n\n> ### Method\n>\n>1. Select the `method or methods` to be moved.\n>2. Select **Refactorings** and then select **Move to package** option.\n>3. Select the package and press **Ok** button.\n\n## Move to class\n\n>1. Select the `method or methods` to be moved.\n>2. Select **Refactorings** and then select **Move to another class** option.\n>3. Select the new class for method(s) and press **Ok** button.\n\n## Move to class side\n\n>1. Select the method or methods to be moved.\n>2. Press **Meta+TC**, select **Refactorings** and then select **Move to class side** option.\n\n## Move to instance side\n\n>1. Select the `method or methods` to be moved.\n>2. Press **Meta+TI**, select **Refactorings** and then select **Move to instance side** option.\n\n# Inline\n\nInline refactoring allows you to reverse extract refactoring of a method or temporary variable.\n\n## Inline temp\n\nInline variables replaces the use of redundant variables with its initializer.\n\n#### Before\n``` Smalltalk\nExample >> method\n    | number b |\n    number := anotherClass value.\n    b := 3 + number.\n```\n#### After\nSelecting `number` temp on source code\n``` Smalltalk\nExample >> method\n    | b |\n    b := 3 + anotherClass value.\n```\n\n>1. Select the `temporary variable` in the source code.\n>2. Press **Meta+T** or from the menu, select **Source code**.\n>3. Select **Inline temp** option.\n\n## Inline method\n\nThe results of inline method place methods's body in the body of the method where we select its call.\n\n#### Before\n``` Smalltalk\nExample >> method\n    | a b c d|\n    a := 1.\n    b := 2.\n    c := self add: a to: b.\n    d := self add: a to: c.\n    \nExample >> add: a to: b\n    ^ a + b\n```\n#### After\nSelecting `self add: a to: b.` on source code\n``` Smalltalk\nExample >> method\n    | a b c d|\n    a := 1.\n    b := 2.\n    c := a + b.\n    d := a + c.\n```\n\n>1. Select the `call to method` in the source code.\n>2. Press **Meta+T** or from the menu, select** Source code**.\n>3. Select **Inline method** option.\n\n## Inline senders\n\nThis refactoring replaces all calls to the method selected from its class by the body of its implementation, in addition to the method itself being eliminated.\n\n>1. Select the `method`.\n>2. From the menu, select **Refactorings**.\n>3. Select **Inline senders** option.\n\n# Push up and Push down\n\n## Push up method\n\nGets rid of duplicate code. If you need to make changes to a method, it’s better to do so in a single place than have to search for all duplicates of the method in subclasses; this refactoring technique can also be used if, for some reason, a subclass redefines a superclass method but performs what’s essentially the same work.\n\n>1. Select the method\n>2. Select **Meta+PU** or from the menu, select **Refactorings** and then select **Push up** option.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/nZiLNx4Y6tA/0.jpg)](http://www.youtube.com/watch?v=nZiLNx4Y6tA)\n\n## Push down method\n\nImproves class coherence. A method is located where you expect to see it. For example if you see that a method is needed by more than one subclass, but not all of them, it may be useful to create an intermediate subclass and move the method to it. This allows avoiding the code duplication that would result from pushing a method down to all subclasses.\n\n>1. Select the method\n>2. Select **Meta+PD** or from the menu, select **Refactorings** and then select **Push down** option.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/F_JjZfZzCqY/0.jpg)](http://www.youtube.com/watch?v=F_JjZfZzCqY)\n\nIn the same way as in the methods you can perform the push up and push down refactorings on the instance variables\n\n## Push up variable\n\n>1. Select the `variable`.\n>2. From the menu select **Push up** option.\n\n## Push down variable\n\n>1. Select the `variable`.\n>2. From the menu select **Push down** option.\n\n# Replace\n\n## Replace senders\n\nReplace senders helps us to change the senders of the selected method to the name of another method that we want, considering that the method with which we replace it must have the same number of arguments as the original.\n\n>1. Select the `method`.\n>2. From the menu, select **Refactorings**.\n>3. Select **Replace senders** option.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/CJjZYugsqZg/0.jpg)](http://www.youtube.com/watch?v=CJjZYugsqZg)\n\n## Find and Replace method\n\nFind and replace helps us when we have duplicate code, if this refactoring consists in selecting a method and looking for the occurrences of your body in a range of methods that is selected.\n\n#### Before\n``` Smalltalk\nExample >> textInputOn: html withName: aString andSymbol: aSymbol\n    html text: aString.\n    html textInput on: aSymbol of: self contact.\n    html break\n\nExample >> renderContentOn: html\n    html\n\tform: [ html text: 'Name:'.\n  \t    html textInput on: #name of: self contact.\n\t    html break.\n\t    html text: 'Email address:'.\n\t    html textInput on: #emailAddress of: self contact.\n\t    html break.\n\t    html text: 'Example:'.\n\t    html textInput on: #example of: self contact.\n\t    html break]\n```\n#### After\n``` Smalltalk\nExample >> textInputOn: html withName: aString andSymbol: aSymbol\n    html text: aString.\n    html textInput on: aSymbol of: self contact.\n    html break\n\nExample >> renderContentOn: html\n    html\n\tform: [ self textInputOn: html withName: 'Name:' andSymbol: #name.\n   \t    self textInputextInputOnt: html withName: 'Email address:' andSymbol: #emailAddress.\n\t    self textInputOn: html withName: 'Example:' andSymbol: #example ]\n```\n\n>1. Select the `method`.\n>2. From the menu, select **Refactorings**.\n>3. Select **Find and replace** option.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/yxOn3tdh1wU/0.jpg)](http://www.youtube.com/watch?v=yxOn3tdh1wU)\n\n# Other refactorings\n\n## Generate accessors\n\nThis refactoring generates the get and set messages of the instance variables, can be used from the class and the variables.\n\n#### Before\n``` Smalltalk\nObject subclass: #Example\n    instanceVariableNames: 'a'\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n```\n#### After\n``` Smalltalk\nObject subclass: #Example\n    instanceVariableNames: 'a'\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nExample >> a\n    ^ a\n\nExample >> a: anObject\n    a := anObject\n```\n\n>### Class\n>\n>1. Select the `class` that you want generate accessors.\n>2. Select **Meta+GA** or from the menu, select **Generate accessors** option.\n\n>### Variables\n>\n>1. Select the `variable(s)` that you want generate accessors.\n>2. From the menu, select **Generate accessors** option.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/LMnv8HDNE-4/0.jpg)](http://www.youtube.com/watch?v=LMnv8HDNE-4)\n\n## New subclass\n\nGenerate a new subclass of a class. \n\n#### Before\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n\nMyA subclass: #MyB\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'</pre>\n```\n#### After\nSelecting the `MyA` class\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nMyA subclass: #MyB\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nMyA subclass: #MyC\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n```\n\n>1. Select `class`.\n>2. From the menu, select **Refactorings** and then select **New subclass** option.\n>3. Fill the dialog's input with new class's name.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/PLqO6s46p_o/0.jpg)](http://www.youtube.com/watch?v=PLqO6s46p_o)\n\n## Insert subclass\n\nGenerate a new subclass of a class between the class and its subclasses. This refactoring is useful when we have to specialize some classes.\n\n#### Before\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n\nMyA subclass: #MyB\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n```\n#### After\nSelecting the `MyA` class\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nMyA subclass: #MyC\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nMyC subclass: #MyB\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n```\n\n>1. Select `class`.\n>2. From the menu, select **Refactorings** and then select **Insert subclass** option.\n>3. Fill the dialog's input with new class's name.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/vflwFbwY58A/0.jpg)](http://www.youtube.com/watch?v=vflwFbwY58A)\n\n## Insert superclass\n\nGenerate a new superclass of a class between the class and its superclass. This refactoring is useful when we must generalize to avoid the redundancy of the classes.\n\n#### Before\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n\nMyA subclass: #MyB\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n```\n#### After\nSelecting the `MyB` class\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nMyA subclass: #MyC\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nMyC subclass: #MyB\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n```\n\n>1. Select `class`.\n>2. From the menu, select **Refactorings** and then select **Insert subclass** option.\n>3. Fill the dialog's input with new class's name.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/b1wpkuxYwHc/0.jpg)](http://www.youtube.com/watch?v=b1wpkuxYwHc)\n\n## Jump to test class\n\nThis seems trivial, however this command offers us a shortcut to automatically create a class for our tests or go to tests class.\n\n>1. Select `class`.\n>2. Press **Meta+GJ** or from the menu, select **Jump to test class**.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/IC6MawvjzwE/0.jpg)](http://www.youtube.com/watch?v=IC6MawvjzwE)\n\n\n##  Abstract instance variables\n\nThis refactoring generate accessors methods if they don't exist and replace every direct access to class variables with accessor methods.\n\n#### Before\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: 'a'\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n\nMyA >> method\n    |result|\n    a := self initializeVariable.\n    result := a value.\n```\n#### After\nSelecting the `a` variable\n``` Smalltalk\nObject subclass: #MyA\n    instanceVariableNames: 'a'\n    classVariableNames: ''\n    package: 'Refactoring-Example'\n    \nExample >> a\n    ^ a\n\nExample >> a: anObject\n    a := anObject\n\nMyA >> method\n    |result|\n    self a: self initializeVariable.\n    result := self a value.\n```\n\n>1. Select `variable`.\n>2. From the menu, select **Abstract instance variables** option.\n\n[![Pharo - Rename refactoring](https://img.youtube.com/vi/cRBICE66v7g/0.jpg)](http://www.youtube.com/watch?v=cRBICE66v7g)\n\n# References\n[1] Martin Fowler, [Refactoring - Improving the Design of Existing Code](https://refactoring.com/)\n"
  },
  {
    "path": "General/SessionsManagement.md",
    "content": "# Sessions Management\n\n * [Description](#description)\n * [Quick start](#quick-start)\n * [Register a class to the session manager](#register-a-class-to-the-session-manager)\n * [Start-up, Shut-down and Saving actions](#start-up--shut-down-and-saving-actions)\n * [Checking the start-up and shut-down list](#checking-the-start-up-and-shut-down-list)\n\n## Description\n\nPharo images have a concept of **Session**. On each image startup the current session is invalidated and a new session is created. A session starts when one open a Pharo image and stop when one close it. A session is also invalidated when saving the image, therefore creating a new session.\nIt is possible to hook your project to those sessions to perform actions such as executing code at startup, shutdown, image saving...\n\n## Quick start\n\nHere is a quick start to show how to set a class variable to the home folder of a user at startup and removing this value at shut down. \n\nYou need to do those actions in a `#startUp:` method and `#shutDown:` method on the class side of your class. \n\n```Smalltalk\nMyClass class>>startUp: isImageStarting\n\tisImageStarting\n\t\tifTrue: [ MyVariable := FileLocator home asFileReference ]\n```\n\n```Smalltalk\nMyClass class>>shutDown: isImageQuitting\n\tisImageQuitting\n\t\tifTrue: [ MyVarible := nil ]\n```\n\nThen you need to register the class in the `SessionManager` of Pharo. This is usually done in the `#initialize` method (class-side).\n\n```Smalltalk\nMyClass class>>initialize\n\tSessionManager default registerUserClassNamed: self name.\n\tself startUp: true. \"Here we execute it to set up the value while loading the project.\"\n```\n\n## Register a class to the session manager\n\nIt is possible to register classes to the `SessionManager` of Pharo in order to be able to execute code at start-up, shut-down or when we save a Pharo image.\n\nThe simplest way to do that is to add this in the class initialization method of the class you want to register.\n\n```Smalltalk\nMyClass class>>initialize\n\tSessionManager default registerUserClassNamed: self name\n```\n  \nSometimes, the order of execution of start-up/shut-down actions might matter. To manage this, it is possible to set a priority.\n  \n```Smalltalk\nMyClass class>>initialize\n\tSessionManager default registerUserClassNamed: self name atPriority: 60\n```\nRegistered handlers with lower priority will be executed first.\nThe actions registered using `#registerUserClassNamed:[atPriority:]` will have a low priority in the startup/shutdown list.\nIt is possible to further refine the priorities using categories. \n\nThe SessionManager has categories. `User` category is one of them. Categories have priority between each others.\nBy default the system comes with those categories (sorted by priority from the highest to the lowest one):\n\n- System (`#registerSystemClassNamed:[atPriority:]`): manages system related modules such as FFI, Files, OSEnvironment, ...\n- Network (`#registerNetworkClassNamed:[atPriority:]`): manages network related modules such as Zinc or git.\n- Graphical User Interface (`#registerUserGUINamed:[atPriority:]`): manages GUI related modules such as events, sensors, morphic, ...\n- Tools (`#registerToolClassNamed:[atPriority:]`): manages the tools of Pharo IDE such as Code browser, Spotter, Inspector, ...\n- User (`#registerUserClassNamed:[atPriority:]`): for the users to register their projects most of the time.\n\n> Most of the time, users should use the `User` category. Use the other ones only if you know what you are doing.\n\nIt is possible to create a new category:\n\n```Smalltalk\nSessionManager default createCategory: aCategoryName.\nSessionManager default createCategory: aCategoryName after: anotherCategoryName.\n```\n\n> It is not recommanded to register a new category before the System, Network or GUI ones. If you do, be sure of what you are doing.\n\nThen one can register classes in you new custom category:\n\n```Smalltalk\nSessionManager default register: (ClassSessionHandler forClassNamed: self name) inCategory: (SessionManager default categoryNamed: 'MyCategory').\nSessionManager default register: (ClassSessionHandler forClassNamed: self name) inCategory: (SessionManager default categoryNamed: 'MyCategory') atPriority: 30.\n```\n\n## Start-up, Shut-down and Saving actions\n\nOnce a class is registered in the `SessionManager`, it is possible to add start-up and shut-down actions that will be executed when we open, close or save an image.\n\nTo register a start-up action, you need to implement a #startUp: method in the class side of your registered class.\nThis method is called in two situations: when you launch an image and after you save an image.\nThis method takes a boolean as parameter. The value of this parameter is true when we start the image and false when we save it. \n\nExample:\n\n```Smalltalk\nMyClass class>>startUp: isImageStarting\n\tTranscript traceCr:\n\t\t(isImageStarting\n\t\t\tifTrue: [ 'Image is starting' ]\n\t\t\tifFalse: [ 'Image was saved' ])\n```\n\nTo register a shut-down action, you need to implement a #shutDown: method in the class side of your registered class.\nThis method is called in two situations: when you quit an image and when you save an image.\nThis method takes a boolean as parameter. The value of this parameter is true when we quit the image and false when we only save it. \n\nExample:\n\n```Smalltalk\nMyClass class>>shutDown: isImageQuitting\n\tTranscript traceCr:\n\t\t(isImageQuitting\n\t\t\tifTrue: [ 'Image is quitting' ]\n\t\t\tifFalse: [ 'Image is been saved' ])\n```\n\n\n## Checking the start-up and shut-down list\n\nWhen manipulating sessions, it is sometime interesting to check the current start-up and shut-down lists.\n\nIt is possible to do this this way:\n\n```Smalltalk\nSessionManager default startupList.\nSessionManager default shutdownList.\n```\n\nThe results of those methods will be sorted by priority.\n"
  },
  {
    "path": "General/SettingUpANewProject.md",
    "content": "# Setting up a new project\n\nIn this article, we describe the good workflow for setting up a new project in Pharo. We will guide you through the whole process from getting a new Pharo image, creating the GitHub repository, and setting up the CI.\n\nWe will demonstrate everything by setting up a toy project - `Counter`, inspired by Chapter 14. Seaside by Example of [Pharo by Example](https://files.pharo.org/books-pdfs/updated-pharo-by-example/2017-01-14-UpdatedPharoByExample.pdf) book. It is a simple class that has a value which can be incremented or decremented.\n\n## Step 0. Download and install Pharo Launcher\n\nIn order to work with Pharo, you should dowload and install Pharo Launcher - a tool for managing Pharo images. It is available for Windows, Linux, and macOS in both 32bit and 64bit version and can be dowloaded from [http://pharo.org/download]().\n\n![](SettingUp_DownloadPharo.png)\n\n## Step 1. Get a fresh Pharo image\n\nInstructions in this tutorial were written for Pharo 8, 64bit. But they should also work fine for Pharo 7. We suggest that you start your new project with the latest development version of Pharo.\n\nOpen your Pharo Launcher. You will see two panels:\n\n- **New Image Templates** on the left - here you can select a template of a new image that you want to create on your machine.\n- **Current Images** on the right - created images will appear here. By double-clicking on image name, you can launch it.\n\nOpen the list of `Official distributions` in the left panel and double-click on the latest development version of Pharo. In our case, this is `Pharo 8.0 - 64bit (development version, latest)`. Give a nice descriptive name to your new image and press `OK`. You can now find your image in the right panel. Launch it by double-clicking on the image name.\n\n![](SettingUp_PharoLauncher.png)\n\n## Step 2. Create a package and a class\n\n!! ( In Pharo 13 or more latest version, we have \"**slots: { #variable }**\" instead of \"**instanceVariableNames: 'variable'**\" )\n\nLet us make our first package. In your newly made image in Pharo Launcher, in the top menu bar choose *Tools* then *System Browser*.\n\n![System Browser tool for developing projects in Pharo](SettingUp_SystemBrowser.png)\n\nSystem Browser is the main tool to develop a project in Pharo. It allows browsing packages, classes, protocols and methods. The most left panel shows all the packages that already exist. To create a new one, press the right click of a mouse on this part, and choose the option New Package. \n\n![Pharo System Browser, new package creation pop-up menu](SettingUp_NewPackage.png)\n\nChoosing it, a new small window will open, where you give a name to the package you are creating. Type the name *Counter* and press ok.\n\n\nTo create a class, first you need to choose the package in which it will be located. Then look at the bottom part of the System Browser in it there is a template for creating a class. It gives us all the information we need: superclass, variables, package. Creating a new class is as easy as filling out this template. Continuing with our example, we will create a new class *MyCounter*. The superclass is *Object*, so we will not change that. But we will change the name of the class. You will notice that saving our class, the second left part of SystemBrowser is no longer empty.\n\n![Pharo System Browser, new class created](SettingUp_AddingClass.png)\n\n## Step 3. Write some failing tests\n\nIf we want to follow the [TDD (test driven development)](https://fr.wikipedia.org/wiki/Test_driven_development), we first need to create tests. All tests are stored in a test class, which is a subclass of *TestCase*. This class can be generated by doing a right-click on the class name and selecting *Jump to test class*. This option will generate a test class in a new package *Counter-Tests*.\n\n![Pharo System Browser, new Test class created](SettingUp_TestClass.png)\n\nNext what we need to do is create some tests. We do this by clicking on our test class, choosing a protocol in second from the right part of the Browser, and implementing a test. \n\nIn case there are no protocols to choose from (this happens in cases when we are making our first test), then we need to add a new one. This is done by pressing a right click on *instance side*, going to New protocol option and picking a protocol you need (in our case tests).\n\n![Pharo System Browser, new protocol creation pop-up menu](SettingUp_NewProtocol.png)\n\nAfter we have choosen a protocol, our bottom part of System Browser will change and show a template for making methods (each test is a separate method). When giving a name it is important to put the word *test* first, so that Pharo knows that what we are making is in fact a test.\n\nIn our example, a counter will be incrementing and decrementing some value. You will notice that we are using methods which have not been created yet and that each test you write will fail (be red) when you run it. \n\nWe can make these tests: \n\n**Creating MyCounter object:** \nWe want to check if the object we created is not equal to nil, that is why we are using *self deny:* message. This will to a check if the statement we send is true and if it is return false. \n\n  \n  ```GitHub\n  testCreatingMyCounter\n    \"A test that will check if the creation of an object MyCounter is done properly\"\n    |tmp|\n    tmp := MyCounter new.\n    self deny: (tmp = nil)\n  ```\n\n\n**Incrementing value:** \nHere we want to check if the method *increment* is really doing his job and adding one to the value. What we did here is: created a new object MyCounter, set the test value, call the method *increment* and checked if the new value is equal to an expected result. Here we use *self assert:* key word message, which returns true if the statement is in fact true. \n\n\n```GitHub\ntestIncrementing\n  \"A test that will check if method increment is working properly. \n    Test value 5. Expected result 6.\"\n  |counter|\n  counter := MyCounter new.\n  counter value: 5.\n  counter increment.\n  self assert: (counter value = 6)\n  ```\n\n\n**Decrementing value:**\nHere we are checking if the method *decrement* is doing his job and subtracting one from the value. The process of creating this test is similar to previous one.\n\n\n```GitHub\ntestDecrementing\n  \"A test that will check if method decrement is working properly.\n   Test value 5. Expested result is 4.\"\n  |counter|\n  counter := MyCounter new.\n  counter value: 5.\n  counter decrement.\n  self assert: (counter value = 4)\n```\n\n\n## Step 4. Add methods to make tests green\n\nNow that we have create tests (which are all red), we need to implement methods that we have been testing. Switch to *MyCounter* class for this part.\n\nThe first thing that you probably have noticed already is that most of our methods are working with some kind of value. This is a number which we are assigning to our counter. Therefore, value is an instance variable of a class MyCounter. Choose your class and add this variable.\n\n![Pharo System Browser, new variable added to class](SettingUp_AddingVariable.png)\n\nIf we have a variable, we need to assure access to it, by making *value* and *value: anInteger* methods. They will allow putting some integer as a new value (*value: anInteger*) and retrieving the current value (*value*).\n\n\n```GitHub\nvalue\n  \"Method that returns variable value.\"\n  ^value\n  ```\n  \n  \n  ```GitHub\n  value: anInteger\n    \"Method that sets *anInteger* as a variable value.\"\n    value := anInteger\n  ```\n\n\nTo make the first test work, we need to implement initialization of an object. Method *init* will be in initialization protocol and it will assign some default integer to the variable value.\n\n\n```GitHub\ninit\n  \"Method for initialization.\n  Setting variables to some default values. For example 0.\"\n  value := 0\n  ```\n\nNow we will show the implementation on method *increment*. This method is adding one to variable value and putting this new number as value. Implementation for method *decrement* will be similar.\n\n\n```GitHub\nincrement\n  \"This method adds 1 to variable value.\"\n  self value: (value + 1)\n  ```\n\n```GitHub\ndecrement\n  \"This method subtracts 1 from variable value.\"\t\n  self value: (value - 1)\n  ```\n\nAfter you have added all the methods, go to your test class and run your tests. Notice that all of them are green now.\n\n## Step 5. Create a baseline and a Metacello script\n\nBaselines allow us to manage dependencies and specify how the repository should be loaded. We can use `Metacello` object to load the project that has a baseline defined for it. In this tutorial we will only show an example of creating a baseline for our simple `Counter` project. For more information on baselines, please read this excellent [Baselines](https://github.com/pharo-open-documentation/pharo-wiki/blob/master/General/Baselines.md) guide on Pharo Wiki.\n\nStart by creating a package called `BaselineOf<YourProjectName>` and the class with the same name which is the subclass of `BaselineOf`. In our case, both package and class are called `BaselineOfCounter`.\n\n```Smalltalk\nBaselineOf subclass: #BaselineOfCounter\n    instanceVariableNames: ''\n    classVariableNames: ''\n    package: 'BaselineOfCounter'\n```\n\nNow create a method `BaselineOfCounter >> baseline:` with the following content:\n\n```Smalltalk\nbaseline: spec\n    <baseline>\n    spec for: #common do: [\t\n\t\t\t\t\n        \"Packages\"\n        spec\n            package: 'Counter';\n            package: 'Counter-Tests' with: [ spec requires: #('Counter') ] ].\n```\n\nAt this point, our baseline does not contain any external dependencies. It only says that our project consists of two packages: `Counter` and `Counter-Tests` and that the package `Counter-Tests` depends on `Counter`.\n\n## Step 6. Create repository on GitHub\n\nTo create the repository on [GitHub](https://github.com/), first you need to visit the site and either *sign in* (if you already have an account) or *sign up* (to make a new account). Go to your profile and choose Repositories.\n\n![Repositories menu GitHub](SettingUp_NewRepoGit.png)\n\nIn the right corner there will be a button *New*, press it to create a new repository. \n\nIn newly opened window add name; description and README if you choose. You can also decide who will see your repository (Public - everyone; Private - you select people who will have access). After filling the necessary information, press *create repository* button.\n\n![GitHub, new repository creation form](SettingUp_CreateNewRepo.png)\n\n## Step 7. Load the repository into your image\n\n## Step 8. Create an src/ folder and add metadata to your repository\n\nIt is a good practice to put all your source packages into a separate folder, usually called `src/`. This ensures that as the number of packages grows, people will not have to scroll a lot to see README. It also makes repository structure cleaner because source code is separated from documentation, licence, etc. You can navigate into the working directory of your repository and create the `src/` folder manually or execute the following line in your Playground to have Pharo create the folder for you:\n\n```Smalltalk\n(FileLocator localDirectory / 'iceberg' / '<userName>' / '<projectName>' / 'src') ensureCreateDirectory \n```\n\n## Step 9. Add packages and do the first commit\n\n## Step 10. Set up the continuous integration (CI)\n\n## Step 11. Add badges to your README.md\n"
  },
  {
    "path": "General/Settings.md",
    "content": "# Settings\n\nA Pharo developer can define **settings** to give users a way to easily customise... well, anything really.\nThe advantages of using the settings framework of Pharo are:\n- Users can change the value of any setting defined in the image with the **Settings Browser** window. No need to build a custom UI for it.\n- It is easy to add settings to an already existing application. A setting is basically just a class variable (or an instance variable of a singleton object) whose value can be set from the Settings Browser.\n- No dependency. Your application does not depend on the **Pharo Settings Framework**, and the Pharo Settings Framework does not depend on your application.\n\n## Table of Contents\n\n* [The Settings Browser](#the-settings-browser)\n* [Declaring a Setting](#declaring-a-setting)\n\t+ [As quick as possible](#as-quick-as-possible)\n\t+ [WARNING!: Default value of a setting](#warning-default-value-of-a-setting)\n\t+ [Elements of a Setting Declaration](#elements-of-a-setting-declaration)\n\t\t- [Id of the setting (#mySetting)](#id-of-the-setting-mysetting)\n\t\t- [Is it a setting or a group node? (setting:)](#is-it-a-setting-or-a-group-node-setting)\n\t\t- [Where is the variable this setting affects? (target:)](#where-is-the-variable-this-setting-affects-target)\n\t\t- [Label and Description (label: description:)](#label-and-description-label-description)\n\t\t- [Parent (parent:)](#parent-parent)\n\t+ [Other Features](#other-features)\n\t\t- [Ordering settings](#ordering-settings)\n\t\t- [Declaring optional settings](#declaring-optional-settings)\n\t\t- [Declaring a tree of settings in one method](#declaring-a-tree-of-settings-in-one-method)\n\t\t- [Providing more precise value domains](#providing-more-precise-value-domains)\n\t\t\t* [Declaring a range setting](#declaring-a-range-setting)\n\t\t\t* [Declaring a list of possible values](#declaring-a-list-of-possible-values)\n\t\t- [Launching a script](#launching-a-script)\n\t\t- [Start-up actions management](#start-up-actions-management)\n\t\t- [Extending the Settings Browser](#extending-the-settings-browser)\n* [Credits](#credits)\n\n\n## The Settings Browser\n\nThe Settings Browser can be opened from the Pharo menu like this:  \n![Open the Settings Browser](./Settings_Image_OpenSettingsBrowser.png)  \n*You can also open it by evaluating: `SettingBrowser open`*\n\nThe Settings Browser looks like this (The \"Appearance\" group of settings is expanded):  \n![The Settings Browser](./Settings_Image_SettingsBrowser.png)\n\n## Declaring a Setting\n\n### As quick as possible\nIn this example, the main class of my application is `MyApplication`, the name of my setting is `mySetting`, and it is a boolean setting.\n\n1. Create a `mySetting` class variable on the class `MyApplication`\n```Smalltalk\nObject subclass: #MyApplication\n\tinstanceVariableNames: ''\n\tclassVariableNames: 'mySetting'\n\tpackage: 'MyPack'\n```\n2. Create a getter and a setter method for it on the class, with a lazy initialisation in the getter\n```Smalltalk\nMyApplication class>>mySetting\n\tmySetting ifNil: [ mySetting := false ].\n\t^ mySetting\n```\n```Smalltalk\nMyApplication class>>mySetting: aValue\n\tmySetting := aValue\n```\n3. Create a method on the `MyApplication` class, to declare the setting:\n```Smalltalk\nMyApplication class>>mySettingSettingsOn: aBuilder\n\t<systemsettings>\n\t(aBuilder setting: #mySetting)\n\t\ttarget: MyApplication;\n\t\tlabel: 'My Setting' translated;\n\t\tdescription: 'A very important setting for my application';\n\t\tparent: nil.\n```\n4. Tada!\n![MySetting](./Settings_Image_MySetting.png)\n\n\n### WARNING!: Default value of a setting\n\n**A setting variable must never be `nil`!**\n\nTo display a setting, the Settings Browser chooses a widget based on the value of the setting variable (boolean -> check box, colour -> colour-picker, integer -> text field...). If the variable of a setting is worth `nil`, the Settings Browser cannot choose a widget.\n\nThe prefered method of ensuring the setting variable is initialised is by setting a lazy initialisation in the accessor method. This is because it also covers the case where the user resets the setting to its default value in the Settings Browser (the variable is set to `nil` in this case).\n\nIf this is not possible, then a default value can be indicated in the setting declaration. Example:  \n```Smalltalk\n(aBuilder setting: #caseSensitiveFinds)\n\tdefault:true;\n\t...\n```\n\n\n### Elements of a Setting Declaration\nHere is an example of a setting declaration. Below is a breakdown of its elements.\n```Smalltalk\nMyApplication class>>mySettingSettingsOn: aBuilder\n\t<systemsettings>\n\t(aBuilder setting: #mySetting)\n\t\ttarget: MyApplication;\n\t\tlabel: 'My Setting' translated;\n\t\tdescription: 'A very important setting for my application' translated;\n\t\tparent: nil.\n```\n\n#### Id of the setting (#mySetting)\nThe id of the setting. It is used to:\n- compute the names of the getter/setter methods to call to change the setting\n- for other settings to define this node as their parent in the settings tree (more on that later)\n\nExample:\n```Smalltalk\n(aBuilder setting: #mySetting)\n```  \nIn this example, the computed name of the getter method is `mySetting`. The computed name of the setter method is `mySetting:`.\n\n#### Is it a setting or a group node? (setting:)\nThe settings are arranged as a tree. Some nodes show a value that can be changed (like the #mySetting we just defined): these are **settings nodes**. Other nodes are just there for organisation purposes: these are **group nodes**.\n\n- Declaring a setting node:  \n```Smalltalk\n(aBuilder setting: #mySetting)\n```  \nResult:  \n![MySetting](./Settings_Image_MySettingSettingNode.png)\n- Declaring a group node:  \n```Smalltalk\n(aBuilder group: #mySetting)\n```  \nResult:  \n![MySetting group node](./Settings_Image_MySettingGroupNode.png)\n\n#### Where is the variable this setting affects? (target:)\n- If the setting is a **class variable**, the **target** of this setting is the class on which the variable is defined. Example:\n```Smalltalk\ntarget: MyApplication;\n```\n- If the setting is an **instance variable of a singleton instance**, the **target** of the setting is the class of the Singleton, and its **targetSelector** is the name of the method to call on that class to get the singleton instance. Example:\n```Smalltalk\ntarget: MySingleton;\ntargetSelector: #getCurrentInstance;\n```\nIn this example, when the settings framework will look for the variable holder, it will send `#getCurrentInstance` to `MySingleton`.\n\n#### Label and Description (label: description:)\nThese should be self-explanatory from the pictures. Example:\n```Smalltalk\nlabel: 'My Setting' translated;\ndescription: 'A very important setting for my application' translated;\n```  \nSending `translated` will greatly facilitate the translation into other languages.\n\n\n#### Parent (parent:)\nTo declare a setting node as a children of another, set its parent property to the id of its parent node. Example: (imagine another setting called `mySettingGroup` is defined elsewhere)\n```Smalltalk\nparent: #mySettingGroup\n```  \nResult:  \n![Another setting node as parent](./Settings_Image_Parent.png)\n\n\n### Other Features\n\n#### Ordering settings\nBy default, sibling settings are sorted alphabetically by their label. To change this, you can:\n- add `noOrdering` to the declaration of a group node, so that its children setting get ordered in the order in which they were declared. Example:\n```Smalltalk\nappearanceSettingsOn: aBuilder\n\t<systemsettings>\n\t(aBuildergroup:#appearance)\n\t\tlabel: 'Appearance' translated;\n\t\tnoOrdering;\n\t\twith: [... ]\n```\n- add `order:` (with a float or integer) to the declaration of a setting. Nodes with an order number are always placed before others and are sorted according to their respective order number. If an order is given to an item, then no ordering is applied for other siblings. Example:\n```Smalltalk\n(aBuilder group: #standardFonts)\n\tlabel: 'Standard fonts' translated;\n\twith: [\n\t\t(aBuilder launcher: #updateFromSystem)\n\t\t\torder:1;\n\t\t\tlabel: 'Update fonts from system' translated.\n\t\t(aBuilder setting: #defaultFont)\n\t\t\tlabel: 'Default' translated.\n\t\t(aBuilder setting: #codeFont)\n\t\t\tlabel: 'Code' translated.\n```\n\n#### Declaring optional settings\nSometimes, some settings do not make sense in all situations. For example, a setting to ask for a second background colour only makes sense if the user selected a gradient as background.  \nSettings whose parent is a boolean setting set to `false` will not be shown in the Settings Browser.\n\n#### Declaring a tree of settings in one method\nUse the `with:` methods to nest setting declarations. Nested settings will have the setting they are nested in as parent. Example:\n\n```Smalltalk\nRBConfigurableFormatter class>>settingsOn: aBuilder\n\t<systemsettings>\n\t(aBuilder group: #configurableFormatter)\n\t\ttarget: self;\n\t\tlabel: 'Configurable Formatter' translated;\n\t\twith:[\n\t\t\t(aBuilder setting: #formatCommentWithStatements)\n\t\t\t\tlabel: 'Format comment with statements' translated.\n\t\t\t(aBuilder setting: #indentString)\n\t\t\t\tlabel: 'Indent string' translated]\n```  \nResult:  \n![Nested Declaration Result](./Settings_Image_NestedDeclarationsResult.png)\n\n#### Providing more precise value domains\nBy default, the possible value set of a preference is not restricted and is given by the actual type of the preference. For example, for a color preference, the widget allows you to choose whatever color. For a number, the widget allows the user to enter any number. But in some cases, only a particular set of values is desired. There are two ways to do this:\n- Declaring a range setting\n- Declaring a list of possible values\n\n##### Declaring a range setting\n1. use `range:` as the type of setting, instead of `setting:` or `group:`\n2. set the `range:` property of the setting (for example: `range: (-5 to: 100)`)\n\nExample:\n```Smalltalk\nscreenMarginSettingOn: aBuilder\n\t<systemsettings>\n\t(aBuilder range: #fullScreenMargin)\n\t\ttarget: SystemWindow;\n\t\tparent: #windows;\n\t\tlabel: 'Full screen margin' translated;\n\t\trange:(-5 to: 100).\n```  \nResult:  \n![Range Setting](./Settings_Image_RangeSetting.png)\n\n##### Declaring a list of possible values\n1. use `pickOne:` as the type of setting, instead of `setting:` or `group:`\n2. set the `domainValues:` property of the setting to the list of possible values (for example: `domainValues: #(#'Reverse Stagger' #Cascade #Standard)`)\n\nExample:\n```Smalltalk\nwindowPositionStrategySettingsOn: aBuilder\n\t<systemsettings>\n\t(aBuilder pickOne: #usedStrategy)\n\t\tlabel: 'Window position strategy' translated;\n\t\ttarget: RealEstateAgent;\n\t\tdomainValues: #(#'Reverse Stagger' #Cascade #Standard)\n```  \nResult:  \n![List of Possible Values](./Settings_Image_ListOfPossibleValues.png)\n\nFor `domainValues:`, you can provide a list of **associations** instead of a list of values. In the Settings Browser, the user will select a value among the keys of these associations, but the setting variable will actually be set to the value corresponding to the selected key, not to the key itself.\n\nExample:  \n```Smalltalk\ndomainValues: {'Big' translated -> 25. 'Medium' translated -> 12. 'Small' -> 5}\n```  \nResult:  \nIn the Settings Browser, the user will choose between \"Big\", \"Medium\" and \"Small\", but the variable corresponding to the setting will actually be set to 25, 12 or 5 respectively.\n\nThe list of possible values **does not have to be static**. You can declare a piece of code that computes the list. It will be executed every time the Settings Browser is opened.  \n\nExample:\n```Smalltalk\ndomainValues: (UITheme allThemeClasses collect: [:c | c themeName -> c])\n```\n\n#### Launching a script\nImagine that you want to launch an external configuration tool or that you want to allow one to configure the system or a particular package with the help of a script. In such a case you can declare a *launcher*. A launcher is shown with a label as a regular setting except that no value is to be entered for it. Instead, a button labelled *Launch* is integrated in the Settings Browser and clicking on it launch an associated script.\n\nIllustration: \n![Launching a Script](./Settings_Image_LaunchingAScript.png)\n\n*More information in section 5.6 \"Launching a script\" of the [Deep Into Pharo book](http://books.pharo.org/deep-into-pharo/).*\n\n#### Start-up actions management\n\nEven if many preferences have been removed from Pharo because they were obsolete, there are a still a large number of them. And even if the Settings Browser is easy to use, it may be tedious to set up your own preferences even for a subset, each time you start working with a new image. A solution is to implement a script to set all your preferred choices. The best way is to create a specific class for that purpose. You can then include it in a package that you can reload each time you want to setup a fresh image. We call this kind of class a *Setting style*.  \nTo manage *Setting styles*, the Settings Browser can be helpful in two ways. First, it can help you discover how to change a preference value, and second, it can create and update a particular style for you.\n\n*More information in section 5.7 \"Start-up actions management\" of the [Deep Into Pharo book](http://books.pharo.org/deep-into-pharo/).*\n\n#### Extending the Settings Browser\n\nThe Settings Browser is by default able to manage simple preference types. These default possibilities are generally enough. But there are some situations where it can be very helpful to be able to handle more complex preference values.  \nAs an example, let us focus on the text selection preferences. We have the primary selection and three other optional kinds of text  selection, the secondary selection, the ‘find and replace’ selection and the selection bar. For all selections, a background color can be set. For the primary, the secondaryand the find and replace selection, a text color can also be chosen.\n\n*More information in section 5.8 \"Extending the Settings Browser\" of the [Deep Into Pharo book](http://books.pharo.org/deep-into-pharo/).*\n\n## Credits\nThomas Dupriez.  \nThis page is based on chapter 5 of the [Deep Into Pharo book](http://books.pharo.org/deep-into-pharo/): The Settings Framework  "
  },
  {
    "path": "General/SortingCollections.md",
    "content": "# Sorting collections\n\nA common requirement in software engineering is to sort collections. This page provides information on how to sort collections in Pharo.\n\n- [Sorting API](#sorting-api)\n  * [Sort a collection](#sort-a-collection)\n  * [Keep a collection sorted](#keep-a-collection-sorted)\n- [Sort functions](#sort-functions)\n- [Sorting via a block](#sorting-via-a-block)\n\n## Sorting API\n\nPharo's Collections come with an API to sort them. In this section, we will present some of it and explain their difference.\n\nThe default sorting implemented on Pharo's collection is a merge sort. Merge sort worst-case complexity is `O(N log N)`. This sorting algorithm usually does only half as many comparisons as heapsort or quicksort.\n\n### Sort a collection \n\nThe two main methods to sort a collection are `#sort:` and `#sorted:`. Those two methods are taking a block or a sort function as parameter (those are explained later in this page) and return a collection sorted based on the parameter.\nThe difference between the two methods is that `#sort:` sort the receiver when the `#sorted:` method sorts a copy of the receiver.\n\n```Smalltalk\n#(1 2 4 7 3 6 4) sort: #yourself ascending. \"#(1 2 3 4 4 6 7) <= This result is the receiver\"\n#(1 2 4 7 3 6 4) sorted: #yourself ascending. \"#(1 2 3 4 4 6 7) <= This result is a copy of the receiver\"\n```\n\nThose two methods also have an equivalent without argument, `#sort` and `#sorted` that sort the collection using the `#<=` comparison operator.\n\nThe API described here will sort a collection at one point but new elements added to the collection will not be sorted. If you wish to keep a collection sorted, you should use `SortedCollection` as explained in the next section.\n\n> Warning: If not absolutely needed, one should not use `SortedCollection` because it might impact performances of your software when adding and removing items to the collection.\n\n### Keep a collection sorted\n\nIn case you want to keep a collection sorted, you should use a `SortedCollection`. This collection is configured with a sort block or sort function and will sort all new elements added to the collection.\n\nYou can transform a collection into sorted collection using `#asSortedCollection:` or `#asSortedCollection`. \n\n```Smalltalk\n(#(1 2 4 7 3 6 4) asSortedCollection: #yourself ascending)\n\tadd: 2;\n\tyourself \"a SortedCollection(1 2 2 3 4 4 6 7)\"\n```\n\nYou can also instantiate yourself the sorted collection:\n\n```Smalltalk\n(SortedCollection sortUsing: #yourself ascending)\n\taddAll: #(1 2 4 7 3 6 4);\n\tyourself \"a SortedCollection(1 2 3 4 4 6 7)\"\n```\n\n```Smalltalk\n(SortedCollection sortBlock: [ :a :b | a < b ])\n\taddAll: #(1 2 4 7 3 6 4);\n\tyourself \"a SortedCollection(1 2 3 4 4 6 7)\"\n```\n\n> Note: #sortUsing: was introduced in Pharo 8. In previous versions it is possible to use #sortBlock: for both sort block and sort functions.\n\n## Sort functions\n\nThe first way to sort a collection is to use a sort function. A sort function is an object configuring how to sort a collection. They can be created in different ways and can be composed. \n\nYou can create a sort function using a property and a direction:\n\n```Smalltalk\n#('longstring' 'test' 'test2') sorted: #size ascending. \"#('test' 'test2' 'longstring')\"\n#('longstring' 'test' 'test2') sorted: [ :string | string size ] descending \"#('longstring' 'test2' 'test')\"\n```\n\n```Smalltalk\n#(#(1 2) #(2 3) #(0 0)) sorted: [:sequence | sequence inject: 0 into: [:sum :each | sum + each] ] descending. \"#(#(2 3) #(1 2) #(0 0))\"\n```\n\nYou can use 2 arguments blocks, for cases where the function isn't expressible with objects that respond to `<` and `=`. The only catch is that such a function should return true or false, but a collation order instead, values of -1 (for before), 0 (the same) or 1 (to follow). For example:\n\n```Smalltalk\n| oddBlock |\noddBlock := [ :a :b | a odd = b odd ifTrue: [ 0 ] ifFalse: [ a odd ifTrue: [ -1 ] ifFalse: [ 1 ] ] ].\n#(1 5 1 3 2 7 9 4 6) asSortedCollection: oddBlock descending\t\"a SortedCollection(6 2 4 3 1 7 9 5 1)\"\n```\n\nSince Pharo 8, it is also possible to express the previous sort function using a property returning a boolean:\n\n```Smalltalk\n#(1 5 1 3 2 7 9 4 6) asSortedCollection: #odd ascending\t\"a SortedCollection(6 2 4 3 1 7 9 5 1)\"\n```\n\nIn this case, the elements answering `false` will be placed before the elements answering true in the ascending order. This is explained by the fact that the function will sort the booleans according to their bit value (0 or 1).\n\n> If you wish to use this feature in a version earlier than Pharo 8, you can add this method as an [extension](Extensions.md) of the Boolean class:\n\n```Smalltalk\nthreeWayCompareTo: anotherObject\n\t^ self asBit threeWayCompareTo: anotherObject asBit\n```\n\nUsing #undefinedFirst and #undefinedLast it is possible to deal with nil values, moving them first or last. For Example:\n\n```Smalltalk\n#(a nil z b) sorted: #value ascending undefinedFirst. \"#(nil #a #b #z)\"\n#(a nil z b) sorted: #value ascending undefinedLast. \"#(#a #b #z nil)\"\n```\n\nFinally, you can use a chained sorted function in case you have elements of the same priority in the first sort function.\n\nIn this next example, we sort by size and for elements of same size we sort by alphabetical order:\n\n```Smalltalk\n#('test' 'toto1' 'test2' 'toto') sorted: #size ascending, #yourself ascending \"#('test' 'toto' 'test2' 'toto1')\"\n```\n\n## Sorting via a block\n\nThe second way to sort a collection is to use a sort block. A sort block takes two elements of the collection as parameter and should return a boolean describing if the first one should be before the second one.\n\n```Smalltalk\n#('longstring' 'test' 'test2') sorted: [ :string1 :string2 | string1 size < string2 size ]. \"#('test' 'test2' 'longstring')\"\n```\n"
  },
  {
    "path": "General/Traits.md",
    "content": "# Traits\n\n- [Description](#description)\n- [Create and use a new Trait](#create-and-use-a-new-trait)\n- [Abstract methods](#abstract-methods)\n- [Stateful traits](#stateful-traits)\n- [Traits initialization](#traits-initialization)\n- [Customize method received from a Trait](#customize-method-received-from-a-trait)\n  * [Reject some methods received from the trait](#reject-some-methods-received-from-the-trait)\n  * [Alias some methods received from the trait](#alias-some-methods-received-from-the-trait)\n- [Customize instance variables received from a (stateful) Trait](#customize-instance-variables-received-from-a-stateful-trait)\n  * [Reject some instance variables received from the trait](#reject-some-instance-variables-received-from-the-trait)\n  * [Alias some instance variables received from the trait](#alias-some-instance-variables-received-from-the-trait)\n- [Trait composition](#trait-composition)\n- [Conflicts](#conflicts)\n\n## Description\n\nTraits are pure units of behavior that can be composed to form classes or other traits. The trait composition mechanism is an alternative to multiple or mixin inheritance in which the composer has full control over the trait composition. It enables more reuse than single inheritance without introducing the drawbacks of multiple or mixin inheritance.\n\nPharo 7's Traits are modular and not tied to the Kernel. So it would be possible to have multiple implementations.\n\n## Create and use a new Trait\n\nCreation of a new Trait is close to the creation of a new class. It is done in a programatic way:\n\n```Smalltalk\nTrait named: #TNameOfMyTrait\n\tuses: {}\n\tpackage: 'MyPackage'\n```\n\nThis will create a new Trait called `TNameOfMyTrait` stored in `MyPackage`.\n\nConcrete example:\n\n```Smalltalk\nTrait named: #FamixTWithEnumValues\n\tuses: {}\n\tslots: {}\n\tpackage: 'Famix-Traits-EnumValue'\n```\n\n> Calypso provides a menu entry to create traits. To access it, right-click on the classes list (with no class or trait selected) and select \"New trait\".\n\n> **Warning**: In Pharo < 8, the message `#named:uses:slots:package:` should be replaced by `#named:uses:slots:category:`.  \n\nThen you add a new method to the Trait, just as you would implement a method in a class. All classes using this trait will be able to use methods created in the Traits except if for methods overriden by the class.\n\nTo use your Trait you just need to declare it in the class declaration as parameter of the `#uses:` keyword. \n\n```Smalltalk\nMySuperClass subclass: #MyClass\n\tuses: TNameOfMyTrait\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'MyPackage'\n```\n\nConcrete example:\n\n```Smalltalk\nFAMIXType subclass: #FAMIXEnum\n\tuses: FamixTWithEnumValues\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'Famix-Compatibility-Entities'\n```\n\nYou can also use multiple Traits with your class with the `#+` message.\n\n```Smalltalk\nMySuperClass subclass: #MyClass\n\tuses: TNameOfMyTrait + TNameOfMySecondTrait\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'MyPackage'\n```\n\n## Abstract methods\n\nWe might need to call a method for which the implementation will be specific to the class using the trait. To manage this case, a Trait can hold methods that explicitely declare that user should define it. These methods contain a call to `#explicitRequirement` message.\n\n```Smalltalk\nTMyTrait>>addButton: aButton\n\tself buttons add: aButton\n```\n\n```Smalltalk\nTMyTrait>>buttons\n\t^ self explicitRequirement\n```\n\n> Some Pharo developers create Traits with all their methods calling `#explicitRequirement` message. Doing this kind of simulate an interface (as Java's interfaces). Users of one of these traits thus declare that they support the interface it defines and override all methods defined by the trait.\n\n## Stateful traits\n\nSince Pharo 7, it is possible to add instance variables or a slot to Traits. This will make you trait a stateful trait. \n\nExamples:\n\n```Smalltalk\nTrait named: #MDLWithConfigurableRightPanel\n\tuses: {}\n\tslots: { #panelComponent. #toolbar }\n\tpackage: 'MaterialDesignLite-Extensions'\n```\n\n```Smalltalk\nTrait named: #FamixTWithEnumValues\n\tuses: {}\n\tslots: { #enumValues => FMMany type: #FamixTEnumValue opposite: #parentEnum }\n\tpackage: 'Famix-Traits-EnumValue'\n```\n\n## Traits initialization\n\nTraits do not include a way to initialize classes using them, it relies on conventions.\n\nOne way to manage this might be to implement a method named `initializeTMyTraitName` on each traits needing an initialization and to call all those methods on the class using them.\n\nIn case of trait composition (See [Trait composition](#trait-composition)), a trait composed of other traits can also implement a initialize method calling the one of the Traits it includes.\n\n## Customize method received from a Trait\nWhen a class uses a trait, it is possible for it to reject or alias some methods.\n\n### Reject some methods received from the trait\nIn some case it is needed to reject a method of a Trait. It can be achieved using `#-` message.\n\n```Smalltalk\nTestCase subclass: #StackTest\n\tuses: TEmptyTest - {#testIfNotEmptyifEmpty. #testIfEmpty. #testNotEmpty} + (TCloneTest - {#testCopyNonEmpty})\n\tslots: { #empty. #nonEmpty }\n\tclassVariables: {  }\n\tpackage: 'Collections-Tests-Stack'\n```\n\n### Alias some methods received from the trait\nIt is possible to alias some methods received from a trait. If, for example you alias `#aliasedMethod` with `#methodAlias` as shown below, your class will hold both `#methodAlias` and `#aliasedMethod`.\n\n```\nObject subclass: #MyObjectUsingTraitByAliasingMethod\n\tuses: TTraitToBeUsed @ { #methodAlias -> #aliasedMethod }\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'TestTraitAliasing'\n```\n\nHere is a simple example. Consider a situation when a trait `TLocated` implements a method `moveTo:` that defines the movement of an object to a given cell. The user of this trait needs to implement the post-movement operation. Usually, this would be done by overriding the `moveTo:` method and calling `super moveTo: aCell` in the first line of the new implementation. However, the super calls can not be used with traits as they install methods directly into the code of their users. The simple workaround would be to create an allias `basicMoveTo:` for the trait method and then call it from the new `moveTo:` method implemented by the user class:\n\n```st\nTLocated >> moveTo: aCell\n    \"Define the movement\"\n\nObject subclass: #Antelope\n    uses: TLocated @ { #basicMoveTo: -> #moveTo: }\n    ...\n\nAntelope >> moveTo: aCell\n    self basicMoveTo: aCell.\n    \"Do some post-movement actions\"\n```\n\n## Customize instance variables received from a (stateful) Trait\nWhen a class uses a trait, it is possible for it to reject or alias some instance variables.\n\n### Reject some instance variables received from the trait\nIn some case it is needed to reject an instance variable of a Trait. It can be achieved using `#--` message. It works similarly to methods rejecting explaining in previous section.\n\n```\nObject subclass: #MyObjectUsingTraitByRejectingInstVar\n\tuses: TTraitToBeUsed asTraitComposition -- #instVarNameToRemove\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'TestTraitAliasing'\n```\n\n> `#asTraitComposition` needs to sent to the trait because `#--` message is not understood by trait but by trait composition.\n\n### Alias some instance variables received from the trait\nIt is possible to alias some instance variables received from a trait. If, for example you alias `#aliasedInstVar` with `#instVarAlias` as shown below, your class will hold both `#instVarAlias` and `#aliasedInstVar`.\n\n```\nObject subclass: #MyObjectUsingTraitByAliasingInstVar\n\tuses: (TTraitToBeUsed >> { #instVarAlias -> #aliasedInstVar })\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'TestTraitAliasing'\n```\n\n## Trait composition\n\nTraits are composable, this mean that you can have Traits using other traits. It is done in the same way than class using a Trait:\n\n```Smalltalk\nTrait named: TMyComposedTrait\n\tuses: TMyFirstTrait + TMySecondTrait\n\tpackage: 'MyPackage'\n```\n\nExample:\n\n```Smalltalk\nTrait named: #EpTEventVisitor\n\tuses: EpTCodeChangeVisitor\n\tpackage: 'Epicea-Visitors'\n```\n## Conflicts\n\nTwo kinds of *conflicts* can happen with methods implemented on Traits.\n\n1. A method is present on a used Trait, but the class using this Trait also implements this method. In that case, the method lookup will select the method from the class. It is an equivalent of an override of method.\n\n2. Two traits implementing the same method are used. In that case, if the method is called it will raise an error `traitConflict`.\n\nA way to solve both cases is to use method aliasing and to remove the conflicting method:\n```Smalltalk\nObject subclass: #MyObjectUsingTraitByAliasingMethod\n\tuses: TTraitToBeUsed @ { #methodAlias -> #conflictingMethod } - { #conflictingMethod }\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'TestTraitAliasing'\n```\n\nAnother way to solve case 2. is to implement a method on the class using the trait in order to chose the behavior wanted.\n"
  },
  {
    "path": "General/Travis.md",
    "content": "# Setting up Travis Continuous Integration\n\n> IMPORTANT NOTE: Since Travis is becoming a pay to use service, it is possible that this documentation will not be updated anymore.\n> [A page on how to use Github Actions](GithubActions.md) in order to have a continuous integration is already available on this wiki.\n\nYour repository should have two extra hidden files: `.travis.yml` and `.smalltalk.ston`.\nIn addition, you may want to have a `.coveralls` configuration to support automatic coverage computation.\n\n# `.travis.yml`\nHere is a basic `.travis.yml` that configure travis to create a matrix to run your projects tests on both linux and osx plateforms and for both Pharo 8.0 and Pharo 7.0 64 bits.\n\n```yaml\nlanguage: smalltalk\nsudo: false\n\nos:\n  - linux\n  - osx\n\nsmalltalk:\n  - Pharo64-8.0\n  - Pharo64-7.0\n```\n\n# `.smalltalk.ston`\n`.smalltalk.ston` is the file where you specify the baseline to use for your project and the packages containing the tests (used to compute coverage).\n\n```\nSmalltalkCISpec {\n  #loading : [\n    SCIMetacelloLoadSpec {\n      #baseline : 'EnlumineurFormatter',\n      #directory : 'src',\n      #platforms : [ #pharo ]\n    }\n  ],\n  #testing : {\n    #coverage : {\n      #packages : [ 'EnlumineurFormatter-Tests' ]\n    }\n  }\n}\n```\n\n# `.coveralls.yml`\nIf one have a coveralls account, one can add a `.coveralls.yml` file with the coveralls token of their project.\n\n\n```yaml\nservice_name: travis-pro\nrepo_token: twxvbgLWXzoj3syZg3eaYfBZxCKEbensg\n```\n"
  },
  {
    "path": "General/TweakingBigImages.md",
    "content": "# Tweaking big images\n\nPharo is special in the sense that the language and IDE are mixed. It means that your application runs together with the IDE.\nIn some cases, it leads to Pharo images consuming a large amount of memory (aka Big Images). \nThe goal of this page is to sum up some tweaking that can be done on Pharo images to improve the performances of such images. \n\n* [Fast dragging](#fast-dragging)\n* [Disable taskbar previews](#disable-taskbar-previews)\n* [Tune Garbage Collection](#tune-garbage-collection)\n* [Disable Quality Assistant plugin](#disable-quality-assistant-plugin)\n* [Disable Spotter plugins](#disable-spotter-plugins)\n* [Disable Epicea](#disable-epicea)\n\n## Fast dragging\n\nWhile dragging windows in Pharo, an animation is run. This animation is not performant and can make the dragging of windows slow in large images.\n\nAs a workaround, it is possible to solve this problem by enabling a \"fast dragging\" option:\n\n```Smalltalk\nUITheme currentSettings fastDragging: true\n```\n\n> Remark: This option is reset when one change the theme Pharo. Thus, you should execute this code snippet each time you update the theme.\n\n## Disable taskbar previews\n\nWhile going over the taskbar of Pharo, previews of the images are displayed. This feature can be really slow on big images. \nIt is possible to disable it:\n\n```Smalltalk\nTaskbarMorph showWindowPreview: false\n```\n\n## Tune Garbage Collection \n\nPharo is a language using a [garbage collector](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) for its memory management. \nWhen objects are created, memory is allocated for them. Once in a while, the memory is cleaned and the garbage collector frees the memory of objects that are not used anymore.\n\nThis process can be customized via multiple parameters. To understand the impact of those parameters we explain here how garbage collection works in Pharo.\n\nBecause most objects usage stops quickly after their instantiation (we say they have a short life-time), Pharo memory (aka \"the heap\") is divided into multiple spaces:\n- The \"Old space\" contains objects that survived multiples garbage collections (GC). When it is filled, new memory segments are allocated to the old space.\n- The \"New Space\" contains recently created objects. \n\nThe \"New Space\" is divided into 3 sub spaces:\n- The \"Eden\" containing the newest objects created (taking 5/7 of the new space)\n- Two survivors spaces (1/7 of the new space each) contains the object that survived some garbage collection already\n\nThe Garbage Collector execute two kind of cleanings:\n- The **scavenge** happens when the Eden is filled at a certain ratio and will clean the Eden. When objects from the eden are still referenced, they are moved to the survivors. There are two kinds of survivors: past survivor space and future survivor space (past space and future space for short). Past and future space swap after each scavenge, which empties eden and past space, copying survivors into future space, tenuring overflow to old space and then making future space the new past space. When the survivor space is fill at more than 90%, the survivors are moved to the old space.\n- The **full garbage collect** (aka full GC) happens when the heap grow past a certain ratio. It will go through the old space and clean the old objects.\n\nWe can customize multiple parameters.\n\nThe size of the new space can be increased. When it increases, scavenges will happen less often.\nThis can increase a lot the speed of algorithm creating a lot of new objects. \n\nThe size of the eden can be accessed via the vm parameter 44. The desired size of the new space can be set via the vm parameter 45. \n\nBy default, the new space size is 3.8Mo. It can be increased to 32 or 64Mo if you have enough memory.\n\n```Smalltalk\nSmalltalk vm parameterAt: 44. \"9057248\"\nSmalltalk vm parameterAt: 45 put: 64 * 1024 * 1024\n```\n\n> Since the eden size is fixed at startup, this change requires to restart the image.\n\nIf you create at some point a lot of objects that will stay for a while, you can increase the size of new memory segments to allocate in order to spend less time to allocate memory. \n\nBy default the growth is of 16Mo.\n\n```Smalltalk\nSmalltalk vm parameterAt: 25 put: 32 * 1024 * 1024\n```\n\nIf your memory needs to grow and shrink a lot, you can also increase the memory threshold above which shrinking object memory happens. \n\nBy default, 32Mo.\n\n```Smalltalk\nSmalltalk vm parameterAt: 24 put: 64 * 1024 * 1024\n```\n\nYou can also increase the ratio of growth and image size at or above which a GC will be performed\tpost scavenge.\n\nBy default, 0.33. This parameter needs to be a float. \n\nIf you use a really high ratio such as 200.0+, no full GC will happen.\n\n```Smalltalk\nSmalltalk vm parameterAt: 55 put: 0.7\n```\n\n> Note: Those 3 last parameters are reset during image startup. \n> In order to maintain them, you can use startup actions. See [Session management documentation](SessionsManagement.md).\n\n> This might change in the future (https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/477).\n\nBy tweaking those parameters, algorithm that took 9min30 before are now taking less than 5min with images of 1.3Go.\n\nThanks to [Eliot Miranda](http://www.mirandabanda.org/cogblog/microbio/) and [Clément Bera](https://clementbera.wordpress.com/) for the explanations.\n\nFor more information: [https://clementbera.wordpress.com/2017/03/12/tuning-the-pharo-garbage-collector](https://clementbera.wordpress.com/2017/03/12/tuning-the-pharo-garbage-collector)\n\n## Disable Quality Assistant plugin\n\nThe code browser in Pharo has a plugin to display code critics. This plugin can take some time to compute the rules in case of large images. It is possible to disable it:\n\n```Smalltalk\nClyCriticBrowserPlugin disable\n```\n\n## Disable Spotter plugins\n\nPharo's spotter has many plugins to search for and display results of mny kind.\n\nSome of those searchs can be long to compute in big images. It is possible to disable the extensions that do not interest us.\n\nYou can find the list of extensions executing:\n\n```Smalltalk\nGTSpotter spotterExtendingMethods\n```\n\nThen you caqn disable an extension. For example if you have poor network you can disable the extension looking for projects in the Pharo catalog.\n\n```Smalltalk\nGTSpotterExtensionSettings disabledExtensions add: 'GTSpotter_spotterCatalogProjectsFor'\n```\n\nThe name of the extension to disable should be of this form: `ClassContainingTheExtension_nameOfTheMethodWithoutLastSemicolon`.\n\nIn case of images with a lot of code, it is possible that many projects extend the world menu. In this case the world menu plugin can be long to search. You can diable it this way:\n\n```Smalltalk\nGTSpotterExtensionSettings disabledExtensions add: 'GTSpotter_spotterWorldMenuFor'\n```\n\nThe extensions to disable will most probably depend on what fills the size of your image. Look through the list and estimate what can take timefor you and what do not interest you. \n\n## Disable Epicea\n\nWhen you compile code, all the changes are persisted in files by the **Epicea** tool. This allows one to revert/replay changes and to get back lost changes in case an image crash. \n\nDisabling Epicea can speed up the work in large images:\n\n```Smalltalk\nEpMonitor reset\n````\n\n> WARNING: Disabling Epicea will remove the possibility to replay changes in case your image crash. Disable it only if necessary!\n"
  },
  {
    "path": "General/Windows10SubsystemForLinux.md",
    "content": "# How to get Pharo running on WSL\n\nPharo can be run under Windows 10 Subsystem for Linux (WSL).\n\n- Install WSL (see [microsoft documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10))\n- Install X Server for Windows (I used [VcXsrv](https://sourceforge.net/projects/vcxsrv/)).\n- Install [Mesa](https://wiki.debian.org/Mesa) with `sudo apt install mesa-utils` (needed because there are missing libraries for the x11 display used by Pharo).\n> Note: The Mesa dependency may be overkill. On the [Pharo install page](https://pharo.org/web/gnu-linux-installation-64) there's mention of some things to do for Ubuntu 16. \n- Install Pharo:\n\n```bash\n$ mkdir MyPharo\n$ cd MyPharo/\n$ curl -L https://get.pharo.org/64/ | bash\n```\n\nThe last step can also be the Pharo Launcher.\n\n> Note: Last time it has been tested, only Pharo of version >= 6 64bit could be run.\n> Pharo 32bits is not compatible because of a missing part of the kernel.\n\nFor other Pharo/WSL issues, see [this blog](https://fuhrmanator.github.io/2019/02/27/Pharo-in-WSL.html). \n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2018 pharo-wiki\n\nAttribution 4.0 International\n\n=======================================================================\n\nCreative Commons Corporation (\"Creative Commons\") is not a law firm and\ndoes not provide legal services or legal advice. Distribution of\nCreative Commons public licenses does not create a lawyer-client or\nother relationship. Creative Commons makes its licenses and related\ninformation available on an \"as-is\" basis. Creative Commons gives no\nwarranties regarding its licenses, any material licensed under their\nterms and conditions, or any related information. Creative Commons\ndisclaims all liability for damages resulting from their use to the\nfullest extent possible.\n\nUsing Creative Commons Public Licenses\n\nCreative Commons public licenses provide a standard set of terms and\nconditions that creators and other rights holders may use to share\noriginal works of authorship and other material subject to copyright\nand certain other rights specified in the public license below. The\nfollowing considerations are for informational purposes only, are not\nexhaustive, and do not form part of our licenses.\n\n     Considerations for licensors: Our public licenses are\n     intended for use by those authorized to give the public\n     permission to use material in ways otherwise restricted by\n     copyright and certain other rights. Our licenses are\n     irrevocable. Licensors should read and understand the terms\n     and conditions of the license they choose before applying it.\n     Licensors should also secure all rights necessary before\n     applying our licenses so that the public can reuse the\n     material as expected. Licensors should clearly mark any\n     material not subject to the license. This includes other CC-\n     licensed material, or material used under an exception or\n     limitation to copyright. More considerations for licensors:\n\twiki.creativecommons.org/Considerations_for_licensors\n\n     Considerations for the public: By using one of our public\n     licenses, a licensor grants the public permission to use the\n     licensed material under specified terms and conditions. If\n     the licensor's permission is not necessary for any reason--for\n     example, because of any applicable exception or limitation to\n     copyright--then that use is not regulated by the license. Our\n     licenses grant only permissions under copyright and certain\n     other rights that a licensor has authority to grant. Use of\n     the licensed material may still be restricted for other\n     reasons, including because others have copyright or other\n     rights in the material. A licensor may make special requests,\n     such as asking that all changes be marked or described.\n     Although not required by our licenses, you are encouraged to\n     respect those requests where reasonable. More_considerations\n     for the public:\n\twiki.creativecommons.org/Considerations_for_licensees\n\n=======================================================================\n\nCreative Commons Attribution 4.0 International Public License\n\nBy exercising the Licensed Rights (defined below), You accept and agree\nto be bound by the terms and conditions of this Creative Commons\nAttribution 4.0 International Public License (\"Public License\"). To the\nextent this Public License may be interpreted as a contract, You are\ngranted the Licensed Rights in consideration of Your acceptance of\nthese terms and conditions, and the Licensor grants You such rights in\nconsideration of benefits the Licensor receives from making the\nLicensed Material available under these terms and conditions.\n\n\nSection 1 -- Definitions.\n\n  a. Adapted Material means material subject to Copyright and Similar\n     Rights that is derived from or based upon the Licensed Material\n     and in which the Licensed Material is translated, altered,\n     arranged, transformed, or otherwise modified in a manner requiring\n     permission under the Copyright and Similar Rights held by the\n     Licensor. For purposes of this Public License, where the Licensed\n     Material is a musical work, performance, or sound recording,\n     Adapted Material is always produced where the Licensed Material is\n     synched in timed relation with a moving image.\n\n  b. Adapter's License means the license You apply to Your Copyright\n     and Similar Rights in Your contributions to Adapted Material in\n     accordance with the terms and conditions of this Public License.\n\n  c. Copyright and Similar Rights means copyright and/or similar rights\n     closely related to copyright including, without limitation,\n     performance, broadcast, sound recording, and Sui Generis Database\n     Rights, without regard to how the rights are labeled or\n     categorized. For purposes of this Public License, the rights\n     specified in Section 2(b)(1)-(2) are not Copyright and Similar\n     Rights.\n\n  d. Effective Technological Measures means those measures that, in the\n     absence of proper authority, may not be circumvented under laws\n     fulfilling obligations under Article 11 of the WIPO Copyright\n     Treaty adopted on December 20, 1996, and/or similar international\n     agreements.\n\n  e. Exceptions and Limitations means fair use, fair dealing, and/or\n     any other exception or limitation to Copyright and Similar Rights\n     that applies to Your use of the Licensed Material.\n\n  f. Licensed Material means the artistic or literary work, database,\n     or other material to which the Licensor applied this Public\n     License.\n\n  g. Licensed Rights means the rights granted to You subject to the\n     terms and conditions of this Public License, which are limited to\n     all Copyright and Similar Rights that apply to Your use of the\n     Licensed Material and that the Licensor has authority to license.\n\n  h. Licensor means the individual(s) or entity(ies) granting rights\n     under this Public License.\n\n  i. Share means to provide material to the public by any means or\n     process that requires permission under the Licensed Rights, such\n     as reproduction, public display, public performance, distribution,\n     dissemination, communication, or importation, and to make material\n     available to the public including in ways that members of the\n     public may access the material from a place and at a time\n     individually chosen by them.\n\n  j. Sui Generis Database Rights means rights other than copyright\n     resulting from Directive 96/9/EC of the European Parliament and of\n     the Council of 11 March 1996 on the legal protection of databases,\n     as amended and/or succeeded, as well as other essentially\n     equivalent rights anywhere in the world.\n\n  k. You means the individual or entity exercising the Licensed Rights\n     under this Public License. Your has a corresponding meaning.\n\n\nSection 2 -- Scope.\n\n  a. License grant.\n\n       1. Subject to the terms and conditions of this Public License,\n          the Licensor hereby grants You a worldwide, royalty-free,\n          non-sublicensable, non-exclusive, irrevocable license to\n          exercise the Licensed Rights in the Licensed Material to:\n\n            a. reproduce and Share the Licensed Material, in whole or\n               in part; and\n\n            b. produce, reproduce, and Share Adapted Material.\n\n       2. Exceptions and Limitations. For the avoidance of doubt, where\n          Exceptions and Limitations apply to Your use, this Public\n          License does not apply, and You do not need to comply with\n          its terms and conditions.\n\n       3. Term. The term of this Public License is specified in Section\n          6(a).\n\n       4. Media and formats; technical modifications allowed. The\n          Licensor authorizes You to exercise the Licensed Rights in\n          all media and formats whether now known or hereafter created,\n          and to make technical modifications necessary to do so. The\n          Licensor waives and/or agrees not to assert any right or\n          authority to forbid You from making technical modifications\n          necessary to exercise the Licensed Rights, including\n          technical modifications necessary to circumvent Effective\n          Technological Measures. For purposes of this Public License,\n          simply making modifications authorized by this Section 2(a)\n          (4) never produces Adapted Material.\n\n       5. Downstream recipients.\n\n            a. Offer from the Licensor -- Licensed Material. Every\n               recipient of the Licensed Material automatically\n               receives an offer from the Licensor to exercise the\n               Licensed Rights under the terms and conditions of this\n               Public License.\n\n            b. No downstream restrictions. You may not offer or impose\n               any additional or different terms or conditions on, or\n               apply any Effective Technological Measures to, the\n               Licensed Material if doing so restricts exercise of the\n               Licensed Rights by any recipient of the Licensed\n               Material.\n\n       6. No endorsement. Nothing in this Public License constitutes or\n          may be construed as permission to assert or imply that You\n          are, or that Your use of the Licensed Material is, connected\n          with, or sponsored, endorsed, or granted official status by,\n          the Licensor or others designated to receive attribution as\n          provided in Section 3(a)(1)(A)(i).\n\n  b. Other rights.\n\n       1. Moral rights, such as the right of integrity, are not\n          licensed under this Public License, nor are publicity,\n          privacy, and/or other similar personality rights; however, to\n          the extent possible, the Licensor waives and/or agrees not to\n          assert any such rights held by the Licensor to the limited\n          extent necessary to allow You to exercise the Licensed\n          Rights, but not otherwise.\n\n       2. Patent and trademark rights are not licensed under this\n          Public License.\n\n       3. To the extent possible, the Licensor waives any right to\n          collect royalties from You for the exercise of the Licensed\n          Rights, whether directly or through a collecting society\n          under any voluntary or waivable statutory or compulsory\n          licensing scheme. In all other cases the Licensor expressly\n          reserves any right to collect such royalties.\n\n\nSection 3 -- License Conditions.\n\nYour exercise of the Licensed Rights is expressly made subject to the\nfollowing conditions.\n\n  a. Attribution.\n\n       1. If You Share the Licensed Material (including in modified\n          form), You must:\n\n            a. retain the following if it is supplied by the Licensor\n               with the Licensed Material:\n\n                 i. identification of the creator(s) of the Licensed\n                    Material and any others designated to receive\n                    attribution, in any reasonable manner requested by\n                    the Licensor (including by pseudonym if\n                    designated);\n\n                ii. a copyright notice;\n\n               iii. a notice that refers to this Public License;\n\n                iv. a notice that refers to the disclaimer of\n                    warranties;\n\n                 v. a URI or hyperlink to the Licensed Material to the\n                    extent reasonably practicable;\n\n            b. indicate if You modified the Licensed Material and\n               retain an indication of any previous modifications; and\n\n            c. indicate the Licensed Material is licensed under this\n               Public License, and include the text of, or the URI or\n               hyperlink to, this Public License.\n\n       2. You may satisfy the conditions in Section 3(a)(1) in any\n          reasonable manner based on the medium, means, and context in\n          which You Share the Licensed Material. For example, it may be\n          reasonable to satisfy the conditions by providing a URI or\n          hyperlink to a resource that includes the required\n          information.\n\n       3. If requested by the Licensor, You must remove any of the\n          information required by Section 3(a)(1)(A) to the extent\n          reasonably practicable.\n\n       4. If You Share Adapted Material You produce, the Adapter's\n          License You apply must not prevent recipients of the Adapted\n          Material from complying with this Public License.\n\n\nSection 4 -- Sui Generis Database Rights.\n\nWhere the Licensed Rights include Sui Generis Database Rights that\napply to Your use of the Licensed Material:\n\n  a. for the avoidance of doubt, Section 2(a)(1) grants You the right\n     to extract, reuse, reproduce, and Share all or a substantial\n     portion of the contents of the database;\n\n  b. if You include all or a substantial portion of the database\n     contents in a database in which You have Sui Generis Database\n     Rights, then the database in which You have Sui Generis Database\n     Rights (but not its individual contents) is Adapted Material; and\n\n  c. You must comply with the conditions in Section 3(a) if You Share\n     all or a substantial portion of the contents of the database.\n\nFor the avoidance of doubt, this Section 4 supplements and does not\nreplace Your obligations under this Public License where the Licensed\nRights include other Copyright and Similar Rights.\n\n\nSection 5 -- Disclaimer of Warranties and Limitation of Liability.\n\n  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE\n     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS\n     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF\n     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,\n     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,\n     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR\n     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,\n     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT\n     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT\n     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.\n\n  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE\n     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,\n     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,\n     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,\n     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR\n     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN\n     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR\n     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR\n     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.\n\n  c. The disclaimer of warranties and limitation of liability provided\n     above shall be interpreted in a manner that, to the extent\n     possible, most closely approximates an absolute disclaimer and\n     waiver of all liability.\n\n\nSection 6 -- Term and Termination.\n\n  a. This Public License applies for the term of the Copyright and\n     Similar Rights licensed here. However, if You fail to comply with\n     this Public License, then Your rights under this Public License\n     terminate automatically.\n\n  b. Where Your right to use the Licensed Material has terminated under\n     Section 6(a), it reinstates:\n\n       1. automatically as of the date the violation is cured, provided\n          it is cured within 30 days of Your discovery of the\n          violation; or\n\n       2. upon express reinstatement by the Licensor.\n\n     For the avoidance of doubt, this Section 6(b) does not affect any\n     right the Licensor may have to seek remedies for Your violations\n     of this Public License.\n\n  c. For the avoidance of doubt, the Licensor may also offer the\n     Licensed Material under separate terms or conditions or stop\n     distributing the Licensed Material at any time; however, doing so\n     will not terminate this Public License.\n\n  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public\n     License.\n\n\nSection 7 -- Other Terms and Conditions.\n\n  a. The Licensor shall not be bound by any additional or different\n     terms or conditions communicated by You unless expressly agreed.\n\n  b. Any arrangements, understandings, or agreements regarding the\n     Licensed Material not stated herein are separate from and\n     independent of the terms and conditions of this Public License.\n\n\nSection 8 -- Interpretation.\n\n  a. For the avoidance of doubt, this Public License does not, and\n     shall not be interpreted to, reduce, limit, restrict, or impose\n     conditions on any use of the Licensed Material that could lawfully\n     be made without permission under this Public License.\n\n  b. To the extent possible, if any provision of this Public License is\n     deemed unenforceable, it shall be automatically reformed to the\n     minimum extent necessary to make it enforceable. If the provision\n     cannot be reformed, it shall be severed from this Public License\n     without affecting the enforceability of the remaining terms and\n     conditions.\n\n  c. No term or condition of this Public License will be waived and no\n     failure to comply consented to unless expressly agreed to by the\n     Licensor.\n\n  d. Nothing in this Public License constitutes or may be interpreted\n     as a limitation upon, or waiver of, any privileges and immunities\n     that apply to the Licensor or You, including from the legal\n     processes of any jurisdiction or authority.\n\n\n=======================================================================\n\nCreative Commons is not a party to its public\nlicenses. Notwithstanding, Creative Commons may elect to apply one of\nits public licenses to material it publishes and in those instances\nwill be considered the “Licensor.” The text of the Creative Commons\npublic licenses is dedicated to the public domain under the CC0 Public\nDomain Dedication. Except for the limited purpose of indicating that\nmaterial is shared under a Creative Commons public license or as\notherwise permitted by the Creative Commons policies published at\ncreativecommons.org/policies, Creative Commons does not authorize the\nuse of the trademark \"Creative Commons\" or any other trademark or logo\nof Creative Commons without its prior written consent including,\nwithout limitation, in connection with any unauthorized modifications\nto any of its public licenses or any other arrangements,\nunderstandings, or agreements concerning use of licensed material. For\nthe avoidance of doubt, this paragraph does not form part of the\npublic licenses.\n\nCreative Commons may be contacted at creativecommons.org.\n"
  },
  {
    "path": "MANIFEST.md",
    "content": "# Pharo wiki manifest\n\nThis file will explain the goals of this project and define its boundaries. \n\nPharo-wiki is a user maintained wiki on the programming language and development environment Pharo and its ecosystem.\n\nThe goals of the project are to provide:\n- documentation on parts of Pharo that are not yet or poorly documented;\n- a centralized source of information on Pharo;\n- pointers to existing documentation;\n- tips on possible workflow on Pharo using all the strength of the environment;\n- references to external libraries;\n- migration guides between differents versions of Pharo.\n\nThe project should be easy to contribute to (with a github account the user should just have to edit a file on the github interface to contribute)\n\nTo be easy to contribute, this project is written in Markdown and hosted on github. Anyone with a github account can easily provide a Pull Request. (See [Contribution guide](CONTRIBUTION.md))\n\nTo achieve these goals, the project is divided into the following sections:\n\n* [Beginners](https://github.com/pharo-open-documentation/pharo-wiki#beginners) - guides for beginners who have just recently discovered Pharo.\n* [General](https://github.com/pharo-open-documentation/pharo-wiki#general) - pages describing some of Pharo mechanism and guides on possible workflows.\n* [Pharo projects](https://github.com/pharo-open-documentation/pharo-wiki#pharo-projects) - documentation about subprojects contained in the Pharo general distribution.\n* [External projects](https://github.com/pharo-open-documentation/pharo-wiki#external-projects) - information about external projects. Most of the pages give some examples to give an idea on how those project work and offer comparisons between multiple projects around the same theme.\n* [Migration guidelines](https://github.com/pharo-open-documentation/pharo-wiki#migration-guidelines) - migration guides between different versions of Pharo.\n* [External ressources](https://github.com/pharo-open-documentation/pharo-wiki#external-ressources) - links to ressources not maintained by the wiki community but interesting to check-out.\n\nAs long as they fit the goals of the wiki, the entries of this project can be:\n- documentation\n- tutorials\n- guides\n- tips and tricks\n\nIf you want to contribute but you are not sure your contribution fits the goals of the project, do not hesitate to open an issue to ask the maintainers for advice.\n\nIf you wish to contribute, you should read the [contribution guide](CONTRIBUTION.md).\n"
  },
  {
    "path": "Migration/MigrationToPharo7.md",
    "content": "# Migration from Pharo 6.1 to Pharo 7.0 guideline\n\n## Pharo 7 file streams guideline\n\nSince version 5, Pharo provides a new file streams API that deprecates the one based on classes \nlike `FileStream` or `MultiByteBinaryOrTextStream`. In Pharo 7 this deprecated API was removed from the kernel.\n\n### Key points\n\n- use file references as entry points to file streams\n- do not use the `FileStream` class\n- `'file.txt' asFileReference readStream` and similar methods now return an instance of `ZnCharacterReadStream`\ninstead of `MultiByteFileStream`\n- `'file.txt' asFileReference writeStream` and similar methods now return an instance of `ZnCharacterWriteStream` \ninstead of `MultiByteFileStream`\n- the new API has a clearer separation between binary and text files\n\n### Code conversion\n\nThis section shows the most common examples of file streams. For simplicity, errors are not handled.\n\n#### Force creation of a new file and write a UTF-8 text\n\n##### obsolete code\n```smalltalk\nFileStream forceNewFileNamed: '1.txt' do: [ :stream | stream nextPutAll: 'a ≠ b' ].\n```\n\n##### new code\n```smalltalk\n'1.txt' asFileReference ensureDelete; \n\twriteStreamDo: [ :stream | stream nextPutAll: 'a ≠ b' ].\n```\n\n#### Read UTF-8 text from an existing file\n\n##### obsolete code\n```smalltalk\nFileStream readOnlyFileNamed: '1.txt' do: [ :stream | \n\tstream upToEnd ].\n```\n\n##### new code\n```smalltalk\n'1.txt' asFileReference readStreamDo: [ :stream | \n\tstream upToEnd ].\n```\n\n#### Get all content of existing UTF-8 file\n\n##### obsolete code\n```smalltalk\n(FileStream readOnlyFileNamed: '1.txt') contentsOfEntireFile.\n  ```\n\n##### new code\n```smalltalk\n'1.txt' asFileReference readStream upToEnd.\n```\n\n#### Force creation of a new file and write binary data into it\n\n##### obsolete code\n```smalltalk\n(FileStream forceNewFileNamed: '1.bin') \n\tbinary;\n\tnextPutAll: #[1 2 3].\n```\n\n##### new code\n```smalltalk\n'1.bin' asFileReference ensureDelete; \n\tbinaryWriteStreamDo: [ :stream | stream nextPutAll: #[1 2 3] ].\n```\n\n#### Read binary data from an existing file\n\n##### obsolete code\n```smalltalk\n(FileStream readOnlyFileNamed: '1.bin') binary; contentsOfEntireFile.\n```\n\n##### new code\n```smalltalk\n'1.bin' asFileReference binaryReadStream upToEnd.\n```\n\n#### Force creation of a new file with a different encoding\n\n##### obsolete code\n```smalltalk\nFileStream forceNewFileNamed: '2.txt' do: [ :stream | \n\tstream converter: (TextConverter newForEncoding: 'cp-1250').\n\tstream nextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.' ].\n```\n\n##### new code\n```smalltalk\n('2.txt' asFileReference) ensureDelete;\n\twriteStreamEncoded: 'cp-1250' do: [ :stream |\n\t\tstream nextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.' ].\n```\n\n#### Read encoded text from an existing file\n\n##### obsolete code\n```smalltalk\nFileStream readOnlyFileNamed: '2.txt' do: [ :stream | \n\tstream converter: (TextConverter newForEncoding: 'cp-1250').\n\tstream upToEnd ].\n\n```\n\n##### new code\n```smalltalk\n('2.txt' asFileReference)\n\treadStreamEncoded: 'cp-1250' do: [ :stream |\n\t\tstream upToEnd ].\n```\n\n#### Write a UTF-8 text to STDOUT\n\n##### obsolete code\n```smalltalk\nFileStream stdout nextPutAll: 'a ≠ b'; lf.\n```\n\n##### new code\n```smalltalk\n(ZnCharacterWriteStream on: Stdio stdout)\n\tnextPutAll: 'a ≠ b'; lf;\n\tflush.\n```\n\n#### Write CP-1250 encoded text to STDOUT\n\n##### obsolete code\n```smalltalk\nFileStream stdout \n\tconverter: (TextConverter newForEncoding: 'cp-1250');\n\tnextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.'; lf.\n```\n\n##### new code\n```smalltalk\n(ZnCharacterWriteStream on: Stdio stdout encoding: 'cp1250')\n\tnextPutAll: 'Příliš žluťoučký kůň úpěl ďábelské ódy.'; lf;\n\tflush.\n```\n\n#### Read a UTF-8 text from STDIN\n\n**CAUTION:** The following code will block your VM until input on STDIN is provided!\n\n##### obsolete code\n```smalltalk\nFileStream stdin upTo: Character lf.\n```\n\n##### new code\n```smalltalk\n(ZnCharacterReadStream on: Stdio stdin) upTo: Character lf.\n```\n\n#### Write binary data to STDOUT\n\n##### obsolete code\n```smalltalk\nFileStream stdout \n\tbinary\n\tnextPutAll: #[80 104 97 114 111 10 ].\n```\n\n##### new code\n```smalltalk\nStdio stdout \n\tnextPutAll: #[80 104 97 114 111 10 ].\n```\n\n#### Read binary data from STDIN\n\n**CAUTION:** The following code will block your VM until input on STDIN is provided!\n\n##### obsolete code\n```smalltalk\nFileStream stdin binary upTo: 10.\n```\n\n##### new code\n```smalltalk\nStdio stdin upTo: 10.\n```\n\n### Positionable streams\n\nThe message `#position:` always works at the binary level, not at the character level.\n\n```smalltalk\n'1.txt' asFileReference readStreamDo: [ :stream | \n\tstream position: 4.\n\tstream upToEnd ].\n```\n\nThis will lead to an error (ZnInvalidUTF8: Illegal leading byte for utf-8 encoding) in case of \nthe file created above, because we set the position into the middle of a UTF-8 encoded character.\nTo be safe, you need to read the file from the beginning.\n\n```smalltalk\n'1.txt' asFileReference readStreamDo: [ :stream |\n\t3 timesRepeat: [ stream next ].\n\tstream upToEnd.].\n```\n\n#### Buffering\n\nThe `MultiByteFileStream` was buffered. If you create a stream using the expression\n\n```smalltalk\n'file.txt' asFileReference readStream.\n```\n\nthen the `ZnCharacterReadStream` is not created directly on top of the stream but on top of a buffered stream \nthat uses the file stream internally. \n\nIf you create a `ZnCharacterReadStream` directly on the file stream, then the characters from the file are read \none by one which may be about **ten times slower**!\n\n```smalltalk\nZnCharacterReadStream on: (File openForReadFileNamed: 'file.txt').\n```\n\n#### Binary streams do not understand #<< message anymore\n\nBinary streams used to understand `#<<` message in the past, but not anymore. One should either use `#next:` or `#nextPutAll:`.\n"
  },
  {
    "path": "PharoProjects/Announcer.md",
    "content": "# Announcer\n`Announcer` and `Announcement` classes provide an implementation of the [observer design pattern](https://en.wikipedia.org/wiki/Observer_pattern) in Pharo.\nAs written on the wikipedia page, it aims to address the following problems:\n\n- A one-to-many dependency between objects should be defined without making the objects tightly coupled.\n- It should be ensured that, when one object changes state, an open-ended number of dependent objects are updated automatically.\n- It should be possible that one object can notify an open-ended number of other objects.\n\nThis page provide a quick tutorial to get started with them.\n\n- [Getting started](#getting-started)\n- [Defining new kind of Announcement](#defining-new-kind-of-announcement)\n- [Using announcer for your subject object](#using-announcer-for-your-subject-object)\n\n## Getting started\nThe `Announcer` class implements a mechanism to:\n1. Allow objects (the observers) to subscribe to announcements\n2. Manage objects subscriptions\n3. Allow the object holding the announcer (the subject) to announce events\n\nFor example, there is an announcer available to let objects listen to announcements (events) concerning the system: `SystemAnnouncer uniqueInstance`.\nSuch announcements include:\n- `ClassAdded`\n- `ClassRemoved`\n- `MethodModified`\n- etc.\n\nIf one wants to be notified when a class is removed, it is possible to subscribe an object to this specific announcement as follow.\n\nFirst, let's create the method `#whenClassAdded:` for the object that will listen to `ClassAdded` announcement.\nThis method will be the hook called when such announcement has been announced.\nIt takes the announcement sent by the subject as parameter.\n\n```Smalltalk\nMyObjectListeningToClassAdded>>#whenClassAdded: aClassAdded\n  Transcript\n    show: aClassAdded classAffected name;\n    show: ' has been added.';\n    cr\n```\n\nThen, we subscribe an instance of our object to the announcer.\nWhen doing that, it is needed to specify\n1. Which kind of announcements (its class) our object listen to.\n2. Which object listen to this kind of announcements.\n3. Which method to call when the annoncement is sent.\n\nThe previous step can be achieved as follow:\n\n```Smalltalk\nSystemAnnouncer uniqueInstance\n  when: ClassAdded send: #whenClassAdded: to: instanceOfMyObjectListeningToClassAdded\n```\n\n> Note: the SystemAnnouncer is a bit special because it is a subclass of `Announcer`.\n> Usually, when creating you own announcer, you do not subclass `Announcer` but rather use it directly by storing an instance in a dedicated instance variable (see Section \"[Using announcer for your subject object](#using-announcer-for-your-subject-object)\").\n\nOnce the code above has been executed, a message is printed in the Transcript each time a class has been added.\nTo unsubscribe an object from an announcer, simply call `#unsubscribe:` method on the announcer.\n\n```Smalltalk\nSystemAnnouncer uniqueInstance\n  unsubscribe: instanceOfMyObjectListeningToClassAdded\n```\n\n## Defining new kind of Announcement\nCreating a new kind of announcement to fit your needs is easy, just subclass `Announcement` class.\nFor example, let's say you have an object that has a color. You want to allow observers to listen to color changes of the object.\nTo do that, let's create a `ColorChangeAnnouncement` class:\n\n```Smalltalk\nAnnouncement subclass: #ColorChangeAnnouncement\n\tslots: { #newColor }\n\tclassVariables: {  }\n\tpackage: 'MyPackage'\n```\n\nYour new kind of announcement aims to hold all the information you need.\nIn our example, `ColorChangeAnnouncement` hold the new color in `#newColor` instance variable.\n\n## Using announcer for your subject object\nThe common pattern to use an `Announcer` in your subject object is to:\n1. Create an `#announcer` instance variable which will contain the instance of `Announcer`.\n2. Create an accessor method for `#announcer` instance variable that use lazy-initialization (so no announcer is created if no announcement is sent and no one wants to subscribe to events of the subject).\n3. The subject object send announcements through its announcer.\n\nAs an example, let's implement the object changing its color discussed in previous section\"\n\n```Smalltalk\nObject subclass: #MyObjectChangeColor\n\tslots: { #announcer. #color }\n\tclassVariables: {  }\n\tpackage: 'MyPackage'\n```\n\nThen we create the accessor for `#announcer` with lazy-initialisation.\n\n```Smalltalk\nMyObjectChangeColor>>#announcer\n  ^ announcer ifNil: [ announcer := Announcer new ]\n```\n\nAnd when the color of the object is updated, we announce it:\n\n```Smalltalk\nMyObjectChangeColor>>#color: aColor\n  color := aColor.\n  self announcer\n    announce: (ColorChangeAnnouncement new\n                newColor: aColor;\n                yourself)\n```\n"
  },
  {
    "path": "PharoProjects/Cursor.md",
    "content": "# Cursor\n\nThe `Cursor` class in Pharo manages the display of the cursor on the screen.\n\nIt is possible to change the way it looks and we will explain how here.\n\nTo select the cursor you want you can check the class side of the `Cursor` class, in \"constants\" protocol.\n\nThe common way to change the look of the cursor is to change it for the execution of a block and then set it back to the original cursor. To do that you can use the `showWhile:` method.\n\n```Smalltalk\nCursor wait showWhile: [ 3 second wait ]\n```\n\nIt might be needed to have full control on the cursor without using a block. To do that Morph implements methods to help with the management of cursors via the hand morph. In the following code, `self` can be any object (`#currentHand` is defined on Object).\n\n```Smalltalk\nself currentHand showTemporaryCursor: Cursor wait. \nself flag: #doSomethingHere.\nself currentHand showTemporaryCursor: nil. \"Reset the cursor to the previous one\"\n```\n"
  },
  {
    "path": "PharoProjects/DynamicVariables.md",
    "content": "# Dynamic variables\n\nPharo contains a system of dynamic variables which are global variables whose value can be changed during the execution of a process.\n\n> Be careful when you use these variables. They should not be used just as a global variable to make access to it easier in the code.\n\nA logger system is good example of the usefulness of dynamic variables. In such a system, we can imagine that we have a default logger that will be used to record logs. However, in some specific cases we want to use a custom logger. In that case a dynamic variable can do the work. If you wish to see it at work you can check this [logger project using it](https://github.com/jecisc/TinyLogger).\n\n## Create a new dynamic variable\n\nTo create a new dynamic variable you just need to create a new subclass of `DynamicVariable`:\n\n```Smalltalk\nDynamicVariable subclass: #MyVariable\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'MyProject'\n```\n\n## Add a default value\n\nIt is possible to assign a default value to your dynamic variable. To do so, you need to add a `default` method.\n\n```Smalltalk\nMyVariable>>default\n\t^ MyDefaultObject\n ```\n \n## Use your dynamic variable\n\nTo use your variable, just send the `value` message to it. If you have no default value, do not forget to manage the case where it can be nil if it can happen.\n\n```Smalltalk\nMyVariable value doSomething\n```\n\n## Change the value of the variable in a process\n\nIf you need to change the value of the variable for the execution of a specific process, just use the `value:during:` message.\n\n```Smalltalk\nMyVariable value: MyNewObject during: [\n\tself doAnActionUsingTheVariable.\n]\n```\n\n## Example\n\nHere is the way dynamic variables are used in the `TinyLogger` project cited above.\n\n```Smalltalk\nDynamicVariable subclass: #TinyCurrentLogger\n\tslots: {  }\n\tclassVariables: {  }\n\tpackage: 'TinyLogger-Core'\n```\n\n```Smalltalk\nTinyCurrentLogger>>default\n\t^ TinyLogger default\n```\n\n```Smalltalk\nObject>>record: aString\n\tTinyCurrentLogger value record: aString\n```\n\n```Smalltalk\nObject>>execute: aBlock recordedAs: aString\n\tTinyCurrentLogger value execute: aBlock recordedAs: aString\n```\n\n```Smalltalk\n\tTinyCurrentLogger value: (TinyLogger new addTranscriptLogger; yourself) during: [ \n\t\t'test' record.\n\t\tTinyCurrentLogger value record: 'Test2'\n\t]\n```\n\n\n"
  },
  {
    "path": "PharoProjects/Metalinks.md",
    "content": "# Metalinks\n\n> **TODO**\n"
  },
  {
    "path": "PharoProjects/Numbers.md",
    "content": "# Numbers\nThis page provides some hints for using Pharo's numbers. For more detailled information, check [Pharo by Example book](http://books.pharo.org/pharo-by-example).\n\n\n## Numbers are not primitive\nAs written in [Pharo by Example book](http://books.pharo.org/pharo-by-example),\n\n> Remarkably, numbers in Smalltalk are not primitive data values but true objects. Of course numbers are implemented efficiently in the virtual machine, but the Number hierarchy is as perfectly accessible and extensible as any other portion of the Smalltalk class hierarchy. - [Pharo by Example](http://books.pharo.org/pharo-by-example), Chapter 8 Section 2\n\nWhich is an interesting feature because it means that extension methods can be added to create objects holding a quantity. This is what is done for `Duration`s:\n\n```Smalltalk\n5 seconds. \"0:00:00:05\"\n```\n\n`#seconds` method creates a new instance of `Duration` representing the number second required.\n\n## Scaled decimals\nScaled decimals allow one to model rationals. That is to say numbers with a fixed number of decimals. They are handy when dealing with money for example. It is possible to create a ScaledDecimal from its litteral form using the `s` notation: `1.45s2` which will store 1.45 with 2 digits precision in decimals.\n\n## Special numbers\n- Infinity: `Float infinity`\n- Negative infinity: `Float negativeInfinity`\n- Not a number: `Float nan`\n- Pi, 2\\*Pi, 3\\*Pi: `Float pi. Float twoPi. Float threePi`\n- Euler's number: `Float e`\n\n## Parse number\nThe class-side methods `#readFrom:` and `#readFrom:base:` of `Number` class allow one to parse a number from a `String`. Here are some examples:\n\n```Smalltalk\nNumber readFrom: '10'. \"10\"\nNumber readFrom: '10' base: 2. \"2\"\nNumber readFrom: '1.0'. \"1.0\"\n```\n\nA specific subclass of `Number` can be used to ensure that the object created by the parser is of a specific kind:\n\n```Smalltalk\nInteger readFrom: '10'. \"10\"\nFloat readFrom: '1.0'. \"1.0\"\n```\n"
  },
  {
    "path": "PharoProjects/OS.md",
    "content": "# Basic interactions with the OS\nThis page describes basic interactions with the OS. The code snippet below should be working on all OS and are built-in: you do not need to install an external project to use them.\n\n- [Execute shell command](#execute-shell-command)\n- [Write environment variable](#write-environment-variable)\n- [Read environment variable](#read-environment-variable)\n\n## Execute shell command\nThe following code execute a shell command and returns an integer which is the return code of the executed command.\nIf the return code is `0`, the execution of the command is successful. Else, the integer returned is the error code generated by the shell command.\n\n```Smalltalk\nLibC uniqueInstance\n\tsystem: 'echo \"foo\" >> /tmp/foo.txt'\n```\n\nTo retrieve the output of a command directly in Pharo, use `#resultOfCommand:`\n\n```Smalltalk\nLibC uniqueInstance\n\tresultOfCommand: 'echo \"foo\"'. \"'foo\n'\"\n```\n\n## Write environment variable\nThe environment behaves similarly to a dictionary when it comes to write a variable.\n\n```Smalltalk\nSmalltalk os environment at: 'FOO' put: 'bar'.\nSmalltalk os environment at: 'FOO' ifAbsentPut: 'bar'\n```\n\n> Note: Before Pharo 7, `#setEnv:value:` message was used. This message is part of the low-level API and should not be used directly.\n\n## Read environment variable\nAs for writing a variable, environment provide an API similar to `Dictionary` to read a variable.\n\n```Smalltalk\nSmalltalk os environment at: 'FOO'.\nSmalltalk os environment at: 'FOO' ifAbsent: [ 'Nope :-(' ].\nSmalltalk os environment at: 'FOO' ifPresent: [ :value | \"Do something interesting.\" ]\n```\n\n> Note: Before Pharo 7, #getEnv: message was used. This message is now deprecated and should not be used.\n"
  },
  {
    "path": "PharoProjects/ObjectsSerialization.md",
    "content": "# Objects serialization support\nTo be done.\n\n## STON\n-> [doc](https://github.com/svenvc/ston/blob/master/ston-paper.md)\n\n## Fuel\n-> [doc]()\n\n## STON v.s. Fuel\n\n|Property                                            |STON                |Fuel                |\n|----------------------------------------------------|--------------------|--------------------|\n|Human-readable                                      | :white_check_mark: | :x:                |\n|Built-in                                            | :white_check_mark: | :white_check_mark: |\n|Works between different major Pharo versions        | :white_check_mark: | :x:*               |\n|Does not require configuration on seralized objects | :x:                | :white_check_mark: |\n\n> *It might work but it is not likely. If a fix was done on Fuel during Pharo development (which is likely), it might make your `.fuel` files unreadable by Pharo. STON is more stable from this perspective.\n"
  },
  {
    "path": "PharoProjects/RichText.md",
    "content": "# Rich text in Pharo\n\n`Text` object models rich text. That is to say text that can be stylised with **bold**, *italics*, colors, different fonts and a few other things. The class `Text` is one of the really ancient classes in smalltalk.\n\n- [Quickstart](#quickstart)\n- [TextEmphasis](#textemphasis)\n- [Colors](#colors)\n- [Different fonts](#different-fonts)\n- [Clickable text](#clickable-text)\n- [Inline images](#inline-images)\n\n## Quickstart\nHere is a quick example illustrating how attributes can be added to `Text` object to create rich text in Pharo:\n\n```Smalltalk\ntext := 'Hello World!' asText.\ntext\n\taddAttribute: TextEmphasis italic from: 7 to: 11;\n\taddAttribute: TextEmphasis struckOut from: 7 to: 11;\n\taddAttribute: (TextColor color: Color red) from: 7 to: 11;\n\taddAttribute: (TextColor color: Color green) from: 12 to: 12.\n```\n\n## TextEmphasis\nThe class `TextEmphasis` defines a set of simple (no font change) changes you can do. See the class side of `TextEmphasis` for the supported styles of emphasis.\n\nIt is possible to overlap the different emphasis styles:\n\n```Smalltalk\ntext := 'Hello World!' asText.\ntext\n\taddAttribute: TextEmphasis italic from: 7 to: 11;\n\taddAttribute: TextEmphasis struckOut from: 7 to: 11.\n```\n\n## Colors\nColored text is done as shown below. Examine the class `Color` for other colors.\n\n```Smalltalk\ntext := 'Hello World!' asText.\ntext\n\taddAttribute: (TextColor color: Color red) from: 7 to: 11;\n\taddAttribute: (TextColor color: Color green) from: 12 to: 12.\n```\n\n## Different fonts\nLoading and managing fonts is an issue in itself.\n\nYou can see which fonts you have available in your image using `StrikeFont actualFamilyNames`.\n\nAssume you have a font named: `Bitmap Source Sans Pro` (was the case on Macbook Pro, Pharo 8, fall 2019). \n\nYou need to turn the font into a text attribute:\n\n```Smalltalk\nlargeAttribute := TextFontReference\n\t\ttoFont:\n\t\t\t(StrikeFont\n\t\t\t\tfamilyName: 'Bitmap Source Sans Pro'\n\t\t\t\tpointSize: 20).\n'My larger text' asText addAttribute: largeAttribute from: 4 to: 10.\n```\n\nThis should give you 'My larger text' with 'larger' being in font size 20 and in the 'Bitmap Source Sans Pro' font.\n\n## Clickable text\nIt is possible to make text do stuff when clicked. This is obviously a huge area. One simple example is:\n\n```Smalltalk\ntextAction := TextAction new \n\tactOnClickBlock: [ \n\t\tTranscript nextPutAll: 'action clicked';cr;endEntry\n\t\t].\n'My action text' asText addAttribute: textAction from: 4 to: 10.\n```\n\n## Inline images\nIt is possible to insert images into text. It is done using a `TextAnchor` attribute which can only be put on the text obtained using the expression `(String value: 1) asText`. The following example illustrates this:\n\n```Smalltalk\nanchoredImage := \n\t(String value: 1) asText addAttribute: \n\t\t(TextAnchor new anchoredMorph: PolymorphSystemSettings pharoLogoForm ).\n\n('Line before image\\' withCRs asText), \nanchoredImage,  \n('\\Line afterimage' withCRs asText).\n```\n\nThere are further examples in the class comment of `TextAnchor`.\n\n> Note:\n> The inline images relies on the morphic system. Not all morphs seem to be able to be inlined in text in Pharo.\n> \n> In addition, you will most likely get the best results if you put images larger than the font size on a line by themself. The class comment of `TextAnchor` has an example of inlining a small icon.\n"
  },
  {
    "path": "PharoProjects/WebBrowser.md",
    "content": "# Web browser\n\n*WebBrowser* is a project included since Pharo 7. The goal of the project is to offer to the user the possibility to open a link directly into the default browser of the computer.\n\nIt currently supports:\n- Most linux 32 and 64bits\n- OSX 32 and 64bits\n- Windows 32bits\n\nTo use it you just need to call:\n\n```Smalltalk\nWebBrowser openOn: 'https://pharo.org'\n```\n"
  },
  {
    "path": "PharoVirtualMachine/pharo-vm-map.md",
    "content": "\n# Introduction\n\n## design principles behind smalltalk\nhttps://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html\n\n**\"*Personal Mastery*: If a system is to serve the creative spirit, it must be entirely comprehensible to a single individual. \"**\n\nThe history of opensmalltalk/pharo virtual machine started a long time ago, with Smalltalk-80, and then in the squeak virtual machine, now opensmalltalk.\n\nhttp://files.squeak.org/docs/OOPSLA.Squeak.html\n\n\"Squeak is an open, highly-portable Smalltalk implementation whose virtual machine is written entirely in Smalltalk, making it easy to debug, analyze, and change. To achieve practical performance, a translator produces an equivalent C program whose performance is comparable to commercial Smalltalks.\"\n\n## overview\nTwo major components of the Smalltalk-80 system can be distinguished: the virtual image and the virtual machine.\n\n1. The virtual image consists of all of the objects in the system, including Smalltalk source code objects, compiler objects, and bytecode compiled method objects. It is platform independent.\n1. The virtual machine is the engine that runs the image. It consists of a machine language (or microcode or bytecode) routines that give dynamics to the objects in the virtual image. It is a platform dependent machine code executable that can be decomposed into: \n    * *Bytecode execution engine* - to interpret or JIT (Just In Time) compile each bytecode into machine code and execute it;  \n    * *Object engine* - to provide memory management of objects;   \n    * *Primitives* - to provide AOT (Ahead Of Time) compiled machine code for accelerated execution and interface to platform dependent operating system routines.\"\n\n\nThe system implementer's task is to create a virtual machine. A virtual image can then be loaded into the virtual machine and the pharo system becomes an interactive entity.\n\nThe various link of the opensmalltalk/pharo VM implementation given in this chapter is organized in a top-down fashion, starting with the source methods written by programmers. These methods are translated by a *compiler* into sequences of instructions called bytecodes. The bytecodes produced by the compiler are instructions for an *interpreter*. Below the interpreter in the implementation is an *object memory* that stores the objects that make up the virtual image.\n\n\n\n\n\nMain lecture: Smalltalk - 80. The language and its implementation:\n[http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf](http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf)\n\nEspecially, the part that are related to the VM: pages 541 to pages 691\nA web format can be found here:\nhttp://www.mirandabanda.org/bluebook/\n\nA tour of the squeak object engine show a good overview, but is a bit more outdated:\nhttp://stephane.ducasse.free.fr/FreeBooks/CollectiveNBlueBook/Rowledge-Final.pdf\n\nBytecode and Virtual Machines:\nhttp://scg.unibe.ch/download/lectures/cc2011/09BytecodeVirtualMachines.pptx.pdf\n\nAn overview of all the the changes brough to opensmalltalk/pharo VM:\nhttps://www.researchgate.net/publication/328509577_Two_Decades_of_Smalltalk_VM_Development_Live_VM_Development_through_Simulation_Tools\n\n## set up\nhttp://forum.world.st/ANN-Pharo-Headless-Beta-Actually-what-is-between-Alpha-and-Beta-td5102089.html\n\nheadless VM: https://github.com/pharo-project/opensmalltalk-vm located in the headless branch.\n\nYou'll find instruction on how to build it on the github page. In addition, you'll get an image with VMMaker loaded so you can study the code of the VM.\n\nTips on debugging the VM:\n* https://pharoweekly.wordpress.com/2019/08/28/pharo-headless-linux-vm-debugging/\n* https://clementbera.wordpress.com/2016/05/30/simulating-the-cog-vm/\n\n\n# Compiler, bytecodes and compiled method\n## introduction\n[https://marianopeck.wordpress.com/2011/04/30/smalltalk-reflective-model/](https://marianopeck.wordpress.com/2011/04/30/smalltalk-reflective-model/)\n## compiler - Opal\nSource methods written by programmers are represented in the system as instances of *String*. The Strings contain sequences of characters that conform to the pharo syntax.\n\nSource methods are translated by the system's *compiler* into sequences of instructions. The instructions are called bytecodes.\n\n* Towards a flexible Pharo Compiler: https://hal.inria.fr/hal-00862411/document\n* https://rmod.inria.fr/archives/events/2011DIS/Slides/Opal/OpalCompiler.pdf\n* https://clementbera.wordpress.com/2013/03/22/toward-a-zero-bugs-interpreter-compiler/\n* https://clementbera.wordpress.com/2013/05/28/modular-compilation-with-opal/\n\n### Example of live compiling\n* http://forum.world.st/Squeak-Compiler-evaluate-3-4-Pharo-equivalent-td5086475.html\n* http://forum.world.st/evaluate-with-bindings-td5071919.html\n\n## bytecode:\nThe original smalltalk interpreter understands 256 bytecode instructions that fall into five categories: pushes, stores, sends, returns, and jumps. Since more than 256 instructions for the interpreter are needed, some of the bytecodes take extensions. An extension is one or two bytes following the bytecode that further specify the instruction. An extension is not an instruction on its own, it is only a part of an instruction. \n\n* [https://marianopeck.wordpress.com/2011/05/21/introduction-to-smalltalk-bytecodes/](https://marianopeck.wordpress.com/2011/05/21/introduction-to-smalltalk-bytecodes/)\n* https://clementbera.wordpress.com/2013/04/21/byte-code-to-source-code-mappin/\n* https://clementbera.wordpress.com/2013/09/23/squeakv3plusclosure-bytecode-set/\n* A bytecode set for adaptive optimizations: https://hal.inria.fr/hal-01088801/document\n\n## compiled method:\nThe compiler creates an instance of *CompiledMethod* to hold the bytecode translation of a source method. \n\n* [https://marianopeck.wordpress.com/2011/05/14/playing-with-compiledmethod/](https://marianopeck.wordpress.com/2011/05/14/playing-with-compiledmethod/)\n* [https://marianopeck.wordpress.com/2011/06/03/primitives-pragmas-literals-and-their-relation-to-compiledmethods/](https://marianopeck.wordpress.com/2011/06/03/primitives-pragmas-literals-and-their-relation-to-compiledmethods/)\n* https://clementbera.wordpress.com/2013/07/29/smalltalk-method-and-block-models/\n* http://www.mirandabanda.org/cogblog/2008/06/17/bluebook-compiledmethods-having-our-cake-and-eating-it-too/\n* [https://marianopeck.wordpress.com/2011/07/06/named-primitives/](https://marianopeck.wordpress.com/2011/07/06/named-primitives/)\n\n## class format:\n[https://marianopeck.wordpress.com/2011/05/07/class-formats-and-compiledmethod-uniqueness/](https://marianopeck.wordpress.com/2011/05/07/class-formats-and-compiledmethod-uniqueness/)\n\n# stack interperter\nThe original smalltalk system wat a stack-oriented interpreter. A big part of the system still contain its source code, which is enhanced with Just In Time  (JIT) in recent version.\n\nThe Smalltalk-80 interpreter executes the bytecode instructions found in *CompiledMethods*. The interpreter uses five pieces of information and repeatedly performs a three-step cycle. \n\nMore information: \nhttp://www.mirandabanda.org/bluebook/bluebook_chapter26.html#TheInterpreter26\n\nUnderstand how a call stack interperter is working:\nhttps://files.pharo.org/books-pdfs/booklet-CallStack/2018-01-23-CallStack.pdf\n\nUnderstand how a simple system may work:\nhttp://books.pharo.org/booklet-ReflectiveCore/pdf/2018-03-05-ReflectiveKernel-spiral.pdf\n\n\n## context\nThe interpreter uses *contexts* to represent the state of its execution of *CompiledMethods* and *blocks*. A context can be a *MethodContext* or a *BlockContext*. A MethodContext represents the execution of a CompiledMethod that was invoked by a message.\n\n* http://www.mirandabanda.org/bluebook/bluebook_chapter26.html#Contexts26\n\n* http://www.mirandabanda.org/bluebook/bluebook_chapter27.html#Contexts27\n\n### in Opensmalltalk/Pharo\nhttp://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/\n\n## block closure\n### In the original smalltalk-80 system:\nhttp://www.mirandabanda.org/bluebook/bluebook_chapter26.html#BlockContexts26\n\n\n### In Opensmalltalk/pharo\n* http://www.mirandabanda.org/cogblog/2008/06/07/closures-part-i/\n* http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/\n* http://www.mirandabanda.org/cogblog/2008/07/24/closures-part-iii-the-compiler/\n\n* https://clementbera.wordpress.com/2016/06/27/fullblockclosure-design/\n\n# object memory\nThe object memory provides the interpreter with an interface to the objects that make up the pharo virtual image. Each object is associated with a unique identifier called its object pointer. The object memory and interpreter communicate about objects with object pointers.\n\nThe object memory associates each object pointer with a set of other object pointers. Every object pointer is associated with the object pointer of a class. If an object has instance variables, its object pointer is also associated with the object pointers of their values. The individual instance variables are referred to by zero-relative integer indices. The value of an instance variable can be changed, but the class associated with an object cannot be changed. The object memory provides the following five fundamental functions to the interpreter.\nhttp://www.mirandabanda.org/bluebook/bluebook_chapter26.html#TheObjectMemory26\n\n### in Opensmalltalk/Pharo\n\n* [https://marianopeck.wordpress.com/2011/10/26/memory-addresses-and-immediate-objects/](https://marianopeck.wordpress.com/2011/10/26/memory-addresses-and-immediate-objects/)\n* http://www.mirandabanda.org/cogblog/2013/09/05/a-spur-gear-for-cog/\n* https://clementbera.wordpress.com/2014/01/16/spurs-new-object-format/\n* https://clementbera.wordpress.com/2014/02/06/7-points-summary-of-the-spur-memory-manager/\n\n\n# beyond smalltalk-80 original VM - JIT\n## Just In Time - JIT\n* http://www.mirandabanda.org/cogblog/2011/03/01/build-me-a-jit-as-fast-as-you-can/\n* http://www.mirandabanda.org/cogblog/2011/03/04/an-arranged-marriage/\n\n## memory compactor and garbage collection\n* https://clementbera.wordpress.com/2018/06/07/free-chunk-management-in-the-cog-vm/\n* https://clementbera.wordpress.com/2017/03/12/tuning-the-pharo-garbage-collector/\n\n### Specific to Pharo\nhttps://github.com/SquareBracketAssociates/Booklet-PharoVirtualMachine\n\n## other\nSub-method, partial behavioral reflection with Reflectivity: Looking back on 10 years of use\nhttps://programming-journal.org/2020/4/5/\n\nDebugging the VM through the simulator (video)\n* https://clementbera.wordpress.com/2018/03/07/sista-vm-screencast/\n\n* http://www.mirandabanda.org/cogblog/2008/11/14/mechanised-modifications-and-miscellaneous-measurements/\n\n## multi-user transactional image\nmagma object representation by Chris Muller. \n* https://wiki.squeak.org/squeak/2665.\n\n# UFFI\n* https://users.dcc.uchile.cl/~rsalgado/uffi-fourth-draft.pdf\n* http://books.pharo.org/booklet-uffi/pdf/2020-02-12-uFFI-V1.0.1\n\nPharo threaded FFI\nhttps://github.com/pharo-project/threadedFFI-Plugin\n\n\n# parameters of the virtual machine\n\nfound in\n```smalltalk\nVirtualMachine >> parameterAt: parameterIndex\n\n\t\"parameterIndex is a positive integer corresponding to one of the VM's internal\n\tparameter/metric registers.  Answer with the current value of that register.\n\tFail if parameterIndex has no corresponding register.\n\tVM parameters are numbered as follows:\n\t1\tend (v3)/size(Spur) of old-space (0-based, read-only)\n\t2\tend (v3)/size(Spur) of young/new-space (read-only)\n\t3\tend (v3)/size(Spur) of heap (read-only)\n\t4\tnil (was allocationCount (read-only))\n\t5\tnil (was allocations between GCs (read-write)\n\t6\tsurvivor count tenuring threshold (read-write)\n\t7\tfull GCs since startup (read-only)\n\t8\ttotal milliseconds in full GCs since startup (read-only)\n\t9\tincremental GCs (SqueakV3) or scavenges (Spur) since startup (read-only)\n\t10\ttotal milliseconds in incremental GCs (SqueakV3) or scavenges (Spur) since startup (read-only)\n\t11\ttenures of surving objects since startup (read-only)\n\t12-20 were specific to ikp's JITTER VM, now 12-19 are open for use\n\t20\tutc microseconds at VM start-up (actually at time initialization, which precedes image load).\n\t21\troot table size (read-only)\n\t22\troot table overflows since startup (read-only)\n\t23\tbytes of extra memory to reserve for VM buffers, plugins, etc (stored\n\tin image file header).\n\t24\tmemory threshold above which shrinking object memory (rw)\n\t25\tmemory headroom when growing object memory (rw)\n\t26\tinterruptChecksEveryNms - force an ioProcessEvents every N milliseconds\t(rw) 27\tnumber of times mark loop iterated for current IGC/FGC (read-only)\tincludes ALL marking\n\t28\tnumber of times sweep loop iterated for current IGC/FGC (read-only)\n\t29\tnumber of times make forward loop iterated for current IGC/FGC\t(read-only) 30\tnumber of times compact move loop iterated for current\tIGC/FGC (read-only)\n\t31\tnumber of grow memory requests (read-only)\n\t32\tnumber of shrink memory requests (read-only)\n\t33\tnumber of root table entries used for current IGC/FGC (read-only)\n\t34\tnumber of allocations done before current IGC/FGC (read-only)\n\t35\tnumber of survivor objects after current IGC/FGC (read-only)\n\t36\tmillisecond clock when current IGC/FGC completed (read-only)\n\t37\tnumber of marked objects for Roots of the world, not including Root\tTable entries for current IGC/FGC (read-only)\n\t38\tmilliseconds taken by current IGC (read-only)\n\t39\tNumber of finalization signals for Weak Objects pending when current\tIGC/FGC completed (read-only)\n\t40\tBytesPerOop for this image\n\t41\timageFormatVersion for the VM\n\t42\tnumber of stack pages in use\n\t43\tdesired number of stack pages (stored in image file header, max 65535)\n\t44\tsize of eden, in bytes\n\t45\tdesired size of eden, in bytes (stored in image file header)\n\t46\tmachine code zone size, in bytes (Cog only; otherwise nil)\n\t47\tdesired machine code zone size (stored in image file header; Cog only;\totherwise nil)\n\t48\tvarious header flags. See getCogVMFlags.\n\t49\tmax size the image promises to grow the external semaphore table to (0\tsets to default, which is 256 as of writing)\n\t50-51 nil; reserved for VM parameters that persist in the image (such as\teden above)\n\t52\troot table capacity\n\t53\tnumber of segments (Spur only; otherwise nil)\n\t54\ttotal size of free old space (Spur only, otherwise nil)\n\t55\tratio of growth and image size at or above which a GC will be performed\tpost scavenge\n\t56\tnumber of process switches since startup (read-only)\n\t57\tnumber of ioProcessEvents calls since startup (read-only)\n\t58\tnumber of ForceInterruptCheck calls since startup (read-only)\n\t59\tnumber of check event calls since startup (read-only)\n\t60\tnumber of stack page overflows since startup (read-only)\n\t61\tnumber of stack page divorces since startup (read-only)\t62\tcompiled code compactions since startup (read-only; Cog only; otherwise nil)\n\t63\ttotal milliseconds in compiled code compactions since startup\t(read-only; Cog only; otherwise nil)\n\t64\tthe number of methods that currently have jitted machine-code\n\t65\twhether the VM supports a certain feature, MULTIPLE_BYTECODE_SETS is bit 0, IMMTABILITY is bit 1\n\t66\tthe byte size of a stack page\n\t67\tthe max allowed size of old space (Spur only; nil otherwise; 0 implies\tno limit except that of the underlying platform)\n\t68\tthe average number of live stack pages when scanned by GC (at\tscavenge/gc/become et al)\n\t69\tthe maximum number of live stack pages when scanned by GC (at\tscavenge/gc/become et al)\n\t70\tthe vmProxyMajorVersion (the interpreterProxy VM_MAJOR_VERSION)\n\t71\tthe vmProxyMinorVersion (the interpreterProxy VM_MINOR_VERSION)\"\n```\n"
  },
  {
    "path": "README.md",
    "content": "# Pharo wiki\n\nWiki for the [Pharo](https://pharo.org/features) programming language and development environment.\n\nThe goals of the wiki are explained in the [Manifest](MANIFEST.md) and contribution guidelines in the [Contribution guide](CONTRIBUTION.md).\n\n> Looking for a list of awesome projects? Check-out [awesome-pharo](https://github.com/pharo-open-documentation/awesome-pharo), a curated list of awesome Pharo projects.\n\n- [Pharo wiki](#pharo-wiki)\n  * [Beginners](#beginners)\n  * [General](#general)\n    + [Infrastructure](#infrastructure)\n    + [Pharo Language](#pharo-language)\n    + [Pharo Tooling](#pharo-tooling)\n  * [Pharo projects](#pharo-projects)\n  * [Pharo and OpenSmalltalk Virtual Machine](#pharo-and-opensmalltalk-virtual-machine)\n  * [External projects](#external-projects)\n    + [Data exchange](#data-exchange)\n    + [Data structures](#data-structures)\n  * [Migration guidelines](#migration-guidelines)\n  * [External resources](#external-resources)\n\n## Beginners\n\n- [Setting up a new project](General/SettingUpANewProject.md) ![Unfinished](https://img.shields.io/badge/Progress-Unfinished-yellow.svg?style=flat)\n- [Things beginners must learn](General/MustKnowForBeginners.md)\n- [Interesting things to know for beginners](General/InterestingsToKnowForBeginners.md)\n- [How to run Pharo from the command line](General/HowToRunPharoFromCommandLine.md) - How to run pharo from the command line.\n- [Glossary](General/Glossary.md) ![Unfinished](https://img.shields.io/badge/Progress-Unfinished-yellow.svg?style=flat)\n\n## General\n\n### Infrastructure\n\n- [How to deal with baselines](General/Baselines.md) - Configure your project and its dependencies.\n- [Setup your CI through github actions](General/GithubActions.md) - Setup your CI via GitHub actions for your Pharo projects.\n- [Pharo code export formats](General/ExportFormats.md) - Explanations about code formats used to export code to VCS such as git.\n- [How to deploy a pharo application](General/DeployYourPharoApplication.md) - A guide to deploy a Pharo application.\n- [Windows 10 Subsystem For Linux (WSL)](General/Windows10SubsystemForLinux.md) - Getting Pharo to run on Windows 10 Subsystem for Linux.\n- [Using CJK (Chinese, Japanese, and Korean) characters](General/CJKCharacter.md) - Guide to help you configure Pharo to support Chinese, Japanese, and Korean characters.\n- [Using CJK input methods](General/CJKInputMethod.md) - Guide to help you configure Pharo to support CJK input method.\n- [Tweaking big images](General/TweakingBigImages.md) - Tips to make large pharo images more responsive.\n- [Image file format](General/ImageFileFormat.md) - Documentation about binary format of Pharo images.\n- [How to setup a travis build](General/Travis.md) - How to have automated build on travis\n\n### Pharo Language\n\n- [Extension methods](General/Extensions.md) - How to extend existing classes in your packages.\n- [Traits](General/Traits.md) - Structure to build classes via composition.\n- [Some cool snippets in Pharo](General/CoolSnippets.md) - A cook book to answer common needs of a Pharo developer.\n- [Progress bar](General/ProgressBar.md) - Display a progress bar to give feedback to the user.\n- [Morphic Layouts](General/Layout.md) - Documentation about the layout management in the Morphic Library of pharo.\n- [Pragmas](General/Pragmas.md) - A guide on Pragmas, annotations to compiled methods to add additional properties.\n- [Coding conventions](General/CodingConventions.md) - A list of convention to follow when writing Pharo code.\n- [Exceptions](General/Exceptions.md) - How Pharo's exceptions work and explanations on how to use them.\n- [Sorting collections](General/SortingCollections.md) - How to sort collections with Pharo's built-in API.\n- [Sessions management](General/SessionsManagement.md) - Documentation on setting up start-up and shut-down actions in Pharo.\n\n### Pharo Tooling\n\n- [Playground](General/Playground.md) - Documentation on the usage of Pharo's playground.\n- [Profiling](General/Profiling.md) - Measure the time and space your program takes to execute.\n- [Menubar and World menu](General/MenuBar.md) - A guide to configure and customize Pharo's menubar and world menu.\n- [Iceberg on Windows workaround](General/IcebergOnWindows.md) - Troubleshooting for some issues appearing when using Iceberg on Windows.\n- [Inspector](General/Inspector.md) - Documentation on the usage of Pharo's inspector.\n- [Refactoring](General/Refactorings.md) - Documentation on the usage of Pharo refactoring's tool.\n- [Settings](General/Settings.md) - How to use Pharo's settings system to define your own settings.\n\n## Pharo projects\n\n<!-- - [How to deal with files](PharoProjects/Files.md) ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat) -->\n<!-- - [Objects serialization](PharoProjects/ObjectsSerialization.md) - Lists possibilities to serialize your objects on disk. ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat) -->\n- [Announcer](PharoProjects/Announcer.md) - Implementation of the observer design pattern built-in Pharo.\n- [Basic interactions with OS](PharoProjects/OS.md)\n- [Cursor](PharoProjects/Cursor.md)\n- [Dynamic variables](PharoProjects/DynamicVariables.md)\n- [Numbers](PharoProjects/Numbers.md)\n- [Rich text](PharoProjects/RichText.md)\n- [WebBrowser](PharoProjects/WebBrowser.md) - A project to open a link in the default web browser.<!-- - [Metalinks](PharoProjects/Metalinks.md) ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat) -->\n\n## Pharo and OpenSmalltalk Virtual Machine\n- [Pharo VM documentation map](PharoVirtualMachine/pharo-vm-map.md) -\n\n## External projects\n### Data exchange\n- [CSV support](ExternalProjects/Export/CSV.md)\n- [JSON support](ExternalProjects/Export/JSON.md)\n<!--\n- [XML support](ExternalProjects/Export/XML.md) ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat)\n- [HTML support](ExternalProjects/Export/HTML.md) ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat)\n- [Arff support](ExternalProjects/Export/Arff.md) - Arff is a format defined by [Weka](http://www.cs.waikato.ac.nz/ml/weka/) to be used for data importation. ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat)\n-->\n\n<!--\n### Data structures\n- [DataFrame](ExternalProjects/DataStructures/DataFrame.md) ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat)\n-->\n\n## Migration guidelines\n\n- [Migrating Streams from Pharo 6.1 to Pharo 7.0](Migration/MigrationToPharo7.md)\n\n## External resources\n- [Pharo Community](ExternalResources/Community.md) - Various links of people involved in Pharo community. Helps to discover Pharo ecosystem.\n- [Contributing to Pharo](https://github.com/pharo-project/pharo/wiki/Contribute-a-fix-to-Pharo) - Official tutorial on how to contribute to Pharo using Iceberg.\n- [Generating your own Pharo images (Bootstrapping)](https://github.com/carolahp/pharo/tree/candle) - Tools for generating small Pharo images from source code.\n- [Magritte3 Wiki](https://github.com/seandenigris/Magritte/wiki) - Wiki related to Magritte3.\n- [Sean's wiki about pharo](https://github.com/seandenigris/pharo/wiki) - The wiki of Sean P. DeNigris related to Pharo.\n- [#pharotip hashtag on twitter](https://twitter.com/hashtag/pharotip) - Tweets to help new users to easily get going with Pharo, started by [@astares](https://twitter.com/TorstenAstares).\n\n![CC](https://mirrors.creativecommons.org/presskit/icons/cc.svg)\n![BY](https://mirrors.creativecommons.org/presskit/icons/by.svg)\n\n<!---\nBadges:\n* ![TODO](https://img.shields.io/badge/Progress-TODO-red.svg?style=flat)\n* ![Unfinished](https://img.shields.io/badge/Progress-Unfinished-yellow.svg?style=flat)\n* ![Review](https://img.shields.io/badge/Progress-Review-blue.svg?style=flat)\n\n-->\n"
  }
]